diff options
author | Tor Andersson <tor@ccxvii.net> | 2023-12-14 12:11:28 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2024-01-08 16:36:48 +0100 |
commit | 000d7493517e569b9ebe5cb493c3541eef9589f4 (patch) | |
tree | 51ab43e0a3751f96cc438d7d125478884b489a23 /rules.js | |
parent | fa11ea4c8dd0c423ad1e86ba0f6a7dd31a35c9af (diff) | |
download | table-battles-000d7493517e569b9ebe5cb493c3541eef9589f4.tar.gz |
Links & Marsaglia.
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 83 |
1 files changed, 76 insertions, 7 deletions
@@ -284,6 +284,12 @@ const S35_AULDEARN = find_scenario(35) const S35_MONTROSE = find_card(35, "Montrose") const S35_GORDON = find_card(35, "Gordon") +const S39_MARSAGLIA = find_scenario(39) +const S39_EUGENE = find_card(39, "Eugene") +const S39_CANNONS = find_card(39, "Cannons") +const S39_BAYONETS = find_card(39, "Bayonets!") +const S39_CATINAT = find_card(39, "Catinat") + // === SETUP === exports.setup = function (seed, scenario, options) { @@ -466,15 +472,20 @@ function remove_dice(c) { } } -function move_dice(from, to) { +function take_all_dice(from, to) { + log("Take dice from " + from + " to " + to + ".") for (let i = 0; i < 12; ++i) { if (get_dice_location(i) === from) { set_dice_location(i, to) + if (to === POOL) + set_dice_value(i, 0) + to = POOL } } } function take_one_die(from, to) { + log("One die from " + from + " to " + to + ".") for (let i = 0; i < 12; ++i) { if (get_dice_location(i) === from) { set_dice_location(i, to) @@ -486,6 +497,7 @@ function take_one_die(from, to) { } function take_wild_die(from, to) { + log("Wild die from " + from + " to " + to + ".") for (let i = 0; i < 12; ++i) { if (get_dice_location(i) === from) { set_dice_location(i, to) @@ -594,6 +606,16 @@ function is_removed_from_play(c) { return !is_card_in_play_or_reserve(c) } +function card_has_active_link(c) { + let link = data.cards[c].link + if (link) { + for (let t of link) + if (is_card_in_play(t)) + return true + } + return false +} + function card_has_attack_with_valid_target(c) { for (let a of data.cards[c].actions) { if (a.type === "Attack") { @@ -1852,7 +1874,7 @@ function goto_attack(target) { if (take_from) { for (let from of take_from) if (has_any_dice_on_card(from)) - move_dice(from, game.selected) + take_all_dice(from, game.selected) } let take_1_from = card_has_rule(game.selected, "take_1_from") @@ -1934,6 +1956,17 @@ function update_attack1() { } } + if (game.scenario === S39_MARSAGLIA) { + if (game.selected === S39_EUGENE) { + if (has_any_dice_on_card(S39_CANNONS)) { + game.self = 0 + } + } + if (game.selected === S39_CATINAT && game.target2 === S39_BAYONETS) { + game.self = 0 + } + } + let extra = card_has_rule(game.selected, "extra_hit_if_dice_on") if (extra && has_any_dice_on_card(extra[0])) game.hits += 1 @@ -1942,6 +1975,9 @@ function update_attack1() { game.hits = clamp(game.hits - 1, 0, 1) if (card_has_rule(game.target, "suffer_1_less")) game.hits = Math.max(0, game.hits - 1) + + if (card_has_active_link(game.target)) + game.hits = Math.max(0, game.hits - 1) } // Update hits and self hits for defensive abilities that redirect or steal hits. @@ -1985,6 +2021,12 @@ states.attack = { gen_action_dice_on_card(from) } + if (game.scenario === S39_MARSAGLIA) { + if (game.selected === S39_CATINAT) { + gen_action_dice_on_card(S39_BAYONETS) + } + } + view.actions.attack = 1 }, attack() { @@ -2001,24 +2043,42 @@ states.attack = { this.attack() }, die(d) { + let from = get_dice_location(d) + let w = side_get_wild_die_card(player_index()) - if (w === get_dice_location(d)) { - log("Wild die from C" + w + ".") + if (w === from) { take_wild_die(w, game.selected) + return } + let may_take_from = card_has_rule(game.selected, "may_take_from") if (may_take_from) { - move_dice(get_dice_location(d), game.selected) + take_all_dice(from, game.selected) update_attack1() update_attack2() + return } + let may_take_from_extra = card_has_rule(game.selected, "may_take_from_extra_self") if (may_take_from_extra) { - move_dice(get_dice_location(d), game.selected) + take_all_dice(from, game.selected) game.self2 = 1 update_attack1() update_attack2() + return } + + if (game.scenario === S39_MARSAGLIA) { + if (game.selected === S39_CATINAT && from === S39_BAYONETS) { + take_all_dice(from, game.selected) + game.target2 = S39_BAYONETS + update_attack1() + update_attack2() + return + } + } + + throw new Error("no handler for taking dice from other card") } } @@ -2099,6 +2159,12 @@ states.command = { // === REACTION === function can_opponent_react() { + + if (game.scenario === S39_MARSAGLIA) { + if (game.selected === S39_CATINAT && game.target2 === S39_BAYONETS) + return false + } + let p = 1 - player_index() let wild = side_has_wild_die(p) for (let c of game.front[p]) @@ -2183,7 +2249,6 @@ function take_wild_die_if_needed_for_reaction(c, ix) { if (w >= 0) { let a = data.cards[c].actions[ix] if (!can_take_reaction(c, a, false)) { - log("Wild die from C" + w + ".") take_wild_die(w, c) } } @@ -2459,6 +2524,8 @@ function get_attack_hits(c, a) { case "1 hit per die (also take dice from 68th Pennsylvania). 1 self per action.": case "1 hit per die. 1 self per action. (But see William Fielding.)": case "1 hit per die (1 extra vs Essex). 1 self per action. (See W. Fielding.)": + case "1 hit per die. 1 self per action (but see Cannons).": + case "1 hit per die. 1 self per action (but see Bayonets!).": case "1 hit per die. 1 self per action. You CHOOSE the target.": return count_dice_on_card(c) case "1 hit per pair.": @@ -2501,6 +2568,8 @@ function get_attack_self(c, a) { case "1 hit per die (also take dice from 68th Pennsylvania). 1 self per action.": case "1 hit per die. 1 self per action. (But see William Fielding.)": case "1 hit per die (1 extra vs Essex). 1 self per action. (See W. Fielding.)": + case "1 hit per die. 1 self per action (but see Cannons).": + case "1 hit per die. 1 self per action (but see Bayonets!).": case "1 hit per die. 1 self per action. You CHOOSE the target.": case "1 hit per pair. 1 self per action.": case "1 hit, PLUS 1 hit per die. 1 self per action.": |