From 9d16099a168f0f31100e8293e1509620b099e20c Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 2 Sep 2022 18:23:20 +0200 Subject: Misc clean ups and bug fixes. Inactive prompts. Hide units after rout. Don't allow wasting supply by picking lesser turn options. --- rules.js | 135 +++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 92 insertions(+), 43 deletions(-) (limited to 'rules.js') diff --git a/rules.js b/rules.js index c25e4f7..b650c97 100644 --- a/rules.js +++ b/rules.js @@ -2310,15 +2310,15 @@ states.turn_option = { gen_action('dummy_card') } - if (game.commit[0] >= 1) + if (game.commit[0] === 1) view.actions.basic = 1 else view.actions.basic = 0 - if (game.commit[0] >= 2) + if (game.commit[0] === 2) view.actions.offensive = view.actions.assault = 1 else view.actions.offensive = view.actions.assault = 0 - if (game.commit[0] >= 3) + if (game.commit[0] === 3) view.actions.blitz = 1 else view.actions.blitz = 0 @@ -2588,6 +2588,7 @@ function assign_fortress_supply() { } const xxx_fortress_supply = { + inactive: "supply check", prompt() { let ix = game.assign let ss = FORTRESS_SRC_LIST[ix] @@ -2671,6 +2672,7 @@ function assign_oasis_supply() { } const xxx_oasis_supply = { + inactive: "supply check", prompt() { let ix = game.assign let oasis = OASIS_HEX_LIST[ix] @@ -2752,6 +2754,7 @@ function goto_initial_supply_check_rout() { } states.initial_supply_check_rout = { + inactive: "supply check", prompt() { view.prompt = `Initial Supply Check: Rout!` for (let x of all_hexes) @@ -2830,6 +2833,7 @@ function goto_final_supply_check_rout() { } states.final_supply_check_rout = { + inactive: "supply check", prompt() { view.prompt = `Final Supply Check: Rout!` for (let x of all_hexes) @@ -2965,7 +2969,7 @@ function gen_rommel_move() { } states.group_move_from = { - inactive: "group move (from)", + inactive: "move phase", prompt() { view.prompt = `Group Move: Select hex to move from.` gen_rommel_move() @@ -3049,7 +3053,7 @@ states.group_move_from = { } states.regroup_move_command_point = { - inactive: "regroup move (command point)", + inactive: "move phase", prompt() { view.prompt = `Regroup Move: Designate the command point hex.` gen_rommel_move() @@ -3086,7 +3090,7 @@ states.regroup_move_command_point = { } states.regroup_move_destination = { - inactive: "regroup move (destination)", + inactive: "move phase", prompt() { view.prompt = `Regroup Move: Select destination hex.` gen_rommel_move() @@ -3213,7 +3217,7 @@ function can_end_move() { } states.move = { - inactive: "move", + inactive: "move phase", prompt() { let rommel1 = (game.rommel === 1) ? 1 : 0 let rommel2 = (game.rommel === 2) ? 1 : 0 @@ -3348,6 +3352,7 @@ states.move = { } states.overrun = { + inactive: "move phase", prompt() { view.prompt = `Overrun!` for (let x of all_hexes) @@ -3579,6 +3584,7 @@ function move_unit(who, to, speed, move) { } states.forced_march_via = { + inactive: "move phase", prompt() { view.prompt = `Move: Select which path to take.` view.selected = game.hexside.who @@ -3586,13 +3592,11 @@ 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 rommel = (game.hexside.move === game.rommel) ? 1 : 0 let who = game.hexside.who let from = unit_hex(who) let speed = unit_speed[who] - - search_move(from, speed + 1 + (rommel1 | rommel2)) + search_move(from, speed + 1 + rommel) forced_march_via(game.hexside.who, via, game.hexside.to, game.hexside.move) game.hexside = null @@ -3601,6 +3605,7 @@ states.forced_march_via = { } states.engage_via = { + inactive: "move phase", prompt() { view.prompt = `Move: Select which hex side to cross.` view.selected = game.hexside.who @@ -3611,24 +3616,22 @@ 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 rommel = (game.hexside.move === game.rommel) ? 1 : 0 let who = game.hexside.who let from = unit_hex(who) let speed = unit_speed[who] - search_move(from, speed + 1 + (rommel1 | rommel2)) + search_move(from, speed + 1 + rommel) forced_march_via(game.hexside.who, via, game.hexside.to, game.hexside.move) game.hexside = null game.state = 'move' }, hex(via) { - let rommel1 = (game.rommel === 1) ? 1 : 0 - let rommel2 = (game.rommel === 2) ? 1 : 0 + let rommel = (game.hexside.move === game.rommel) ? 1 : 0 let who = game.hexside.who let from = unit_hex(who) let speed = unit_speed[who] - search_move(from, speed + (rommel1 | rommel2)) + search_move(from, speed + rommel) engage_via(game.hexside.who, via, game.hexside.to, game.hexside.move) game.hexside = null @@ -3722,6 +3725,7 @@ function resume_forced_marches() { } states.forced_marches = { + inactive: "forced marches", prompt() { view.prompt = `Forced Marches!` for (let [who, to] of game.forced) @@ -3778,6 +3782,7 @@ function goto_forced_marches_rout() { } states.forced_marches_rout = { + inactive: "forced marches", prompt() { view.prompt = `Forced Marches: Rout!` for (let x of all_hexes) @@ -3896,6 +3901,7 @@ function goto_retreat() { } states.retreat_from = { + inactive: "retreat", prompt() { view.prompt = `Retreat: Select hex to retreat from.` @@ -3951,6 +3957,7 @@ function goto_retreat_who(from) { } states.retreat_who = { + inactive: "retreat", prompt() { view.prompt = `Retreat: Select units to retreat.` let full_retreat = true @@ -4006,6 +4013,7 @@ function apply_retreat() { } states.provoke_probe_combat = { + inactive: "probe combat", prompt() { view.prompt = `Retreat: You may provoke probe combat at ${hex_name[game.retreat]}.` view.selected = game.retreat_units @@ -4056,6 +4064,7 @@ function goto_retreat_move() { } states.retreat_move = { + inactive: "retreat", prompt() { view.prompt = `Retreat!` if (game.selected < 0) { @@ -4171,7 +4180,7 @@ function goto_refuse_battle_move() { } states.refuse_battle_move = { - inactive: "refuse battle (withdraw group move)", + inactive: "refuse battle", prompt() { view.prompt = `Refuse Battle: Withdraw units.` if (game.selected < 0) { @@ -4262,6 +4271,7 @@ function goto_rout(from, enemy, after) { } states.rout_elimination = { + inactive: "rout", prompt() { view.prompt = "Rout: Eliminate all units that can not disengage." for_each_friendly_unit_in_hex(game.rout.from, u => { @@ -4277,6 +4287,7 @@ states.rout_elimination = { } states.rout_attrition = { + inactive: "rout", prompt() { view.prompt = "Rout: All units lose one step of rout attrition." for_each_friendly_unit_in_hex(game.rout.from, u => { @@ -4310,6 +4321,7 @@ function goto_rout_move() { } states.rout_move = { + inactive: "rout", prompt() { view.prompt = `Rout: Withdraw units.` if (game.selected < 0) { @@ -4360,6 +4372,7 @@ function end_rout() { log_br() 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) if (game.active !== game.rout.active) set_enemy_player() @@ -4574,7 +4587,7 @@ function roll_battle_fire(who, tc) { if (fc !== ARTILLERY && is_minefield_offensive_fire()) total = total / 2 - game.flash = `${class_name_cap[fc]} ${firepower_name[fp]} ${result.join("")} at ${class_name[tc]}` + game.flash = `${class_name_cap[fc]} ${firepower_name[fp]} ${result.join("")} at ${class_name[tc]}.` log(game.flash) return total } @@ -4651,14 +4664,15 @@ function goto_hits() { game.hits[2] |= 0 game.hits[3] |= 0 + game.flash = "Inflicted " + format_hits() + "." + log(game.flash) + if (game.hits[0] + game.hits[1] + game.hits[2] + game.hits[3] > 0) { - game.flash = format_allocate_hits() if (game.state === 'battle_fire') game.state = 'battle_hits' else game.state = 'probe_hits' } else { - game.flash = "No hits" if (game.state === 'battle_fire') end_battle_hits() else @@ -4802,11 +4816,18 @@ function gen_battle_hits() { } function apply_battle_hit(who) { - game.flash = "" + if (unit_steps(who) === 1) { + log(`Eliminated ${class_name[unit_class[who]]}.`) + game.flash = `Eliminated ${class_name[unit_class[who]]} \u2014 ` + } else { + game.flash = `Reduced ${class_name[unit_class[who]]} \u2014 ` + } game.hits[unit_class[who]] -= reduce_unit(who) + game.flash += format_hits() + " left." } states.battle_fire = { + inactive: "battle (fire)", prompt() { if (game.active === game.phasing) view.prompt = `Battle: Offensive Fire!` @@ -4840,11 +4861,12 @@ states.battle_fire = { } states.battle_hits = { + inactive: "battle (hits)", prompt() { if (game.active === game.phasing) - view.prompt = `Battle: ${format_allocate_hits()} from Defensive Fire.` + view.prompt = `Battle: Allocate ${format_hits()} from Defensive Fire.` else - view.prompt = `Battle: ${format_allocate_hits()} from Offensive Fire.` + view.prompt = `Battle: Allocate ${format_hits()} from Offensive Fire.` gen_battle_hits() }, unit_hit(who) { @@ -4872,6 +4894,7 @@ function end_battle_hits() { } states.probe_fire = { + inactive: "probe combat (fire)", prompt() { if (game.active !== game.phasing) view.prompt = `Probe: Offensive Fire!` @@ -4903,11 +4926,12 @@ states.probe_fire = { } states.probe_hits = { + inactive: "probe combat (hits)", prompt() { if (game.active !== game.phasing) - view.prompt = `Probe: ${format_allocate_hits()} from Defensive Fire.` + view.prompt = `Probe: Allocate ${format_hits()} from Defensive Fire.` else - view.prompt = `Probe: ${format_allocate_hits()} from Offensive Fire.` + view.prompt = `Probe: Allocate ${format_hits()} from Offensive Fire.` gen_battle_hits() }, unit_hit(who) { @@ -5030,18 +5054,32 @@ function goto_pursuit_fire_during_refuse_battle(where) { game.state = 'pursuit_fire' } -function format_allocate_hits() { - let hits = 0 - if (typeof game.hits === 'number') - hits = game.hits - else - hits = game.hits[0] + game.hits[1] + game.hits[2] + game.hits[3] - if (hits === 0) - return `Allocate zero hits` - else if (hits === 1) - return `Allocate 1 hit` - else - return `Allocate ${hits} hits` +function format_hits() { + if (typeof game.hits === 'number') { + if (game.hits === 0) + return "zero hits" + if (game.hits === 1) + return "1 hit" + return game.hits + " hits" + } + + let n = game.hits[0] + game.hits[1] + game.hits[2] + game.hits[3] + if (n === 0) + return `zero hits` + + let s = [] + if (game.hits[ARMOR] > 0) + s.push(game.hits[ARMOR] + " armor") + if (game.hits[INFANTRY] > 0) + s.push(game.hits[INFANTRY] + " infantry") + if (game.hits[ANTITANK] > 0) + s.push(game.hits[ANTITANK] + " anti-tank") + if (game.hits[ARTILLERY] > 0) + s.push(game.hits[ARTILLERY] + " artillery") + + if (n === 1) + return s.join(", ") + " hit" + return s.join(", ") + " hits" } function goto_rout_hits() { @@ -5079,11 +5117,11 @@ function roll_pursuit_fire_imp(who, n, hp) { } else { b = die_face_miss[b] } - game.flash = `${speed_name_cap[speed]} fired ${a}${b}` + game.flash = `${speed_name_cap[speed]} fired ${a}${b}.` } if (n === 1) { let a = roll_die() - game.flash = `${speed_name_cap[speed]} fired ${a}` + game.flash = `${speed_name_cap[speed]} fired ${a}.` if (a >= 4) { game.hits++ a = die_face_hit[a] @@ -5185,7 +5223,7 @@ function gen_pursuit_hits(normal_steps, elite_steps, iterate) { states.pursuit_hits = { inactive: "pursuit fire (hits)", prompt() { - view.prompt = "Pursuit Fire: " + format_allocate_hits() + "." + view.prompt = "Pursuit Fire: Allocate " + format_hits() + "." let normal_steps = count_normal_steps_in_pursuit() let elite_steps = count_elite_steps_in_pursuit() gen_pursuit_hits(normal_steps, elite_steps, for_each_undisrupted_friendly_unit_in_hex) @@ -5203,7 +5241,7 @@ states.pursuit_hits = { states.rout_hits = { inactive: "rout fire (hits)", prompt() { - view.prompt = "Pursuit Fire: " + format_allocate_hits() + "." + view.prompt = "Pursuit Fire: Allocate " + format_hits() + "." let normal_steps = count_normal_steps_in_rout() let elite_steps = count_elite_steps_in_rout() gen_pursuit_hits(normal_steps, elite_steps, for_each_friendly_unit_in_hex) @@ -5264,6 +5302,7 @@ function goto_buildup_discard() { } states.buildup_discard = { + inactive: "buildup (discard)", prompt() { view.prompt = "Buildup: Discard any unwanted dummy cards." let hand = player_hand() @@ -5341,6 +5380,7 @@ function resume_buildup_eliminate_unsupplied() { } states.buildup_eliminate_unsupplied = { + inactive: "buildup (unsupplied)", prompt() { view.prompt = `Buildup: Eliminate unsupplied units.` for_each_friendly_unit_on_map(u => { @@ -5434,6 +5474,7 @@ function goto_buildup_reinforcements() { } states.buildup_reinforcements = { + inactive: "buildup (reinforcements)", prompt() { view.prompt = `Buildup: Bring on reinforcements.` gen_action_hex(friendly_base()) @@ -5575,7 +5616,7 @@ function gen_spending_bps() { // Receive replacement in base if (from === base) { - if (unit_lost_steps(who) > 0 && bps <= replacement_cost(who)) + if (unit_lost_steps(who) > 0 && bps >= replacement_cost(who)) view.actions.replacement = 1 else view.actions.replacement = 0 @@ -5625,6 +5666,7 @@ function gen_spending_bps() { } states.spending_bps = { + inactive: "buildup", prompt() { view.prompt = `Buildup: Spend buildup points (${available_bps()} remain).` if (game.selected < 0) { @@ -5758,6 +5800,7 @@ function friendly_buildup_network() { } states.minefield = { + inactive: "buildup", prompt() { view.prompt = `Buildup: Build a minefield.` let mfs = friendly_minefields() @@ -5782,6 +5825,7 @@ states.minefield = { } states.dismantle1 = { + inactive: "buildup", prompt() { view.prompt = `Buildup: Dismantle first minefield to build a new one.` let mfs = friendly_minefields() @@ -5798,6 +5842,7 @@ states.dismantle1 = { } states.dismantle2 = { + inactive: "buildup", prompt() { view.prompt = `Buildup: Dismantle second minefield to build a new one.` let mfs = friendly_minefields() @@ -5814,6 +5859,7 @@ states.dismantle2 = { } states.dismantle3 = { + inactive: "buildup", prompt() { view.prompt = `Buildup: Build a new minefield.` let mfs = friendly_minefields() @@ -5869,6 +5915,7 @@ function goto_player_initiative() { } states.allied_player_initiative = { + inactive: "initiative", prompt() { view.prompt = "Initiative: You may challenge for the initiative." let hand = player_hand() @@ -5897,6 +5944,7 @@ states.allied_player_initiative = { } states.axis_player_initiative = { + inactive: "initiative", prompt() { view.prompt = "Initiative: You may defend your initiative." let hand = player_hand() @@ -6097,6 +6145,7 @@ function goto_initial_supply_cards() { } states.initial_supply_cards = { + inactive: "mulligan", prompt() { view.prompt = `Setup: You may discard your entire hand and redraw a new one.` gen_action('discard') -- cgit v1.2.3