diff options
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 200 |
1 files changed, 183 insertions, 17 deletions
@@ -159,6 +159,22 @@ function unit_speed(u) { return units[u].speed } +function is_artillery_unit(u) { + return units[u].class === 'artillery' +} + +function is_armor_unit(u) { + return units[u].class === 'armor' +} + +function is_infantry_unit(u) { + return units[u].class === 'infantry' +} + +function is_antitank_unit(u) { + return units[u].class === 'antitank' +} + function unit_hex(u) { return game.units[u] >>> 5 } @@ -211,6 +227,14 @@ function clear_unit_moved(u) { game.units[u] &= ~16 } +function is_unit_fired(u) { + return set_has(game.fired, u) +} + +function set_unit_fired(u) { + set_add(game.fired, u) +} + function unit_steps(u) { return units[u].steps - unit_lost_steps(u) } @@ -643,7 +667,7 @@ function clear_supply_networks() { game.allied_supply_line = null } -// === MOVEMENT === +// === PATHING === const path_from = [ new Array(hexcount), new Array(hexcount), new Array(hexcount), null, new Array(hexcount) ] const path_cost = [ new Array(hexcount), new Array(hexcount), new Array(hexcount), null, new Array(hexcount) ] @@ -851,6 +875,17 @@ function find_valid_regroup_destinations(from, rommel) { // === TURN === +function set_active_player() { + game.active = game.phasing +} + +function set_passive_player() { + if (game.phasing === AXIS) + game.active = ALLIED + else + game.active = AXIS +} + // Supply check // Turn option // Movement @@ -866,14 +901,17 @@ function end_player_turn() { game.phasing = ALLIED else game.phasing = AXIS - game.active = game.phasing + set_active_player() goto_player_turn() } function goto_player_turn() { + // paranoid resetting of state + game.side_limit = {} game.rommel = 0 game.from1 = game.from2 = 0 game.to1 = game.to2 = 0 + goto_supply_check() } @@ -922,6 +960,8 @@ states.turn_option = { }, } +// ==== MOVEMENT PHASE === + function goto_move_phase() { game.state = 'select_moves' if (game.active === AXIS) { @@ -1133,17 +1173,11 @@ states.move_who = { }, end_move() { clear_supply_networks() + // TODO + goto_combat_phase() } } -function rommel_group_move_bonus(from) { - if (game.rommel === 1 && from === game.from1 && !game.to1) - return 1 - if (game.rommel === 2 && from === game.from2 && !game.to2) - return 1 - return 0 -} - function print_path(who, from, to, road) { let p = [ hex_name[to] ] while (to && to !== from) { @@ -1190,7 +1224,7 @@ function apply_move(move, who, from, to) { claim_hexside_control(side) if (is_new_battle_hex(to)) { claim_hex_control_for_defender(to) - game.battles.push(to) + set_add(game.active_battles, to) } return true } @@ -1363,6 +1397,127 @@ function stop_move(who) { game.state = 'move_who' } +// ==== COMBAT PHASE === + +function goto_combat_phase() { + game.state = 'select_active_battles' +} + +states.select_active_battles = { + inactive: "combat phase (select active battles)", + prompt() { + view.prompt = `Select active battles.` + for (let x = first_hex; x <= last_hex; ++x) + if (hex_exists[x]) + if (!set_has(game.active_battles, x) && is_battle_hex(x)) + gen_action_hex(x) + gen_action('next') + }, + hex(x) { + push_undo() + set_add(game.active_battles, x) + }, + next() { + push_undo() + if (game.turn_option === 'assault') + game.state = 'select_assault_battles' + else + game.state = 'select_battle' + } +} + +states.select_assault_battles = { + inactive: "combat phase (select assault battles)", + prompt() { + view.prompt = `Select assault battles.` + for (let x of game.active_battles) + if (!set_has(game.assault_battles, x)) + gen_action_hex(x) + gen_action_next() + }, + hex(x) { + push_undo() + set_add(game.assault_battles, x) + }, + next() { + push_undo() + game.state = 'select_battle' + } +} + +states.select_battle = { + inactive: "combat phase (select next battle)", + prompt() { + view.prompt = `Select next battle to resolve.` + for (let x of game.active_battles) + gen_action_hex(x) + if (game.active_battles.length === 0) + gen_action('end_combat') + }, + hex(x) { + push_undo() + game.battle = x + goto_defensive_fire() + }, +} + +function goto_defensive_fire() { + set_passive_player() + game.fired = [] + game.state = 'defensive_fire' +} + +function goto_offensive_fire() { + set_active_player() + game.fired = [] + game.state = 'offensive_fire' +} + +const xxx_fire = { + prompt() { + view.prompt = `Fire!` + + let arty = false + for (let u = 0; u < units.length; ++u) { + if (is_friendly_unit(u) && !is_unit_fired(u) && unit_hex(u) === game.battle) { + if (is_artillery_unit(u)) { + gen_action_unit(u) + arty = true + } + } + } + + if (!arty) { + for (let u = 0; u < units.length; ++u) { + if (is_friendly_unit(u) && !is_unit_fired(u) && unit_hex(u) === game.battle) { + gen_action_unit(u) + } + } + } + }, + unit(who) { + clear_undo() + set_unit_fired(who) + + let done = true + for (let u = 0; u < units.length; ++u) + if (is_friendly_unit(u) && !is_unit_fired(u) && unit_hex(u) === game.battle) + done = false + if (done) + end_fire() + }, +} + +function end_fire() { + if (game.state === 'defensive_fire') + goto_offensive_fire() + else + end_combat_phase() +} + +states.defensive_fire = xxx_fire +states.offensive_fire = xxx_fire + // === DEPLOYMENT === states.free_deployment = { @@ -1403,10 +1558,10 @@ states.free_deployment = { gen_action_next() }, unit(u) { - if (game.selected.includes(u)) - remove_from_array(game.selected, u) + if (set_has(game.selected, u)) + set_delete(game.selected, u) else - game.selected.push(u) + set_add(game.selected, u) }, hex(x) { push_undo() @@ -1414,7 +1569,7 @@ states.free_deployment = { let u = game.selected[i] set_unit_hex(u, x) } - game.selected.length = 0 + set_clear(game.selected) }, next() { clear_undo() @@ -1910,10 +2065,9 @@ exports.setup = function (seed, scenario, options) { axis_sides: [], allied_sides: [], - // current turn option and moves + // current turn option and selected moves turn_option: null, side_limit: {}, - battles: [], rommel: 0, from1: 0, to1: 0, @@ -1924,6 +2078,14 @@ exports.setup = function (seed, scenario, options) { move_from: 0, move_used: 0, move_road: 4, + + // combat + active_battles: [], + assault_battles: [], + battle: 0, + fired: [], + hits: null, + flash: null, } setup(scenario) @@ -1956,6 +2118,10 @@ exports.view = function(state, current) { if (game.to1) view.to1 = game.to1 if (game.to2) view.to2 = game.to2 + if (game.battle) view.battle = game.battle + if (game.fired) view.fired = game.fired + if (game.flash) view.flash = game.flash + return common_view(current) } |