diff options
-rw-r--r-- | rules.js | 152 |
1 files changed, 90 insertions, 62 deletions
@@ -4,6 +4,8 @@ const max = Math.max const min = Math.min const abs = Math.abs +const AUTOSELECT = false + var states = {} var game = null var view = null @@ -261,21 +263,22 @@ var first_enemy_unit, last_enemy_unit function set_active_player() { clear_undo() - game.active = game.phasing - update_aliases() + if (game.active !== game.phasing) { + game.active = game.phasing + update_aliases() + } } function set_passive_player() { clear_undo() - if (game.phasing === AXIS) - game.active = ALLIED - else - game.active = AXIS - update_aliases() + let nonphasing = (game.phasing === AXIS ? ALLIED : AXIS) + if (game.active !== nonphasing) { + game.active = nonphasing + update_aliases() + } } function set_enemy_player() { - clear_undo() if (is_active_player()) set_passive_player() else @@ -1930,7 +1933,7 @@ function can_all_undisrupted_units_withdraw(from) { return false let result = true for_each_undisrupted_friendly_unit_in_hex(from, u => { - if (!result === true && !can_unit_withdraw(u)) + if (result === true && !can_unit_withdraw(u)) result = false }) return result @@ -2550,7 +2553,7 @@ const xxx_fortress_supply = { gen_action_unit(u) } } - gen_action_next() + gen_action('next') }, unit(who) { let ix = game.assign @@ -2693,7 +2696,7 @@ function goto_initial_supply_check_rout() { } if (n === 0) goto_turn_option() - else if (n === 1) + else if (AUTOSELECT && n === 1) goto_rout(where, false, goto_initial_supply_check_rout) else game.state = 'initial_supply_check_rout' @@ -2779,7 +2782,7 @@ function goto_final_supply_check_rout() { } if (n === 0) end_player_turn() - else if (n === 1) + else if (AUTOSELECT && n === 1) goto_rout(where, false, goto_final_supply_check_rout) else game.state = 'final_supply_check_rout' @@ -3314,22 +3317,22 @@ states.move = { goto_retreat() }, overrun() { - let n = 0 - let where = 0 - for (let x of all_hexes) { - if (is_enemy_rout_hex(x)) { - n ++ - where = x - } - } + push_undo() flush_move_summary() init_move_summary() - // TODO: auto-select or allow undo? - if (n === 1) { - goto_overrun(where) - } else { - push_undo() - game.state = 'overrun' + game.state = 'overrun' + + if (false) { + let n = 0 + let where = 0 + for (let x of all_hexes) { + if (is_enemy_rout_hex(x)) { + n ++ + where = x + } + } + if (n === 1) + return goto_overrun(where) } }, end_move() { @@ -3710,7 +3713,7 @@ function engage_via_hexside(who, via, to) { if (is_new_battle_hex(to)) { claim_hex_control_for_defender(to) - set_add(game.active_battles, to) + set_add(game.new_battles, to) } } @@ -4154,7 +4157,7 @@ function end_retreat_2() { // === REFUSE BATTLE === function can_select_refuse_battle_hex() { - for (let x of game.active_battles) + for (let x of game.new_battles) if (can_all_undisrupted_units_disengage_and_withdraw(x)) return true return false @@ -4173,7 +4176,7 @@ states.refuse_battle = { inactive: "refuse battle", prompt() { view.prompt = `You may Refuse Battle from hexes just attacked.` - for (let x of game.active_battles) + for (let x of game.new_battles) if (can_all_undisrupted_units_disengage_and_withdraw(x)) gen_action_hex(x) gen_action('pass') @@ -4181,7 +4184,7 @@ states.refuse_battle = { hex(x) { log_h3(`Refused battle at #${x}`) game.refuse = x - set_delete(game.active_battles, x) + set_delete(game.new_battles, x) goto_pursuit_fire_during_refuse_battle(x) }, pass() { @@ -4390,7 +4393,9 @@ function end_rout() { game.state = game.rout.state release_hex_control(game.rout.from) hide_units_in_hex(game.rout.from) - set_delete(game.active_battles, game.rout.from) + + set_delete(game.new_battles, game.rout.from) + if (game.active !== game.rout.active) set_enemy_player() let after = game.rout.after @@ -4427,11 +4432,14 @@ function goto_combat_phase() { } if (is_mandatory_combat(BARDIA)) - set_add(game.active_battles, BARDIA) + set_add(game.new_battles, BARDIA) if (is_mandatory_combat(BENGHAZI)) - set_add(game.active_battles, BENGHAZI) + set_add(game.new_battles, BENGHAZI) if (is_mandatory_combat(TOBRUK)) - set_add(game.active_battles, TOBRUK) + set_add(game.new_battles, TOBRUK) + + for (let x of game.new_battles) + set_add(game.active_battles, x) let n = count_and_reveal_battle_hexes() if (n > 0) { @@ -4445,18 +4453,31 @@ function goto_combat_phase() { } states.select_active_battles = { - inactive: "combat phase (select active battles)", + inactive: "combat phase", prompt() { view.prompt = `Select active battles.` view.selected_hexes = game.active_battles - for (let x of all_hexes) + for (let x of all_hexes) { if (!set_has(game.active_battles, x) && is_battle_hex(x)) gen_action_hex(x) - gen_action('next') + if (set_has(game.active_battles, x) && !set_has(game.new_battles, x)) + gen_action_hex(x) + } + if (game.active_battles.length === 0) + gen_action('pass') + else + gen_action('next') + if (game.active_battles.length > game.new_battles.length) + gen_action('undo') + }, + undo() { + game.active_battles = game.new_battles.slice() }, hex(x) { - push_undo() - set_add(game.active_battles, x) + set_toggle(game.active_battles, x) + }, + pass() { + end_combat_phase() }, next() { if (game.active_battles.length > 0) { @@ -4471,18 +4492,27 @@ states.select_active_battles = { } states.select_assault_battles = { - inactive: "combat phase (select assault battles)", + inactive: "combat phase", prompt() { view.prompt = `Select assault battles.` view.selected_hexes = game.assault_battles for (let x of game.active_battles) - if (!set_has(game.assault_battles, x)) - gen_action_hex(x) - gen_action_next() + gen_action_hex(x) + if (game.assault_battles.length === 0) + gen_action('pass') + else { + gen_action('undo') + gen_action('next') + } + }, + undo() { + set_clear(game.assault_battles) }, hex(x) { - push_undo() - set_add(game.assault_battles, x) + set_toggle(game.assault_battles, x) + }, + pass() { + goto_select_battle() }, next() { goto_select_battle() @@ -4491,18 +4521,17 @@ states.select_assault_battles = { function goto_select_battle() { if (game.active_battles.length > 0) { - if (game.active_battles.length > 1) { - game.state = 'select_battle' - } else { + if (game.active_battles.length === 1) goto_battle(game.active_battles[0]) - } + else + game.state = 'select_battle' } else { end_combat_phase() } } states.select_battle = { - inactive: "combat phase (select next battle)", + inactive: "combat phase", prompt() { view.prompt = `Select next battle to resolve.` view.active_battles = game.active_battles @@ -4516,11 +4545,10 @@ states.select_battle = { } function end_combat_phase() { - if (game.turn_option === 'blitz') { + if (game.turn_option === 'blitz') goto_blitz_turn() - } else { + else goto_final_supply_check() - } } function goto_blitz_turn() { @@ -4630,6 +4658,7 @@ function end_battle() { hide_units_in_hex(game.battle) } + set_delete(game.new_battles, game.battle) set_delete(game.active_battles, game.battle) set_delete(game.assault_battles, game.battle) @@ -5449,7 +5478,7 @@ states.buildup_discard = { let hand = player_hand() if (hand[DUMMY] > 0) gen_action('dummy_card') - gen_action_next() + gen_action('next') }, dummy_card() { push_undo() @@ -6801,6 +6830,7 @@ exports.setup = function (seed, scenario, options) { rout: null, // combat + new_battles: [], active_battles: [], assault_battles: [], pursuit: 0, @@ -6905,10 +6935,6 @@ exports.query = function (state, current, q) { return null } -function gen_action_next() { - gen_action('next') -} - function gen_action_unit(u) { gen_action('unit', u) } @@ -7143,10 +7169,12 @@ function common_view(current) { states[game.state].prompt() else view.prompt = "Unknown state: " + game.state - if (game.undo && game.undo.length > 0) - view.actions.undo = 1 - else - view.actions.undo = 0 + if (view.actions.undo === undefined) { + if (game.undo && game.undo.length > 0) + view.actions.undo = 1 + else + view.actions.undo = 0 + } } return view } |