summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js134
1 files changed, 106 insertions, 28 deletions
diff --git a/rules.js b/rules.js
index 0930ef5..6a8a636 100644
--- a/rules.js
+++ b/rules.js
@@ -171,6 +171,11 @@ const SS_BENGHAZI = 3
const SS_TOBRUK = 4
const SS_OASIS = 5
+const MF_AXIS = 0
+const MF_ALLIED = 1
+const MF_VISIBLE = 2
+const MF_REVEAL = 3
+
const region_egypt = regions["Egypt"]
const region_egypt_and_libya = regions["Libya"].concat(regions["Egypt"])
const region_libya_and_sidi_omar = regions["Libya"].concat(regions["Sidi Omar"])
@@ -1483,10 +1488,7 @@ function friendly_supply_network() {
// === PATHING ===
-// NOTE: we don't actually need path_from but we can use it to show paths taken in client
-// NOTE: we may need the path to reveal minefields moved through
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) ]
const path_valid = new Array(hexcount)
@@ -1735,6 +1737,16 @@ function can_move_to(to, speed) {
return false
}
+function move_road(to, speed) {
+ if (path_cost[4][to] <= speed + 4)
+ return 4
+ if (path_cost[2][to] <= speed + 2)
+ return 2
+ if (path_cost[1][to] <= speed + 1)
+ return 1
+ return 0
+}
+
function max_speed_of_undisrupted_and_unmoved_friendly_unit_in_hex(from) {
let max_speed = 0
for_each_undisrupted_and_unmoved_friendly_unit_in_hex(from, u => {
@@ -1756,6 +1768,33 @@ function find_valid_regroup_destinations(from, rommel) {
}
}
+// === MINEFIELDS ===
+
+function visit_hex(x) {
+ let mf_enemy = (game.active === AXIS) ? MF_AXIS : MF_ALLIED
+ if (set_has(game.minefields[mf_enemy], x))
+ set_add(game.minefields[MF_REVEAL], x)
+ console.log("VISIT", x, hex_name[x])
+}
+
+function visit_path(from, to, speed) {
+ let road = move_road(to, speed)
+ while (to && to !== from) {
+ visit_hex(to)
+ to = path_from[road][to]
+ }
+}
+
+function reveal_visited_minefields() {
+ for (let x of game.minefields[MF_REVEAL]) {
+ log(`Minefield at #${x}.`)
+ set_delete(game.minefields[MF_AXIS], x)
+ set_delete(game.minefields[MF_ALLIED], x)
+ set_add(game.minefields[MF_VISIBLE], x)
+ }
+ set_clear(game.minefields[MF_REVEAL])
+}
+
// === SUPPLY COMMITMENT & TURN OPTION ===
function goto_turn_option() {
@@ -2341,6 +2380,7 @@ states.select_moves = {
},
end_turn() {
clear_undo()
+ reveal_visited_minefields()
goto_final_supply_check()
}
}
@@ -2816,7 +2856,7 @@ function move_unit(who, to, speed, move) {
if (game.hexside.forced[0])
forced_march_via(who, game.hexside.via[0], to, move)
else
- engage_via(who, game.hexside.via[0], to)
+ engage_via(who, game.hexside.via[0], to, move)
delete game.hexside
} else {
game.state = 'engage_via'
@@ -2825,6 +2865,7 @@ function move_unit(who, to, speed, move) {
else {
log(`>from #${from} to #${to}`)
+ visit_path(from, to, speed)
set_unit_moved(who)
set_unit_hex(who, to)
}
@@ -2838,6 +2879,14 @@ states.forced_march_via = {
gen_action_hex(x)
},
hex(via) {
+ let rommel1 = (game.rommel === 1) ? 1 : 0
+ let rommel2 = (game.rommel === 2) ? 1 : 0
+ let who = game.hexside.who
+ let from = unit_hex(who)
+ let speed = unit_speed[who]
+
+ search_move(from, speed + 1 + (rommel1 | rommel2))
+
forced_march_via(game.hexside.who, via, game.hexside.to, game.hexside.move)
delete game.hexside
game.state = 'move'
@@ -2855,22 +2904,39 @@ states.engage_via = {
gen_action_hex(game.hexside.via[i])
},
forced_march(via) {
+ let rommel1 = (game.rommel === 1) ? 1 : 0
+ let rommel2 = (game.rommel === 2) ? 1 : 0
+ let who = game.hexside.who
+ let from = unit_hex(who)
+ let speed = unit_speed[who]
+ search_move(from, speed + 1 + (rommel1 | rommel2))
+
forced_march_via(game.hexside.who, via, game.hexside.to, game.hexside.move)
delete game.hexside
game.state = 'move'
},
hex(via) {
- engage_via(game.hexside.who, via, game.hexside.to)
+ let rommel1 = (game.rommel === 1) ? 1 : 0
+ let rommel2 = (game.rommel === 2) ? 1 : 0
+ let who = game.hexside.who
+ let from = unit_hex(who)
+ let speed = unit_speed[who]
+ search_move(from, speed + (rommel1 | rommel2))
+
+ engage_via(game.hexside.who, via, game.hexside.to, game.hexside.move)
delete game.hexside
game.state = 'move'
}
}
function forced_march_via(who, via, to, move) {
+ let speed = unit_speed[who] + (game.rommel === move ? 1 : 0)
let from = unit_hex(who)
set_unit_moved(who)
set_unit_hex(who, via)
+ visit_path(from, via, speed)
+
// remember where we should advance to / return to
if ((move === 1 && game.to1) || (move === 2 && game.to2))
game.forced.push([who, to, from])
@@ -2889,12 +2955,25 @@ function forced_march_via(who, via, to, move) {
log(`>forced march from #${from} via #${via} to #${to}`)
}
-function engage_via(who, via, to) {
+function engage_via(who, via, to, move) {
+ let speed = unit_speed[who] + (game.rommel === move ? 1 : 0)
let from = unit_hex(who)
set_unit_moved(who)
set_unit_hex(who, to)
+ visit_path(from, via, speed)
+ visit_hex(to)
+
+ if (from !== via)
+ log(`>from #${from} via #${via} to #${to}`)
+ else
+ log(`>from #${from} to #${to}`)
+
+ engage_via_hexside(who, via, to)
+}
+
+function engage_via_hexside(who, via, to) {
let side = to_side_id(via, to)
if (game.side_limit[side])
game.side_limit[side] = 2
@@ -2913,11 +2992,6 @@ function engage_via(who, via, to) {
claim_hex_control_for_defender(to)
set_add(game.active_battles, to)
}
-
- if (from !== via)
- log(`>from #${from} via #${via} to #${to}`)
- else
- log(`>from #${from} to #${to}`)
}
// === FORCED MARCHES ===
@@ -2944,8 +3018,9 @@ states.forced_marches = {
let roll = roll_die()
if (roll >= 4) {
log(`Forced March roll ${die_face_hit[roll]} success.`)
+ visit_hex(to)
if (has_enemy_unit(to)) {
- engage_via(who, via, to, false)
+ engage_via_hexside(who, via, to, false)
} else {
set_unit_hex(who, to)
log(`>from #${via} to #${to}`)
@@ -3630,6 +3705,8 @@ function is_mandatory_combat(fortress) {
function goto_combat_phase() {
set_active_player()
+ reveal_visited_minefields()
+
if (game.turn_option === 'pass') {
if (is_mandatory_combat(BARDIA))
return goto_rout(BARDIA, false, goto_combat_phase)
@@ -4673,12 +4750,12 @@ function count_secret_minefields() {
let n = 0
if (is_axis_player()) {
let network = game.buildup.axis_network
- for (let x of game.axis_minefields)
+ for (let x of game.minefields[MF_AXIS])
if (network[x])
++n
} else {
let network = game.buildup.allied_network
- for (let x of game.allied_minefields)
+ for (let x of game.minefields[MF_ALLIED])
if (network[x])
++n
}
@@ -5732,10 +5809,8 @@ exports.setup = function (seed, scenario, options) {
raiders: [],
recover: [],
- axis_minefields: [],
- allied_minefields: [],
- reveal_minefields: [], // to be revealed at end of movement
- minefields: [], // revealed to both players
+ // axis/allied/visible/to-be-revealed
+ minefields: [[],[],[],[]], // revealed to both players
// fortress control
fortress: 7,
@@ -5810,22 +5885,25 @@ exports.view = function(state, current) {
allied_sides: game.allied_sides,
}
+ let player_minefields = null
if (current === AXIS) {
view.cards = game.axis_hand
- if (game.axis_minefields.length > 0)
- view.minefields = game.minefields.concat(game.axis_minefields)
- else
- view.minefields = game.minefields
+ if (game.minefields[MF_AXIS].length > 0)
+ player_minefields = game.minefields[MF_AXIS]
}
else if (current === ALLIED) {
view.cards = game.allied_hand
- if (game.allied_minefields.length > 0)
- view.minefields = game.minefields.concat(game.allied_minefields)
- else
- view.minefields = game.minefields
+ if (game.minefields[MF_ALLIED].length > 0)
+ player_minefields = game.minefields[MF_ALLIED]
}
- else {
- view.minefields = game.minefields
+ if (game.minefields[MF_VISIBLE].length > 0) {
+ if (player_minefields)
+ view.minefields = game.minefields[MF_VISIBLE].concat(player_minefields)
+ else
+ view.minefields = game.minefields[MF_VISIBLE]
+ } else {
+ if (player_minefields)
+ view.minefields = player_minefields
}
if (current === game.active)