From 511f63e26b2d150396d917bef2cfbfc32593e81c Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sat, 16 Dec 2023 03:38:40 +0100 Subject: fix counterattack order --- rules.js | 43 ++++++++++++++++++++++++++++++++----------- tools/gendata.js | 14 ++++++++++++-- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/rules.js b/rules.js index 2316da4..bd4138e 100644 --- a/rules.js +++ b/rules.js @@ -2419,21 +2419,32 @@ function current_action() { function find_target_of_attack(c, a) { let in_res = card_has_rule(c, "attack_reserve") - for (let c of a.target_list) { - if (set_has(game.front[0], c)) - return c - if (set_has(game.front[1], c)) - return c + for (let t of a.target_list) { + if (set_has(game.front[0], t)) + return t + if (set_has(game.front[1], t)) + return t if (in_res) { - if (set_has(game.reserve[0], c)) - return c - if (set_has(game.reserve[1], c)) - return c + if (set_has(game.reserve[0], t)) + return t + if (set_has(game.reserve[1], t)) + return t } } return -1 } +function find_target_of_counterattack(a) { + // Note: only used for no-choice counterattacks + for (let t of a.target_list) { + if (set_has(game.front[0], t)) + return t + if (set_has(game.front[1], t)) + return t + } + return -1 +} + function find_first_target_of_command(c, a) { if (game.scenario === S37_INKERMAN) { @@ -2998,20 +3009,30 @@ function can_take_reaction(c, a, wild) { switch (a.type) { default: throw new Error("invalid reaction: " + a.type) + case "Screen": // if a friendly formation is attacked by a listed enemy formation // ... or a listed formation is attacked (Wheatfield Road Artillery, etc) if (!a.target_list.includes(game.selected) && !a.target_list.includes(game.target)) return false break + case "Counterattack": // if this formation is attacked if (game.target !== c) return false // ... by one of the listed targets - if (!a.target_list.includes(game.selected)) - return false + if (a.choice) { + // if "any" or "or" choice + if (!a.target_list.includes(game.selected)) + return false + } else { + // if strict order + if (find_target_of_counterattack(a) !== game.selected) + return false + } break + case "Absorb": // if attack target is listed on absorb action if (!a.target_list.includes(game.target)) diff --git a/tools/gendata.js b/tools/gendata.js index ff38695..b2405ec 100644 --- a/tools/gendata.js +++ b/tools/gendata.js @@ -327,6 +327,7 @@ function process_card(c, ix) { for (let a of c.actions) { if (a.target) { let tname = a.target.replace(" out of reserve", "") + if (tname === "Any enemy attack" || tname === "Any enemy formation" || tname === "Any enemy attacking it") a.target_list = find_enemy_cards(c.scenario, c.wing) else if (tname === "Any friendly formation") @@ -356,12 +357,21 @@ function process_card(c, ix) { else a.target_list = tname.split(/, | OR | or | and /).map(name => find_card(c.scenario, name)) - // Hothenfriedberg invisible charles last target in list! + // Hohenfriedberg invisible charles last target in list! if (c.number === "267A" || c.number === "268A" || c.number === "269A") a.target_list.push(find_card(c.scenario, "Charles")) } - if (a.type === "Absorb") + + if (a.type === "Counterattack") { + if (/, /.test(a.target)) + a.choice = 0 + else + a.choice = 1 + } + + if (a.type === "Absorb") { a.target_list = a.target_list.filter(x => x !== ix) // never absorb for self + } } if (c.rules) { for (let key in c.rules) { -- cgit v1.2.3