summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rules.js152
1 files changed, 90 insertions, 62 deletions
diff --git a/rules.js b/rules.js
index c109de0..2019300 100644
--- a/rules.js
+++ b/rules.js
@@ -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
}