summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js200
1 files changed, 183 insertions, 17 deletions
diff --git a/rules.js b/rules.js
index bc6c618..4edfa17 100644
--- a/rules.js
+++ b/rules.js
@@ -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)
}