diff options
author | Tor Andersson <tor@ccxvii.net> | 2023-12-09 19:58:23 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2024-01-08 16:36:47 +0100 |
commit | 3d4909f946f724562d354a55a721ded43a12c268 (patch) | |
tree | 7e6659790356e7c021c51f85b9537f85a8d54d23 /rules.js | |
parent | c5f35f99aa9605a7baf43d6c407b126a51e878f8 (diff) | |
download | table-battles-3d4909f946f724562d354a55a721ded43a12c268.tar.gz |
Towton and Edgecote Moor. take_from, rout_with, and remove_with.
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 77 |
1 files changed, 70 insertions, 7 deletions
@@ -13,12 +13,12 @@ Special card rules implemented: suffer_1_less_1_max suffer_1_less start_with_no_cubes + take_from TODO: - remove_with rout_with + remove_with wild - take_from attack_reserve no_morale @@ -210,6 +210,9 @@ const S3201_DH_HILL = find_card(3201, "D.H. Hill") const S3201_AP_HILL = find_card(3201, "A.P. Hill") const S3201_LONGSTREET = find_card(3201, "Longstreet") +const S12_TOWTON = find_scenario(12) +const S13_EDGECOTE_MOOR = find_scenario(13) + // === SETUP === exports.setup = function (seed, scenario, options) { @@ -296,6 +299,13 @@ exports.setup = function (seed, scenario, options) { // === GAME STATE ACCESSORS === +function count_total_cubes() { + let n = game.morale[0] + game.morale[1] + for (let i = 1; i < game.cubes.length; i += 2) + n += game.cubes[i] + return n +} + function card_has_rule(c, name) { let rules = data.cards[c].rules if (rules) @@ -359,6 +369,14 @@ function remove_dice(c) { } } +function move_dice(from, to) { + for (let i = 0; i < 12; ++i) { + if (get_dice_location(i) === from) { + set_dice_location(i, to) + } + } +} + function eliminate_card(c) { remove_dice(c) remove_cubes(c, 3) @@ -647,10 +665,22 @@ function can_place_dice(c) { } // At cube limit? - if (data.cards[c].special) + if (data.cards[c].special) { + // Max on card if (map_get(game.cubes, c, 0) >= data.cards[c].special) return false + // Max available + let n_cubes = count_total_cubes() + if (n_cubes >= 10) + return false + + if (game.scenario === S12_TOWTON) { + if (n_cubes >= 8) + return false + } + } + // At per wing limit? let wing = data.cards[c].wing let n_wing = 0 @@ -1355,7 +1385,11 @@ states.bombard = { function goto_attack() { let a = current_action() - // TODO: 88B German Infantry - take dice from Saxon Infantry + let take_from = card_has_rule(game.selected, "take_from") + if (take_from) { + for (let from of take_from) + move_dice(from, game.selected) + } game.state = "attack" game.target = find_target_of_attack(a) @@ -1457,6 +1491,18 @@ states.command = { } } + if (game.scenario === S13_EDGECOTE_MOOR) { + // TODO: pay all 3 cubes? remove cards from play? + if (game.reserve[0].length === 0 && game.reserve[1].length > 0) { + log("Gained a second morale cube.") + game.morale[0] += 1 + } + if (game.reserve[1].length === 0 && game.reserve[0].length > 0) { + log("Gained a second morale cube.") + game.morale[1] += 1 + } + } + if (find_first_target_of_command(game.selected, current_action()) < 0) { pay_for_action(game.selected) end_action_phase() @@ -1742,6 +1788,7 @@ function get_attack_hits(c, a) { case "1 hit per die.": case "1 hit per die. 1 self per action.": case "1 hit per die. Ignore first target until it comes out of Reserve.": + case "1 hit per die (but see below). 1 self per action.": return count_dice_on_card(c) case "1 hit per pair.": case "1 hit per pair. 1 self per action.": @@ -1762,6 +1809,7 @@ function get_attack_self(c, a) { return 0 case "1 hit. 1 self per action.": case "1 hit per die. 1 self per action.": + case "1 hit per die (but see below). 1 self per action.": case "1 hit per pair. 1 self per action.": case "1 hit, PLUS 1 hit per die. 1 self per action.": return 1 @@ -1771,15 +1819,30 @@ function get_attack_self(c, a) { // === ROUTING === function should_remove_card(c) { - // TODO: remove after X routs special rules + let remove_with = card_has_rule(c, "remove_with") + if (remove_with) { + for (let other of remove_with) + if (is_card_in_play(other)) + return false + return true + } + return false } function should_rout_card(c) { - // TODO: rout after X routs special rules - if (!data.cards[c].special) + if (!data.cards[c].special) { if (map_get(game.sticks, c, 0) === 0) return true + + let rout_with = card_has_rule(c, "rout_with") + if (rout_with) { + for (let other of rout_with) + if (is_card_in_play(other)) + return false + return true + } + } return false } |