From 4177faf4cce352fa472de8b8dae503e6dc705941 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 27 Jul 2022 14:20:50 +0200 Subject: Rout after failure to attack fortress. --- rules.js | 71 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/rules.js b/rules.js index a37f8e0..e0f8ae6 100644 --- a/rules.js +++ b/rules.js @@ -3,9 +3,8 @@ // TODO: select hexside for engaging // TODO: fortress supply -// TODO: fortress battles mandatory combat! // TODO: oasis supply -// TODO: legal pass withdrawal moves +// TODO: legal pass withdrawal moves (reduce supply net, withdraw from fortress attack) // TODO: raiders // TODO: MINEFIELDS @@ -16,9 +15,6 @@ // TODO: when is "fired" status cleared? -// TODO: cache supply lines -// same as presence cache - // RULES: disrupted units routed again in second enemy turn, will they still recover? // assume yes, easy to change (remove from game.recover set if routed) @@ -29,10 +25,11 @@ const min = Math.min const abs = Math.abs var states = {} -var after_rout = {} var game = null var view = null +var after_rout_table = {} + const { all_hexes, hex_exists, hex_road, side_road, side_limit, hex_name, units, regions } = require("./data") function debug_hexes3(n, list) { @@ -1517,7 +1514,7 @@ function goto_initial_supply_check_rout() { if (n === 0) goto_turn_option() else if (n === 1) - goto_rout(where, false, "goto_initial_supply_check_rout") + goto_rout(where, false, goto_initial_supply_check_rout) else game.state = 'initial_supply_check_routs' } @@ -1530,12 +1527,10 @@ states.initial_supply_check_routs = { gen_action_hex(x) }, hex(where) { - goto_rout(where, true, "goto_initial_supply_check_rout") + goto_rout(where, true, goto_initial_supply_check_rout) } } -after_rout.goto_initial_supply_check_rout = goto_initial_supply_check_rout - function goto_final_supply_check() { set_active_player() @@ -1571,7 +1566,7 @@ function goto_final_supply_check_rout() { if (n === 0) end_player_turn() else if (n === 1) - goto_rout(where, false, "goto_final_supply_check_rout") + goto_rout(where, false, goto_final_supply_check_rout) else game.state = 'final_supply_check_routs' } @@ -1584,7 +1579,7 @@ states.final_supply_check_routs = { gen_action_hex(x) }, hex(where) { - goto_rout(where, false, "goto_final_supply_check_rout") + goto_rout(where, false, goto_final_supply_check_rout) } } @@ -1596,12 +1591,10 @@ states.final_supply_check_routs = { gen_action_hex(x) }, hex(where) { - goto_rout(where, false, "goto_final_supply_check_rout") + goto_rout(where, false, goto_final_supply_check_rout) } } -after_rout.goto_final_supply_check_rout = goto_final_supply_check_rout - // ==== MOVEMENT PHASE === function goto_move_phase() { @@ -2330,11 +2323,11 @@ function end_retreat() { // no shielding units remain if (is_friendly_rout_hex(game.retreat)) - goto_rout(game.retreat, false, "end_retreat_2") + goto_rout(game.retreat, false, end_retreat_2) // rear-guard eliminated all enemy units else if (is_enemy_rout_hex(game.retreat)) - goto_rout(game.retreat, true, "end_retreat_2") + goto_rout(game.retreat, true, end_retreat_2) else end_retreat_2() @@ -2347,8 +2340,6 @@ function end_retreat_2() { end_move_phase() } -after_rout.end_retreat_2 = end_retreat_2 - // === REFUSE BATTLE === function goto_refuse_battle() { @@ -2442,7 +2433,7 @@ states.refuse_battle_move = { function end_refuse_battle_move() { clear_undo() if (is_friendly_rout_hex(game.refuse)) - goto_rout(game.refuse, false, "end_refuse_battle_move_2") + goto_rout(game.refuse, false, end_refuse_battle_move_2) else end_refuse_battle_move_2() } @@ -2453,8 +2444,6 @@ function end_refuse_battle_move_2() { goto_refuse_battle() } -after_rout.end_refuse_battle_move_2 = end_refuse_battle_move_2 - // === ROUT === // rout attrition @@ -2463,7 +2452,14 @@ after_rout.end_refuse_battle_move_2 = end_refuse_battle_move_2 // eliminated if cannot function goto_rout(from, enemy, after) { - // remember current state so we can resume after routing + // remember state and callback so we can resume after routing + + if (after) { + if (!after_rout_table[after.name]) + after_rout_table[after.name] = after + after = after.name + } + game.rout = { state: game.state, active: game.active, @@ -2564,14 +2560,35 @@ function end_rout() { let after = game.rout.after delete game.rout if (after) - after_rout[after]() + after_rout_table[after]() } // ==== COMBAT PHASE === +function is_mandatory_combat(fortress, control_prop) { + return is_battle_hex(fortress) && (game[control_prop] !== game.phasing) +} + function goto_combat_phase() { clear_undo() set_active_player() + + if (game.turn_option === 'pass') { + if (is_mandatory_combat(BARDIA, "bardia")) + return goto_rout(BARDIA, false, goto_combat_phase) + if (is_mandatory_combat(BENGHAZI, "benghazi")) + return goto_rout(BENGHAZI, false, goto_combat_phase) + if (is_mandatory_combat(TOBRUK, "tobruk")) + return goto_rout(TOBRUK, false, goto_combat_phase) + } else { + if (is_mandatory_combat(BARDIA, "bardia")) + set_add(game.active_battles, BARDIA) + if (is_mandatory_combat(BENGHAZI, "benghazi")) + set_add(game.active_battles, BENGHAZI) + if (is_mandatory_combat(TOBRUK, "tobruk")) + set_add(game.active_battles, TOBRUK) + } + let n = count_battle_hexes() if (n > 0) { if (n > game.active_battles.length) @@ -2663,7 +2680,7 @@ function end_combat_phase() { if (game.rommel) game.rommel = 3 set_clear(game.fired) - game.turn_option = 'basic' + game.turn_option = 'second blitz' goto_move_phase() } else { goto_final_supply_check() @@ -2767,8 +2784,6 @@ function end_battle() { end_combat_phase() } -after_rout.end_battle = end_battle - function apply_battle_fire(tc) { let who = pop_selected() @@ -2938,7 +2953,7 @@ states.battle_hits = { next() { clear_undo() if (is_friendly_rout_hex(game.battle)) { - goto_rout(game.battle, false, "end_battle") + goto_rout(game.battle, false, end_battle) } else if (game.active === game.phasing) { // goto offensive fire game.state = 'battle_fire' -- cgit v1.2.3