diff options
-rw-r--r-- | play.html | 9 | ||||
-rw-r--r-- | play.js | 44 | ||||
-rw-r--r-- | rules.js | 86 |
3 files changed, 95 insertions, 44 deletions
@@ -26,7 +26,9 @@ header.your_turn { background-color: orange; } #log { background-color: ghostwhite; } #log .h1 { background-color: silver; font-weight: bold; padding-top:2px; padding-bottom:2px; text-align: center; } #log .h2 { background-color: gainsboro; padding-top:2px; padding-bottom:2px; text-align: center; } -#log .h3 { background-color: whitesmoke; padding-top:2px; padding-bottom:2px; text-align: center; } +#log .h3 { background-color: lavender; padding-top:2px; padding-bottom:2px; text-align: center; } +#log > .i { padding-left: 20px; } +#log > div > .i { padding-left: 12px; } .role_info { padding: 15px; } @@ -295,6 +297,11 @@ svg .hex.allied_control { fill-opacity: 0.2; } +svg .hex.tip { + fill: black; + fill-opacity: 0.6; +} + #map .unit { position: absolute; } @@ -624,10 +624,23 @@ function on_update() { action_button("undo", "Undo") } +function on_focus_hex_tip(x) { + ui.hexes[x].classList.add("tip") +} + +function on_click_hex_tip(x) { + console.log(ui.hexes[x]) + ui.hexes[x].scrollIntoView({ block:"center", inline:"center", behavior:"smooth" }) +} + +function on_blur_hex_tip(x) { + ui.hexes[x].classList.remove("tip") +} + function sub_hex_name(match, p1, offset, string) { let x = p1 | 0 let n = hex_name[x] - return `<span class="hex" onmouseenter="on_focus_hex_tip(${x})" onmouseleave="on_blur_hex_tip(${x})">${n}</span>` + return `<span class="hex" onmouseenter="on_focus_hex_tip(${x})" onmouseleave="on_blur_hex_tip(${x})" onclick="on_click_hex_tip(${x})">${n}</span>` } function sub_unit_name(match, p1, offset, string) { @@ -635,8 +648,21 @@ function sub_unit_name(match, p1, offset, string) { return units[u].name } +function on_log_line(text, cn) { + let p = document.createElement("div") + if (cn) p.className = cn + p.innerHTML = text + return p +} + function on_log(text) { let p = document.createElement("div") + + if (text.match(/^>/)) { + text = text.substring(1) + p.className = "i" + } + text = text.replace(/&/g, "&") text = text.replace(/</g, "<") text = text.replace(/>/g, ">") @@ -646,20 +672,20 @@ function on_log(text) { if (text.match(/^\.h1/)) { text = text.substring(4) - p.className = 'h1' + p.className = "h1" } if (text.match(/^\.h2/)) { text = text.substring(4) - if (text.startsWith('Axis')) - p.className = 'h2 axis' - else if (text.startsWith('Allied')) - p.className = 'h2 allied' + if (text.startsWith("Axis")) + p.className = "h2 axis" + else if (text.startsWith("Allied")) + p.className = "h2 allied" else - p.className = 'h2' + p.className = "h2" } if (text.match(/^\.h3/)) { text = text.substring(4) - p.className = 'h3' + p.className = "h3" } if (text.indexOf("\n") < 0) { @@ -668,7 +694,7 @@ function on_log(text) { text = text.split("\n") p.appendChild(on_log_line(text[0])) for (let i = 1; i < text.length; ++i) - p.appendChild(on_log_line(text[i], "indent")) + p.appendChild(on_log_line(text[i], "i")) } return p } @@ -67,8 +67,6 @@ const first_allied_unit = units.findIndex(item => item.nationality === 'allied') const last_axis_unit = first_allied_unit - 1 const last_allied_unit = units.length - 1 -console.log("FOO", first_axis_unit, last_axis_unit, first_allied_unit, last_allied_unit) - function debug_hexes3(n, list) { console.log("--", n, "--") list = list.map((x,i) => hex_exists[i] ? x : "") @@ -111,6 +109,7 @@ const AXIS = 'Axis' const ALLIED = 'Allied' const firepower_name = [ "0", "1", "2", "3", "TF", "DF", "SF" ] +const speed_name = [ "zero", "leg", "motorized", "mechanized", "recon" ] const SF = 6 const DF = 5 @@ -955,7 +954,7 @@ function print_path(who, from, to, road) { to = path_from[road][to] p.unshift(hex_name[to]) } - log(unit_name(who) + " moved " + p.join(", ") + ".") + log(">" + p.join(" - ") + ".") } function search_move(start, start_cost, start_road) { @@ -1241,7 +1240,7 @@ function set_active_player() { } function set_passive_player() { - if (game.active === AXIS) + if (game.phasing === AXIS) game.active = ALLIED else game.active = AXIS @@ -1286,7 +1285,7 @@ function goto_initial_supply_check() { if (snet[x]) { set_unit_supply(u, ssrc) if (is_unit_disrupted(u) && set_has(game.recover, u) && !is_battle_hex(x)) { - log(`%${u} recovered at #${x}`) + log(`Recovered at #${x}`) set_delete(game.recover, u) clear_unit_disrupted(u) } @@ -1501,7 +1500,7 @@ function goto_move_who() { log(`Group move from #${game.from1} (Rommel).`) } else { if (game.from1 && game.to1) - log(`Regroup move from #${game.from1} to #${game.to1}.`) + log(`Regroup move\nfrom #${game.from1}\nto #${game.to1}.`) else if (game.from1) log(`Group move from #${game.from1}.`) } @@ -1516,6 +1515,8 @@ function goto_move_who() { else if (game.from2) log(`Group move from #${game.from2}.`) } + log_br() + log("Moved:") game.state = 'move_who' } @@ -1571,10 +1572,12 @@ states.move_who = { }, retreat() { push_undo() + log_br() game.state = 'retreat_select_from' }, end_move() { clear_undo() + log_br() end_move_phase() } } @@ -1602,8 +1605,6 @@ function apply_move(move, who, from, to) { if (is_battle_hex(to)) { let side = to_side_id(to, path_from[road][to]) - log(`cross ${side} ${hex_name[to]}/${hex_name[path_from[road][to]]}`) - if (game.side_limit[side]) game.side_limit[side] = 2 else @@ -1697,7 +1698,6 @@ states.move_to = { search_move(from, 0, 4) if (can_move_group_1(who, from, to)) { - log(`group moved ${who} to ${to}`) game.move_from = from if (apply_move(1, who, from, to)) stop_move(who) @@ -1707,7 +1707,6 @@ states.move_to = { } if (can_move_group_2(who, from, to)) { - log(`group moved ${who} to ${to}`) game.move_from = from if (apply_move(2, who, from, to)) stop_move(who) @@ -1717,7 +1716,6 @@ states.move_to = { } if (can_move_regroup_1(who, from, to)) { - log(`regrouped ${who} to ${to}`) apply_move(1, who, from, to) stop_move(who) game.state = 'move_who' @@ -1725,7 +1723,6 @@ states.move_to = { } if (can_move_regroup_2(who, from, to)) { - log(`regrouped ${who} to ${to}`) apply_move(2, who, from, to) stop_move(who) game.state = 'move_who' @@ -1882,7 +1879,7 @@ states.retreat_select_who = { }) game.retreat_units = game.selected game.selected = [] - goto_retreat_pursuit_fire(game.retreat) + goto_pursuit_fire_during_retreat(game.retreat) }, partial_retreat() { clear_undo() @@ -1911,7 +1908,7 @@ states.provoke_probe_combat = { if (shielded) goto_retreat_who() else - goto_retreat_pursuit_fire(game.retreat) + goto_pursuit_fire_during_retreat(game.retreat) }, } @@ -2018,8 +2015,9 @@ states.refuse_battle = { }, hex(x) { push_undo() + log_h3(`Refused battle at #${x}`) set_delete(game.active_battles, x) - goto_refuse_pursuit_fire(x) + goto_pursuit_fire_during_refuse_battle(x) }, next() { goto_combat_phase() @@ -2068,6 +2066,7 @@ states.refuse_battle_to = { }, hex(to) { let who = game.selected[0] + log(`>to #${to}`) set_unit_hex(who, to) set_unit_disrupted(who) game.selected = [] @@ -2390,31 +2389,46 @@ function end_probe() { // === PURSUIT FIRE === -function goto_retreat_pursuit_fire(where) { +// Refuse battle +// active pursuit fire +// passive apply hits +// passive moves + +// Retreat +// passive pursuit fire +// active apply hits +// active moves + +// Rout +// non-routing pursuit fire +// routing apply hits +// routing moves + +function goto_pursuit_fire_during_retreat(where) { clear_undo() set_passive_player() game.hits = 0 game.pursuit = where if (can_pursuit_fire()) - game.state = 'retreat_pursuit_fire' + game.state = 'pursuit_fire' else goto_pursuit_hits() } -function goto_refuse_pursuit_fire(where) { +function goto_pursuit_fire_during_refuse_battle(where) { clear_undo() set_active_player() game.hits = 0 game.pursuit = where - if (can_pursuit_fire()) - game.state = 'refuse_pursuit_fire' + if (can_pursuit_fire(true)) + game.state = 'pursuit_fire' else goto_pursuit_hits() } function goto_pursuit_hits() { + set_enemy_player() if (game.hits > 0) { - set_passive_player() let hp = count_hp_in_pursuit() if (game.hits > hp) game.hits = hp @@ -2434,10 +2448,11 @@ function slowest_undisrupted_enemy_unit_speed(where) { return r } -function can_pursuit_fire() { +function can_pursuit_fire(verbose) { let result = false let slowest = slowest_undisrupted_enemy_unit_speed(game.pursuit) - log(`Slowest enemy speed is ${slowest}.`) + if (verbose) + log(`Slowest enemy was ${speed_name[slowest]}.`) for_each_undisrupted_friendly_unit_in_hex(game.pursuit, u => { if (unit_speed(u) >= slowest && !is_unit_fired(u)) result = true @@ -2445,11 +2460,11 @@ function can_pursuit_fire() { return result } -function roll_pursuit_fire(n) { +function roll_pursuit_fire(who, n) { if (n === 2) { let a = random(6) + 1 let b = random(6) + 1 - log(`Pursuit fire ${a}, ${b}.`) + log(`>%${who} pursuit fired ${a}, ${b}.`) if (a >= 4) game.hits++ if (b >= 4) @@ -2457,13 +2472,18 @@ function roll_pursuit_fire(n) { } if (n === 1) { let a = random(6) + 1 - log(`Pursuit fire ${a}.`) + log(`>%${who} pursuit fired ${a}.`) if (a >= 4) game.hits++ } + + let hp = count_hp_in_pursuit() + if (game.hits > hp) + game.hits = hp + return game.hits === hp } -const xxx_pursuit_fire = { +states.pursuit_fire = { inactive: "pursuit fire (fire)", prompt() { view.prompt = `Pursuit Fire.` @@ -2472,22 +2492,22 @@ const xxx_pursuit_fire = { if (unit_speed(u) >= slowest && !is_unit_fired(u)) gen_action_unit(u) }) + // TODO: only save fire if there are shielded enemy units? gen_action('next') }, unit(who) { let slowest = slowest_undisrupted_enemy_unit_speed(game.pursuit) - if (unit_speed(who) > slowest) - roll_pursuit_fire(2) - else - roll_pursuit_fire(1) set_unit_fired(who) + let done = roll_pursuit_fire(who, (unit_speed(who) > slowest ? 2 : 1)) + if (done || !can_pursuit_fire(false)) + goto_pursuit_hits() }, next() { goto_pursuit_hits() } } -const xxx_pursuit_hits = { +states.pursuit_hits = { inactive: "pursuit fire (hits)", prompt() { view.prompt = `Pursuit Fire: Apply ${game.hits} hits.` @@ -2532,10 +2552,8 @@ function end_pursuit_fire() { game.from1 = game.pursuit game.pursuit = 0 if (game.retreat) { - set_active_player() game.state = 'retreat_who' } else { - set_passive_player() game.state = 'refuse_battle_who' } } |