summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-12-14 13:16:07 +0100
committerTor Andersson <tor@ccxvii.net>2024-01-08 16:36:48 +0100
commit69d1cdece310f734d06bb2f99ebf393f836178f3 (patch)
treea431cc5075fea4cb1e26760ae8114b40c027502e
parenta3447a670f869ea2d4d8bca26fad526fa3e531c9 (diff)
downloadtable-battles-69d1cdece310f734d06bb2f99ebf393f836178f3.tar.gz
Blenheim.
-rw-r--r--play.html2
-rw-r--r--play.js1
-rw-r--r--rules.js133
3 files changed, 122 insertions, 14 deletions
diff --git a/play.html b/play.html
index 6f3d030..8442c9d 100644
--- a/play.html
+++ b/play.html
@@ -94,7 +94,7 @@ main {
[data-card="237A"] .slot_sticks { height: 55px; }
.slot_sticks {
- height: 87px;
+ min-height: 87px;
display: flex;
flex-direction: column;
justify-content: end;
diff --git a/play.js b/play.js
index 1d8488f..7deb683 100644
--- a/play.js
+++ b/play.js
@@ -381,6 +381,7 @@ function on_update() {
action_button("absorb", "Absorb")
action_button("roll", "Roll")
action_button("pass", "Pass")
+ action_button("next", "Next")
action_button("end_turn", "End turn")
action_button("undo", "Undo")
}
diff --git a/rules.js b/rules.js
index e6794c7..18612cf 100644
--- a/rules.js
+++ b/rules.js
@@ -300,6 +300,12 @@ const S40_CASSINES_II = find_card(40, "Cassines II")
const S40_MANNSFELDT = find_card(40, "Mannsfeldt")
const S40_GUTTENSTEIN = find_card(40, "Guttenstein")
+const S41_BLENHEIM_SCENARIO = find_scenario(41)
+const S41_CLERAMBAULT = find_card(41, "Clerambault")
+const S41_CUTTS_COLUMN = find_card(41, "Cutt's Column")
+const S41_BLENHEIM_CARD = find_card(41, "Blenheim")
+const S41_PRINCE_EUGENE = find_card(41, "Prince Eugene")
+
// === SETUP ===
exports.setup = function (seed, scenario, options) {
@@ -1363,6 +1369,8 @@ states.place_on_card = {
function end_roll_phase() {
push_undo()
+ game.selected = -1
+
// Remove placed dice to add cube on special cards.
for (let c of game.front[player_index()]) {
let s = data.cards[c].special
@@ -1379,10 +1387,12 @@ function end_roll_phase() {
set_player_dice_value(p, i, 0)
if (game.scenario === S26_PEACH_ORCHARD) {
- if (is_card_in_play(S26_FATAL_BLUNDER)) {
- if (!placed_any_dice_on_wing(PINK)) {
- game.state = "s26_fatal_blunder"
- return
+ if (player_index() === 0) {
+ if (is_card_in_play(S26_FATAL_BLUNDER)) {
+ if (!placed_any_dice_on_wing(PINK)) {
+ game.state = "s26_fatal_blunder"
+ return
+ }
}
}
}
@@ -1392,6 +1402,17 @@ function end_roll_phase() {
return goto_game_over(P2, "Geary's Division arrived.")
}
+ if (game.scenario === S41_BLENHEIM_SCENARIO) {
+ if (player_index() === 1) {
+ if (is_card_in_play(S41_CLERAMBAULT)) {
+ if (!placed_any_dice_on_wing(DKBLUE)) {
+ game.state = "s41_clerambault"
+ return
+ }
+ }
+ }
+ }
+
end_turn()
}
@@ -1430,6 +1451,29 @@ states.s26_fatal_blunder = {
}
}
+states.s41_clerambault = {
+ prompt() {
+ view.prompt = "Rout Clerambault and add his sticks to Blenheim!"
+ if (is_card_in_play(S41_BLENHEIM_CARD) && get_sticks(S41_CLERAMBAULT)) {
+ view.selected = S41_CLERAMBAULT
+ gen_action_card(S41_BLENHEIM_CARD)
+ } else {
+ gen_action_card(S41_CLERAMBAULT)
+ }
+ },
+ card(c) {
+ if (c === S41_BLENHEIM_CARD)
+ set_sticks(S41_BLENHEIM_CARD, get_sticks(S41_BLENHEIM_CARD) + get_sticks(S41_CLERAMBAULT))
+ set_sticks(S41_CLERAMBAULT, 0)
+ if (c === S41_CLERAMBAULT) {
+ rout_card(S41_CLERAMBAULT)
+ game.morale[0]++
+ game.morale[1]--
+ end_turn()
+ }
+ },
+}
+
function end_turn() {
clear_undo()
@@ -1521,6 +1565,8 @@ function check_cube_requirement(c, req) {
switch (req) {
case "3 cubes":
return get_cubes(c) >= 3
+ case "Two Cubes":
+ return get_cubes(c) >= 2
case "Voluntary":
case undefined:
return get_cubes(c) >= 1
@@ -1622,7 +1668,7 @@ function can_take_action(c, a, ix) {
}
function s40_can_take_cassines_action(c, a, b) {
- return (player_index() === 1) && (get_sticks(c) < 3) && (is_card_in_play(a) || is_card_in_play(b))
+ return (get_sticks(c) < 3) && (is_card_in_play(a) || is_card_in_play(b))
}
function can_take_any_action() {
@@ -1637,10 +1683,19 @@ function can_take_any_action() {
}
if (game.scenario === S40_CHIARI) {
- if (s40_can_take_cassines_action(S40_CASSINES_I, S40_NIGRELLI, S40_KRIECHBAUM))
- return true
- if (s40_can_take_cassines_action(S40_CASSINES_II, S40_MANNSFELDT, S40_GUTTENSTEIN))
- return true
+ if (player_index() === 1) {
+ if (s40_can_take_cassines_action(S40_CASSINES_I, S40_NIGRELLI, S40_KRIECHBAUM))
+ return true
+ if (s40_can_take_cassines_action(S40_CASSINES_II, S40_MANNSFELDT, S40_GUTTENSTEIN))
+ return true
+ }
+ }
+
+ if (game.scenario === S41_BLENHEIM_SCENARIO) {
+ if (player_index() === 0) {
+ if (has_any_dice_on_card(S41_PRINCE_EUGENE))
+ return true
+ }
}
return false
@@ -1752,10 +1807,19 @@ states.action = {
}
if (game.scenario === S40_CHIARI) {
- if (s40_can_take_cassines_action(S40_CASSINES_I, S40_NIGRELLI, S40_KRIECHBAUM))
- gen_action_card(S40_CASSINES_I)
- if (s40_can_take_cassines_action(S40_CASSINES_II, S40_MANNSFELDT, S40_GUTTENSTEIN))
- gen_action_card(S40_CASSINES_II)
+ if (player_index() === 1) {
+ if (s40_can_take_cassines_action(S40_CASSINES_I, S40_NIGRELLI, S40_KRIECHBAUM))
+ gen_action_card(S40_CASSINES_I)
+ if (s40_can_take_cassines_action(S40_CASSINES_II, S40_MANNSFELDT, S40_GUTTENSTEIN))
+ gen_action_card(S40_CASSINES_II)
+ }
+ }
+
+ if (game.scenario === S41_BLENHEIM_SCENARIO) {
+ if (player_index() === 0) {
+ if (has_any_dice_on_card(S41_PRINCE_EUGENE))
+ gen_action_card(S41_PRINCE_EUGENE)
+ }
}
},
retire(c) {
@@ -1790,6 +1854,12 @@ states.action = {
game.selected = c
game.state = "s40_cassines"
}
+ if (game.scenario === S41_BLENHEIM_SCENARIO) {
+ game.selected = S41_PRINCE_EUGENE
+ game.target2 = -1
+ game.self = Math.min(get_sticks(S41_PRINCE_EUGENE), count_dice_on_card(S41_PRINCE_EUGENE))
+ game.state = "s41_prince_eugene"
+ }
}
}
@@ -1817,6 +1887,35 @@ states.s40_cassines = {
},
}
+states.s41_prince_eugene = {
+ prompt() {
+ if (game.target2 < 0) {
+ view.prompt = `Prince Eugene: Move up to ${game.self} unit sticks to any Red card.`
+ for (let c of game.front[0])
+ if (data.cards[c].wing === RED && !data.cards[c].special)
+ gen_action_card(c)
+ } else {
+ view.prompt = `Prince Eugene: Move up to ${game.self} unit sticks to ${card_name(game.target2)}.`
+ gen_action_card(game.target2)
+ view.actions.next = 1
+ }
+ },
+ card(c) {
+ game.target2 = c
+ log(game.target2 + " moved one stick from " + game.selected)
+ set_sticks(game.selected, get_sticks(game.selected) - 1)
+ set_sticks(game.target2, get_sticks(game.target2) + 1)
+ if (--game.self === 0) {
+ pay_for_action(game.selected)
+ end_action_phase()
+ }
+ },
+ next() {
+ pay_for_action(game.selected)
+ end_action_phase()
+ },
+}
+
function goto_null(c) {
log("Fizzled " + card_number(c))
pay_for_action(c)
@@ -2036,6 +2135,12 @@ function update_attack1() {
}
}
+ if (game.scenario === S41_BLENHEIM_SCENARIO) {
+ // TODO: Original attack only, or also when Blenheim absorbs from Clerambault?
+ if (game.selected === S41_CUTTS_COLUMN && game.target === S41_BLENHEIM_CARD)
+ game.hits *= 2
+ }
+
let extra = card_has_rule(game.selected, "extra_hit_if_dice_on")
if (extra && has_any_dice_on_card(extra[0]))
game.hits += 1
@@ -2595,6 +2700,7 @@ function get_attack_hits(c, a) {
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 (2 hits per die vs. Blenheim). 1 self per action.":
case "1 hit per die. 1 self per action. You CHOOSE the target.":
return count_dice_on_card(c)
case "1 hit per pair.":
@@ -2639,6 +2745,7 @@ function get_attack_self(c, a) {
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 (2 hits per die vs. Blenheim). 1 self per action.":
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.":