/src-extra/chaos/sql/chaos/server/actions/NextPhase.sql
SQL | 179 lines | 97 code | 15 blank | 67 comment | 9 complexity | b56cdaa9139b9d0b48438d8883db6eca MD5 | raw file
Possible License(s): BSD-3-Clause
1select module('Chaos.Server.Actions.NextPhase'); 2 3/* 4== next phase 5 6next phase is the function to end a wizard's turn and move to the next 7one. It can be called implicitly by other actions as well as directly, 8e.g. once you've cast your spell, there's nothing you can do except 9end your turn so next_phase gets called automatically 10 11*/ 12 13select create_var('dont_nest_ai_next_phase', 'bool'); 14select set_relvar_type('dont_nest_ai_next_phase_table', 'hack'); 15 16create function action_next_phase() returns void as $$ 17declare 18 --c int; 19 next_phase_again boolean := false; 20begin 21/* 22=== check for game completion 23*/ 24 if (exists (select 1 from game_completed_table)) then 25 return; 26 end if; 27 --check for win or draw 28 case (select count(1) from wizards where not expired) 29 when 1 then --someone has won 30 perform game_completed(); 31 update current_wizard_table set current_wizard = 32 (select wizard_name from wizards where not expired); 33 perform add_history_game_won(); 34 return; 35 when 0 then --game is drawn 36 perform game_completed(); 37 perform add_history_game_drawn(); 38 delete from current_wizard_table; 39 return; 40 else 41 null; 42 end case; 43 44/* 45=== current wizard clean up phase 46 47If the user selects next phase when they have a spell to cast, then we 48want to call the usual skip spell action so as not to duplicate the 49work. But skip spell will call next_phase itself automatically and we 50don't want to do two next phases, so if there is a spell to be 51skipped, run that and don't run the rest of the next_phase function 52since it will be called via skip spell. 53 54this might be better if skip spell wasn't used for both explicitly and 55implicitly skipping 56 57*/ 58 -- if the current spell isn't completed, then skip it 59 if get_turn_phase() = 'cast' 60 and exists(select 1 from current_wizard_table 61 inner join wizard_spell_choices 62 on (current_wizard = wizard_name)) then 63 perform skip_spell(); 64 return; 65 end if; 66 67 --multiple update hack to get round constraints 68 update in_next_phase_hack_table 69 set in_next_phase_hack = true; 70 71 --complete current phase: 72 if (select turn_phase = 'move' from turn_phase_table) then 73 delete from pieces_moved; 74 end if; 75 76/* 77=== all wizards clean up phase 78 79clean up if this is the last wizard for this phase, then move to next 80phase, if this is autonomous, then do it and move to move phase this 81works because all the end phase stuff happens before the autonomous 82phase is run in this function, and all the setup runs after it is run. 83 84*/ 85 86 if is_last_wizard() then 87 case get_turn_phase() 88 when 'cast' then 89 --clear the cast alignment which is used to adjust the world 90 --alignment when a spell is cast 91 delete from cast_alignment_table; 92 when 'move' then 93 --if this is the end of the move phase then we're on the next turn 94 update turn_number_table 95 set turn_number = turn_number + 1; 96 perform add_history_new_turn(); 97 else 98 null; 99 end case; 100 --move to the next turn phase 101 update turn_phase_table 102 set turn_phase = next_turn_phase(turn_phase); 103 104 if get_turn_phase() = 'autonomous' then 105 perform do_autonomous_phase(); 106 update turn_phase_table 107 set turn_phase = next_turn_phase(turn_phase); 108 end if; 109 end if; 110 111/* 112=== init new current phase 113*/ 114 -- move to the next wizard, this is the meat of this function 115 update current_wizard_table 116 set current_wizard = next_wizard(current_wizard); 117 118 --initialise the spell for this phase 119 if get_turn_phase() = 'cast' then 120 --setup the cast alignment table if this is the start of the cast 121 --phases 122 if is_first_wizard() then 123 insert into cast_alignment_table values(0); 124 end if; 125 if exists(select 1 from current_wizard_spell) then 126 insert into spell_parts_to_cast_table 127 select coalesce(numb, 0) from target_spells 128 natural inner join current_wizard_spell; 129 insert into cast_success_checked_table values (false); 130 else 131 --skip to the next phase automatically 132 next_phase_again := true; 133 end if; 134 /*elseif (select turn_phase = 'move' from turn_phase_table) then 135 insert into pieces_to_move 136 select ptype, allegiance, tag 137 from moving_pieces 138 inner join current_wizard_table 139 on allegiance = current_wizard;*/ 140 end if; 141 142 --finished our updates for this next phase 143 update in_next_phase_hack_table 144 set in_next_phase_hack = false; 145 146 perform add_history_wizard_up(); 147/* 148=== continue 149*/ 150 --if there is nothing to do in the new current phase - continue to 151 --next phase automatically 152 if next_phase_again then 153 perform action_next_phase(); 154 end if; 155end; 156$$ language plpgsql volatile; 157 158/* 159=== internals 160*/ 161create function is_last_wizard() returns boolean as $$ 162 with 163 uw as (select wizard_name,original_place 164 from wizards 165 where not expired) 166 select original_place = (select max(original_place) from uw) 167 from current_wizard 168 natural inner join uw 169$$ language sql stable; 170 171create function is_first_wizard() returns boolean as $$ 172 with 173 uw as (select wizard_name,original_place 174 from wizards 175 where not expired) 176 select original_place = (select min(original_place) from uw) 177 from current_wizard 178 natural inner join uw 179$$ language sql stable;