diff options
author | Tor Andersson <tor@ccxvii.net> | 2023-12-15 19:18:24 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2024-01-08 16:36:48 +0100 |
commit | 049d7c8c00af98151f1b35d5481c9116d969f569 (patch) | |
tree | 3ffa6f53999b7d5ce4554c0b64bbe4b74547b85f | |
parent | 10a85af52ed7f94d65729d5c7a9a9473582cf328 (diff) | |
download | table-battles-049d7c8c00af98151f1b35d5481c9116d969f569.tar.gz |
Fleurus.
-rw-r--r-- | cards.css | 4 | ||||
-rw-r--r-- | play.html | 9 | ||||
-rw-r--r-- | play.js | 11 | ||||
-rw-r--r-- | rules.js | 101 |
4 files changed, 98 insertions, 27 deletions
@@ -239,7 +239,7 @@ line-height: 12px; bottom: 0px; right: 0px; - padding: 6px 8px; + padding: 7px 8px; } .extra { @@ -249,7 +249,7 @@ line-height: 12px; bottom: 0px; left: 0px; - padding: 6px 8px; + padding: 7px 8px; } /* SCENARIO CARD */ @@ -125,12 +125,9 @@ main { align-items: start; } -/* S37 Inkerman - The Fog */ -[data-card="225B"] .slot_sticks { display: none } - -/* S?? XXX - Retreat to Nivelles */ -[data-card="237A"] .slot_dice { height: 32px; } -[data-card="237A"] .slot_sticks { height: 55px; } +/* S38 Fleurus - Retreat to Nivelles */ +[data-card="237A"] .slot_cubes:empty { display: none } +[data-card="237A"] .slot_cubes:not(:empty) ~ .slot_sticks { display: none } .slot_sticks { margin: 12px; @@ -133,10 +133,15 @@ function create_formation_slot(id, top) { e.appendChild(ui.cards[id]) } - if (card.special || card.name === "The Fog" || card.name === "Retreat to Nivelles") + if (card.name === "Retreat to Nivelles") { ui.slot_cubes[id] = append_div(e, "slot_cubes") - if (!card.special) ui.slot_sticks[id] = append_div(e, "slot_sticks") + } else { + if (card.special) + ui.slot_cubes[id] = append_div(e, "slot_cubes") + else + ui.slot_sticks[id] = append_div(e, "slot_sticks") + } if (!top) { e.appendChild(ui.cards[id]) @@ -177,6 +182,8 @@ function create_formation_card(id) { append_div(e, "strength", "IV") else if (card.special === 5) append_div(e, "strength", "V") + else if (card.special === -1) + append_div(e, "strength", "?") else append_div(e, "strength", card.strength) @@ -144,9 +144,8 @@ function goto_game_over(result, victory) { game.state = "game_over" game.active = "None" game.result = result - game.victory = result + " victory! " + victory + game.victory = victory log("") - log(result + " victory!") log(victory) return true } @@ -264,6 +263,7 @@ const S35_MONTROSE = find_card(35, "Montrose") const S35_GORDON = find_card(35, "Gordon") const S38_FLEURUS = find_scenario(38) +const S38_WALDECK = find_card(38, "Waldeck") const S38_RETREAT_TO_NIVELLES = find_card(38, "Retreat to Nivelles") const S38_LUXEMBOURGS_HORSE = find_card(38, "Luxembourg's Horse") const S38_GOURNAYS_HORSE = find_card(38, "Gournay's Horse") @@ -424,7 +424,10 @@ exports.setup = function (seed, scenario, options) { log("") if (info.players[0].tactical > 0 || info.players[1].tactical > 0) { - log("Tactical Victory:") + if (game.scenario === S38_FLEURUS) + log("Tactical Draw:") + else + log("Tactical Victory:") if (info.players[0].tactical > 0) log(">" + player_name(0) + ": " + info.players[0].tactical) if (info.players[1].tactical > 0) @@ -448,6 +451,10 @@ exports.setup = function (seed, scenario, options) { map_set(game.cubes, S37_THE_FOG, 3) } + if (game.scenario === S38_FLEURUS) { + map_set(game.cubes, S38_RETREAT_TO_NIVELLES, 3) + } + goto_start_turn() return game @@ -527,7 +534,7 @@ function set_sticks(c, n) { } function move_sticks(from, to, n) { - log("moved N sticks") + log(`Moved ${n} sticks from C${from} to C${to}.`) // TODO? set_sticks(from, get_sticks(from) - n) set_sticks(to, get_sticks(to) + n) } @@ -770,6 +777,11 @@ function check_impossible_to_attack_victory() { function get_tactical_victory_points(p) { let n = game.lost[1-p] + if (game.scenario === S38_FLEURUS) { + if (p === 1) + n += get_sticks(S38_RETREAT_TO_NIVELLES) + } + if (game.scenario === S46_ROCOUX) { if (p === 0) n += get_sticks(S46_AUSTRIANS) @@ -800,22 +812,27 @@ function check_victory() { if (game.scenario === S49_LEUTHEN) { if (is_removed_from_play(S49_NADASDY) && is_card_in_reserve(S49_COLLOREDO)) - return goto_game_over(P1, "Nadasdy routed before Colloredo entered play.") + return goto_game_over(P1, "Nadasdy routed before Colloredo entered play!") } if (game.morale[0] === 0) - return goto_game_over(P2, player_name(0) + " has run out of morale!") + return goto_game_over(P2, player_name(0) + " ran out of morale!") if (game.morale[1] === 0) - return goto_game_over(P1, player_name(1) + " has run out of morale!") + return goto_game_over(P1, player_name(1) + " ran out of morale!") let tv0 = get_tactical_victory_points(0) let tv1 = get_tactical_victory_points(1) + if (game.scenario === S38_FLEURUS) { + if (tv1 >= 22) + return goto_game_over("Draw", player_name(1) + " secured a draw!") + } + if (info.players[0].tactical > 0 && tv0 >= info.players[0].tactical) - return goto_game_over(P1, player_name(0) + " tactical victory!") + return goto_game_over(P1, player_name(0) + " won a tactical victory!") if (info.players[1].tactical > 0 && tv1 >= info.players[1].tactical) - return goto_game_over(P2, player_name(1) + " tactical victory!") + return goto_game_over(P2, player_name(1) + " won a tactical victory!") return false } @@ -2012,7 +2029,7 @@ function goto_start_turn() { if (is_infantry(c) || is_cavalry(c)) have_inf_or_cav = true if (!have_inf_or_cav) - return goto_game_over(P1, "Frederick has no Infantry or Cavalry in play!") + return goto_game_over(P1, "Frederick had no Infantry or Cavalry in play!") } } @@ -2117,7 +2134,6 @@ states.action = { }, retire(c) { push_undo() - retire_card(c) if (game.scenario === S38_FLEURUS) { if (c === S38_LUXEMBOURGS_HORSE) { @@ -2126,6 +2142,7 @@ states.action = { } } + retire_card(c) end_action_phase() }, a1(c) { @@ -2390,6 +2407,11 @@ function find_first_target_of_command(c, a) { return S37_THE_FOG } + if (game.scenario === S38_FLEURUS) { + if (c === S38_WALDECK) + return S38_RETREAT_TO_NIVELLES + } + if (game.scenario === S44_HOHENFRIEDBERG) { if (c === S44_CHARLES) { if (game.reserve[1].length > 0) @@ -2782,6 +2804,18 @@ function goto_command() { return } + if (game.scenario === S38_FLEURUS && game.selected === S38_WALDECK) { + remove_cubes(S38_RETREAT_TO_NIVELLES, 3) + remove_dice(game.selected) + if (1 || !has_any_cubes_on_card(S38_RETREAT_TO_NIVELLES)) { + game.selected = S38_RETREAT_TO_NIVELLES + game.state = "s38_retreat_to_nivelles_1" + return + } + end_action_phase() + return + } + game.state = "command" } @@ -2842,6 +2876,35 @@ states.command = { }, } +states.s38_retreat_to_nivelles_1 = { + prompt() { + view.prompt = "Retreat to Nivelles: Remove all in-play Grand Alliance cards!" + for (let c of game.front[1]) + if (c !== S38_RETREAT_TO_NIVELLES) + gen_action_card(c) + }, + card(c) { + move_all_sticks(c, S38_RETREAT_TO_NIVELLES) + remove_card(c) + if (game.front[1].length === 1) + game.state = "s38_retreat_to_nivelles_2" + }, +} + +states.s38_retreat_to_nivelles_2 = { + prompt() { + view.prompt = "Retreat to Nivelles: Bring van Aylva & van Weibnom out of reserve." + for (let c of game.reserve[1]) + gen_action_card(c) + }, + card(c) { + bring_out_of_reserve(c) + if (game.reserve[1].length === 0) + end_action_phase() + }, +} + + // === REACTION === function can_opponent_react() { @@ -3470,12 +3533,12 @@ function end_routing() { if (game.routed[0]) { game.morale[0] -= Math.min(game.routed[0], game.morale[0]) if (game.morale[0] === 0) - return goto_game_over(P2, player_name(0) + " has run out of morale!") + return goto_game_over(P2, player_name(0) + " ran out of morale!") } if (game.routed[1]) { game.morale[1] -= Math.min(game.routed[1], game.morale[1]) if (game.morale[1] === 0) - return goto_game_over(P1, player_name(1) + " has run out of morale!") + return goto_game_over(P1, player_name(1) + " ran out of morale!") } } @@ -3529,6 +3592,13 @@ function end_reserve() { goto_roll_phase() } +function bring_out_of_reserve(c) { + log(card_name(c) + " came out of reserve.") + let p = find_card_owner(c) + set_delete(game.reserve[p], c) + set_add(game.front[p], c) +} + states.reserve = { prompt() { view.prompt = "Enter reserves!" @@ -3538,10 +3608,7 @@ states.reserve = { gen_action_card(c) }, card(c) { - log(card_name(c) + " came out of reserve.") - let p = find_card_owner(c) - set_delete(game.reserve[p], c) - set_add(game.front[p], c) + bring_out_of_reserve(c) resume_reserve() }, } |