PageRenderTime 16ms CodeModel.GetById 12ms app.highlight 3ms RepoModel.GetById 0ms app.codeStats 0ms

/src-extra/chaos/sql/chaos/server/actions/NextPhase.sql

http://github.com/JakeWheat/hssqlppp
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;