summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--images/shield.svg1
-rw-r--r--play.css6
-rw-r--r--play.html30
-rw-r--r--play.js25
-rw-r--r--rules.ts562
5 files changed, 305 insertions, 319 deletions
diff --git a/images/shield.svg b/images/shield.svg
new file mode 100644
index 0000000..52362c1
--- /dev/null
+++ b/images/shield.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="512px" width="512px" viewBox="0 0 512 512"><path d="M259.303 23.195C191.17 23.188 122.745 33.57 54.896 54.732l-6.12 2.825-.303 6.52c0 95.313 9.696 178.568 40.297 249.96s82.32 130.185 165.277 174.62l4.672 2.337 4.087-2.336C343.87 445.236 396.29 386.753 427.5 315.205c31.21-71.547 41.465-155.484 41.465-251.13V57.07l-6.424-2.336c-67.16-21.138-135.104-31.53-203.237-31.537z"/></svg>
diff --git a/play.css b/play.css
index 21a5cd3..f63868a 100644
--- a/play.css
+++ b/play.css
@@ -7,8 +7,8 @@ body.Lancaster header.your_turn { background-color: hsl(355, 83%, 72%); }
#turn_info { background-color: gray; }
.panel_header { background-color: hsl(34, 10%, 30%); }
-body.York #event_header, body.York #plan_header, .court_panel.york .panel_header { background-color: hsl(217, 15%, 33%); }
-body.Lancaster #event_header, body.Lancaster #plan_header, .court_panel.lancaster .panel_header { background-color: hsl(355, 15%, 33%); }
+body.York #event_header, body.York #hand_header, body.York #plan_header, .court_panel.york .panel_header { background-color: hsl(217, 15%, 33%); }
+body.Lancaster #event_header, body.Lancaster #hand_header, body.Lancaster #plan_header, .court_panel.lancaster .panel_header { background-color: hsl(355, 15%, 33%); }
/* LOG */
@@ -330,7 +330,7 @@ body.Lancaster #plan_actions .york { display: none }
gap: 4px;
}
-#pieces .marker {
+#map .marker {
position: absolute;
}
diff --git a/play.html b/play.html
index b330ad0..a555324 100644
--- a/play.html
+++ b/play.html
@@ -32,6 +32,7 @@
<li class="debug separator">
</menu>
</details>
+ <button onclick="toggle_seats()"><img src="images/shield.svg"></button>
<button onclick="toggle_pieces()"><img src="/images/earth-africa-europe.svg"></button>
</div>
</header>
@@ -62,19 +63,21 @@
<div id="map">
<div id="locales"></div>
-<div id="boxes"></div>
+
+<div id="seats"></div>
<div id="pieces">
- <div id="turn" class="marker circle turn levy"></div>
- <div id="end" class="marker circle end"></div>
- <div id="victory_check" class="marker square victory_check"></div>
- <div id="towns" class="marker square towns"></div>
- <div id="cities" class="marker square cities"></div>
- <div id="fortresses" class="marker square fortresses"></div>
- <div id="ip" class="marker square ip"></div>
<div id="battle" class="hide" style="z-index:50"></div>
</div>
+<div id="turn" class="marker circle turn levy"></div>
+<div id="end" class="marker circle end"></div>
+<div id="victory_check" class="marker square victory_check"></div>
+<div id="towns" class="marker square towns"></div>
+<div id="cities" class="marker square cities"></div>
+<div id="fortresses" class="marker square fortresses"></div>
+<div id="ip" class="marker square ip"></div>
+
</div>
</div>
@@ -102,16 +105,6 @@
</div>
</div>
-<div id="reserves_panel" class="panel hide">
-<div id="reserves_header" class="panel_header">Reserves</div>
-<div id="reserves" class="panel_body court_body"></div>
-</div>
-
-<div id="routed_panel" class="panel hide">
-<div id="routed_header" class="panel_header">Routed / Fled</div>
-<div id="routed" class="panel_body court_body"></div>
-</div>
-
<div id="arts_of_war_panel" class="panel hide">
<div id="arts_of_war_header" class="panel_header">Arts of War</div>
<div id="arts_of_war" class="panel_body"></div>
@@ -229,7 +222,6 @@
<div data-card="L36" class="card aow lancaster c72"><div class="event"><div class="title">Talbot to the Rescue</div><div class="text"><b>Hold:</b> Play upon Death check to Disband any Routed Lancastrians instead of rolling for Death.</div></div><div class="capability sh3"><div class="title">Chevaliers</div><div class="subtitle">French knights</div><div class="text">This Lord’s Men-at-Arms suffer -1 Armour against Missiles but Melee Strike x2.</div></div><div class="number">L36</div></div>
<div data-card="L37" class="card aow lancaster c73"><div class="event"><div class="title">The Earl of Richmond</div><div class="subtitle">is with a mighty power landed at Milford</div><div class="text"><b>This Levy</b><br>Lancastrian Vassal Levy always succeeds.</div></div><div class="capability sh3"><div class="title">Madame La Grande</div><div class="subtitle">Louis XI's daughter Anne finances Tudors</div><div class="text">Each Pay segment (3.2) that this Lord at or adjacent to a Friendly English Channel Port, he receives 1 Coin.</div></div><div class="number">L37</div></div>
-
<!-- END CARD DATA -->
</div>
diff --git a/play.js b/play.js
index 96f3ab0..2f1f71e 100644
--- a/play.js
+++ b/play.js
@@ -6,6 +6,10 @@ function toggle_pieces() {
document.getElementById("pieces").classList.toggle("hide")
}
+function toggle_seats() {
+ document.getElementById("seats").classList.toggle("hide")
+}
+
// === CONSTANTS (matching those in rules.js) ===
function find_lord(name) { return data.lords.findIndex((x) => x.name === name) }
@@ -366,7 +370,6 @@ const ui = {
cards: [],
cards2: [],
lords2: [],
- calendar: [],
seat: [],
plan_panel: document.getElementById("plan_panel"),
@@ -600,7 +603,7 @@ function build_map() {
//e.style.transform = "rotate(315deg)"
e.style.zIndex = "-50"
register_tooltip(e, data.lords[ix].short_name)
- document.getElementById("pieces").appendChild(e)
+ document.getElementById("seats").appendChild(e)
})
data.lords.forEach((lord, ix) => {
@@ -653,22 +656,8 @@ function build_map() {
register_tooltip(e, data.vassals[ix].name)
})
- for (let i = 1; i <= 16; ++i) {
- let name = "box" + i
- let x = calendar_boxes[name][0]
- let y = calendar_boxes[name][1]
- let w = calendar_boxes[name][2]
- let h = calendar_boxes[name][3]
- calendar_xy[i] = [ x, y, w, h ]
-
- let e = ui.calendar[i] = document.createElement("div")
- e.className = "calendar box " + name
- e.style.left = x + "px"
- e.style.top = y + "px"
- e.style.width = w + "px"
- e.style.height = h + "px"
- document.getElementById("boxes").appendChild(e)
- }
+ for (let i = 1; i <= 16; ++i)
+ calendar_xy[i] = calendar_boxes["box" + i]
for (let i = 0; i <= 45; ++i) {
let name = "track" + i
diff --git a/rules.ts b/rules.ts
index 91d5a5c..51b1434 100644
--- a/rules.ts
+++ b/rules.ts
@@ -4287,6 +4287,7 @@ function end_sail() {
// Disbanded in battle!
if (!is_lord_on_map(game.command)) {
+ game.group = null
clear_flag(FLAG_MARCH_TO_PORT)
clear_flag(FLAG_SAIL_TO_PORT)
spend_all_actions()
@@ -4977,6 +4978,7 @@ function end_march() {
// Disbanded in battle!
if (!is_lord_on_map(game.command)) {
+ game.group = null
clear_flag(FLAG_MARCH_TO_PORT)
clear_flag(FLAG_SAIL_TO_PORT)
spend_all_actions()
@@ -6245,123 +6247,6 @@ states.ravine = {
},
}
-// === BATTLE EVENT: REGROUP ===
-
-function is_regroup_in_play() {
- if (is_event_in_play(EVENT_YORK_REGROUP)) {
- for (let p of battle_strike_positions) {
- let lord = game.battle.array[p]
- if (is_york_lord(lord) && lord_has_routed_troops(lord) && get_lord_forces(lord, RETINUE))
- return true
- }
- }
- return false
-}
-
-function goto_regroup() {
- set_active(YORK)
- game.state = "regroup"
-}
-
-states.regroup = {
- prompt() {
- for (let p of battle_strike_positions) {
- let lord = game.battle.array[p]
- if (is_york_lord(lord) && lord_has_routed_troops(lord) && get_lord_forces(lord, RETINUE))
- gen_action_lord(lord)
- }
- if (game.battle.step >= 2) {
- view.prompt = "Regroup: You may choose a lord to regroup."
- view.actions.pass = 1
- } else {
- view.prompt = "Regroup: Choose a lord to regroup."
- }
- },
- lord(lord) {
- push_undo()
- logevent(EVENT_YORK_REGROUP)
- logi("L" + lord)
- game.who = lord
- game.state = "regroup_roll_protection"
- game.event_regroup = [
- 0,
- 0,
- get_lord_routed_forces(lord, MEN_AT_ARMS),
- get_lord_routed_forces(lord, LONGBOWMEN),
- get_lord_routed_forces(lord, MILITIA),
- get_lord_routed_forces(lord, BURGUNDIANS),
- get_lord_routed_forces(lord, MERCENARIES),
- ]
- },
- pass() {
- goto_battle_lord_rout()
- },
-}
-
-states.regroup_roll_protection = {
- prompt() {
- view.prompt = "Regroup: Roll each routed troop's protection for them to recover."
- if (game.event_regroup[MEN_AT_ARMS] > 0)
- gen_action_routed_men_at_arms(game.who)
- if (game.event_regroup[LONGBOWMEN] > 0)
- gen_action_routed_longbowmen(game.who)
- if (game.event_regroup[MILITIA] > 0)
- gen_action_routed_militia(game.who)
- if (game.event_regroup[BURGUNDIANS] > 0)
- gen_action_routed_burgundians(game.who)
- if (game.event_regroup[MERCENARIES] > 0)
- gen_action_routed_mercenaries(game.who)
- },
- routed_burgundians(lord) {
- action_regroup(lord, BURGUNDIANS)
- },
- routed_mercenaries(lord) {
- action_regroup(lord, MERCENARIES)
- },
- routed_longbowmen(lord) {
- action_regroup(lord, LONGBOWMEN)
- },
- routed_men_at_arms(lord) {
- action_regroup(lord, MEN_AT_ARMS)
- },
- routed_militia(lord) {
- action_regroup(lord, MILITIA)
- },
-}
-
-function action_regroup(lord: Lord, type: Force) {
- let protection = get_modified_protection(lord, type)
-
- let die = roll_die()
- if (die <= protection) {
- logi(`${get_force_name(lord, type)} ${range(protection)}: W${die}`)
- add_lord_routed_forces(lord, type, -1)
- add_lord_forces(lord, type, 1)
- } else {
- logi(`${get_force_name(lord, type)} ${range(protection)}: B${die}`)
- }
-
- game.event_regroup[type]--
-
- for (let i = 2; i < 7; ++i)
- if (game.event_regroup[i] > 0)
- return
- end_regroup()
-}
-
-function end_regroup() {
- // remove event from play once used
- set_delete(game.events, EVENT_YORK_REGROUP)
-
- game.who = NOBODY
- delete game.event_regroup
-
- if (game.battle.step < 2)
- game.state = "assign_hits"
- else
- goto_battle_lord_rout()
-}
-
// === BATTLE EVENT: CALTROPS ===
states.caltrops = {
@@ -6582,48 +6467,160 @@ function is_leeward_battle_line_in_play(lord: Lord) {
return false
}
-// === BATTLE EVENT: SWIFT MANEUVER ===
+// === BATTLE EVENT: REGROUP ===
-states.swift_maneuver_1 = {
- get inactive() {
- view.engaged = game.battle.engagements[0]
- return format_strike_step()
- },
+function is_regroup_in_play() {
+ if (is_event_in_play(EVENT_YORK_REGROUP)) {
+ for (let p of battle_strike_positions) {
+ let lord = game.battle.array[p]
+ if (is_york_lord(lord) && lord_has_routed_troops(lord) && get_lord_forces(lord, RETINUE))
+ return true
+ }
+ }
+ return false
+}
+
+function goto_regroup() {
+ set_active(YORK)
+ game.state = "regroup"
+}
+
+states.regroup = {
prompt() {
- view.prompt = "Swift Maneuver: Reroll routed retinue?"
- view.actions.pass = 1
- gen_action_routed_retinue(game.who)
+ for (let p of battle_strike_positions) {
+ let lord = game.battle.array[p]
+ if (is_york_lord(lord) && lord_has_routed_troops(lord) && get_lord_forces(lord, RETINUE))
+ gen_action_lord(lord)
+ }
+ if (game.battle.step >= 2) {
+ view.prompt = "Regroup: You may choose a lord to regroup."
+ view.actions.pass = 1
+ } else {
+ view.prompt = "Regroup: Choose a lord to regroup."
+ }
},
- routed_retinue(lord) {
- action_spend_valour(lord, RETINUE)
- if (lord_has_routed_retinue(lord))
- this.pass()
- else
- finish_action_assign_hits()
+ lord(lord) {
+ push_undo()
+ logevent(EVENT_YORK_REGROUP)
+ logi("L" + lord)
+ game.who = lord
+ game.state = "regroup_roll_protection"
+ game.event_regroup = [
+ 0,
+ 0,
+ get_lord_routed_forces(lord, MEN_AT_ARMS),
+ get_lord_routed_forces(lord, LONGBOWMEN),
+ get_lord_routed_forces(lord, MILITIA),
+ get_lord_routed_forces(lord, BURGUNDIANS),
+ get_lord_routed_forces(lord, MERCENARIES),
+ ]
},
pass() {
- game.battle.reroll = 0
- set_active_enemy()
- game.state = "swift_maneuver_2"
+ goto_battle_lord_rout()
},
}
-states.swift_maneuver_2 = {
- inactive: "Swift Maneuver",
+states.regroup_roll_protection = {
prompt() {
- view.prompt = "Swift Maneuver: You may end the battle round immediately."
- view.actions.end_battle_round = 1
- view.actions.pass = 1
+ view.prompt = "Regroup: Roll each routed troop's protection for them to recover."
+ if (game.event_regroup[MEN_AT_ARMS] > 0)
+ gen_action_routed_men_at_arms(game.who)
+ if (game.event_regroup[LONGBOWMEN] > 0)
+ gen_action_routed_longbowmen(game.who)
+ if (game.event_regroup[MILITIA] > 0)
+ gen_action_routed_militia(game.who)
+ if (game.event_regroup[BURGUNDIANS] > 0)
+ gen_action_routed_burgundians(game.who)
+ if (game.event_regroup[MERCENARIES] > 0)
+ gen_action_routed_mercenaries(game.who)
},
- end_battle_round() {
- logevent(EVENT_YORK_SWIFT_MANEUVER)
- set_active_enemy()
- goto_battle_lord_rout()
+ routed_burgundians(lord) {
+ action_regroup(lord, BURGUNDIANS)
},
- pass() {
- set_active_enemy()
- finish_action_assign_hits()
+ routed_mercenaries(lord) {
+ action_regroup(lord, MERCENARIES)
+ },
+ routed_longbowmen(lord) {
+ action_regroup(lord, LONGBOWMEN)
},
+ routed_men_at_arms(lord) {
+ action_regroup(lord, MEN_AT_ARMS)
+ },
+ routed_militia(lord) {
+ action_regroup(lord, MILITIA)
+ },
+}
+
+function action_regroup(lord: Lord, type: Force) {
+ let protection = get_modified_protection(lord, type)
+
+ let die = roll_die()
+ if (die <= protection) {
+ logi(`${get_force_name(lord, type)} ${range(protection)}: W${die}`)
+ add_lord_routed_forces(lord, type, -1)
+ add_lord_forces(lord, type, 1)
+ } else {
+ logi(`${get_force_name(lord, type)} ${range(protection)}: B${die}`)
+ }
+
+ game.event_regroup[type]--
+
+ for (let i = 2; i < 7; ++i)
+ if (game.event_regroup[i] > 0)
+ return
+ end_regroup()
+}
+
+function end_regroup() {
+ // remove event from play once used
+ set_delete(game.events, EVENT_YORK_REGROUP)
+
+ game.who = NOBODY
+ delete game.event_regroup
+
+ if (game.battle.step < 2)
+ game.state = "assign_hits"
+ else
+ goto_battle_lord_rout()
+}
+
+// === 4.4.2 BATTLE ROUNDS ===
+
+/*
+
+ for each round (until one side is fully routed)
+ flee (defender)
+ flee (attacker)
+ reposition (defender)
+ reposition (attacker)
+ determine engagements
+ VANGUARD (round 1 only)
+ for each engagement
+ archery strike
+ total hits
+ assign hits (defender then attacker)
+ SWIFT MANEUVER - skip to check lord rout
+ melee strike
+ total hits
+ FINAL CHARGE
+ assign hits (defender then attacker)
+ SWIFT MANEUVER - skip to check lord rout
+ check lord rout (defender then attacker)
+ REGROUP
+
+*/
+
+function goto_battle_rounds() {
+ log_h4(`Battle Round ${game.battle.round}`)
+
+ game.battle.step = 0
+
+ if (game.battle.round === 1) {
+ set_active_defender()
+ goto_culverins_and_falconets()
+ } else {
+ goto_flee()
+ }
}
// === BATTLE CAPABILITY: CULVERINS AND FALCONETS ===
@@ -6718,138 +6715,6 @@ function use_culverins(lord: Lord) {
return 0
}
-// === BATTLE CAPABILITY: FINAL CHARGE ===
-
-function can_final_charge() {
- // If LORD_RICHARD_III with RETINUE in engagement before melee strike.
- if (is_melee_step()) {
- for (let pos of game.battle.engagements[0]) {
- let lord = game.battle.array[pos]
- if (lord === LORD_RICHARD_III && get_lord_forces(lord, RETINUE) > 0)
- return true
- }
- }
- return false
-}
-
-states.final_charge = {
- prompt() {
- view.prompt = "Final Charge: Retinue may suffer +1 hit to add +3 extra hits against enemy."
- view.actions.final_charge = 1
- view.actions.pass = 1
- },
- final_charge() {
- logcap(AOW_YORK_FINAL_CHARGE)
- log_hits("+3", lord_name[find_lord_with_capability_card(AOW_YORK_FINAL_CHARGE)])
- log_hits("+1", "Final Charge")
- game.battle.final_charge = 1
- if (game.battle.attacker === YORK) {
- game.battle.ahits += 1
- game.battle.dhits += 3
- } else {
- game.battle.ahits += 3
- game.battle.dhits += 1
- }
- goto_defender_assign_hits()
- },
- pass() {
- goto_defender_assign_hits()
- },
-}
-
-// === BATTLE CAPABILITY: VANGUARD ===
-
-function is_vanguard_in_battle() {
- for (let eng of game.battle.engagements) {
- for (let p of eng) {
- let lord = game.battle.array[p]
- if (lord !== NOBODY) {
- if (lord_has_capability(lord, AOW_YORK_VANGUARD))
- return true
- }
- }
- }
- return false
-}
-
-states.vanguard = {
- get inactive() {
- let lord = find_lord_with_capability_card(AOW_YORK_VANGUARD)
- let p = get_lord_array_position(lord)
- for (let eng of game.battle.engagements)
- if (eng.includes(p))
- view.engaged = eng
- return "Vanguard"
- },
- prompt() {
- view.prompt = "Vanguard: Norfolk may choose his engagement to be the only one."
-
- let lord = find_lord_with_capability_card(AOW_YORK_VANGUARD)
- let p = get_lord_array_position(lord)
- for (let eng of game.battle.engagements)
- if (eng.includes(p))
- view.engaged = eng
-
- view.actions.vanguard = 1
- view.actions.pass = 1
- },
- vanguard() {
- let lord = find_lord_with_capability_card(AOW_YORK_VANGUARD)
-
- // Filter out engagements that don't contain Vanguard lord
- game.battle.engagements = game.battle.engagements.filter(engagement => {
- for (let p of engagement)
- if (game.battle.array[p] === lord)
- return true
- return false
- })
-
- goto_select_engagement()
- },
- pass() {
- goto_select_engagement()
- },
-}
-
-// === 4.4.2 BATTLE ROUNDS ===
-
-/*
-
- for each round (until one side is fully routed)
- flee (defender)
- flee (attacker)
- reposition (defender)
- reposition (attacker)
- determine engagements
- VANGUARD (round 1 only)
- for each engagement
- archery strike
- total hits
- assign hits (defender then attacker)
- SWIFT MANEUVER - skip to check lord rout
- melee strike
- total hits
- FINAL CHARGE
- assign hits (defender then attacker)
- SWIFT MANEUVER - skip to check lord rout
- check lord rout (defender then attacker)
- REGROUP
-
-*/
-
-function goto_battle_rounds() {
- log_h4(`Battle Round ${game.battle.round}`)
-
- game.battle.step = 0
-
- if (game.battle.round === 1) {
- set_active_defender()
- goto_culverins_and_falconets()
- } else {
- goto_flee()
- }
-}
-
// === 4.4.2 BATTLE ROUNDS: FLEE ===
function goto_flee() {
@@ -7195,6 +7060,60 @@ function end_engagement() {
goto_select_engagement()
}
+// === BATTLE CAPABILITY: VANGUARD ===
+
+function is_vanguard_in_battle() {
+ for (let eng of game.battle.engagements) {
+ for (let p of eng) {
+ let lord = game.battle.array[p]
+ if (lord !== NOBODY) {
+ if (lord_has_capability(lord, AOW_YORK_VANGUARD))
+ return true
+ }
+ }
+ }
+ return false
+}
+
+states.vanguard = {
+ get inactive() {
+ let lord = find_lord_with_capability_card(AOW_YORK_VANGUARD)
+ let p = get_lord_array_position(lord)
+ for (let eng of game.battle.engagements)
+ if (eng.includes(p))
+ view.engaged = eng
+ return "Vanguard"
+ },
+ prompt() {
+ view.prompt = "Vanguard: Norfolk may choose his engagement to be the only one."
+
+ let lord = find_lord_with_capability_card(AOW_YORK_VANGUARD)
+ let p = get_lord_array_position(lord)
+ for (let eng of game.battle.engagements)
+ if (eng.includes(p))
+ view.engaged = eng
+
+ view.actions.vanguard = 1
+ view.actions.pass = 1
+ },
+ vanguard() {
+ let lord = find_lord_with_capability_card(AOW_YORK_VANGUARD)
+
+ // Filter out engagements that don't contain Vanguard lord
+ game.battle.engagements = game.battle.engagements.filter(engagement => {
+ for (let p of engagement)
+ if (game.battle.array[p] === lord)
+ return true
+ return false
+ })
+
+ goto_select_engagement()
+ },
+ pass() {
+ goto_select_engagement()
+ },
+}
+
// === 4.4.2 BATTLE ROUNDS: TOTAL HITS (ROUND UP) ===
function goto_total_hits() {
@@ -7254,6 +7173,45 @@ function log_hits(total, name) {
logi(`${total} ${name}`)
}
+// === BATTLE CAPABILITY: FINAL CHARGE ===
+
+function can_final_charge() {
+ // If LORD_RICHARD_III with RETINUE in engagement before melee strike.
+ if (is_melee_step()) {
+ for (let pos of game.battle.engagements[0]) {
+ let lord = game.battle.array[pos]
+ if (lord === LORD_RICHARD_III && get_lord_forces(lord, RETINUE) > 0)
+ return true
+ }
+ }
+ return false
+}
+
+states.final_charge = {
+ prompt() {
+ view.prompt = "Final Charge: Retinue may suffer +1 hit to add +3 extra hits against enemy."
+ view.actions.final_charge = 1
+ view.actions.pass = 1
+ },
+ final_charge() {
+ logcap(AOW_YORK_FINAL_CHARGE)
+ log_hits("+3", lord_name[find_lord_with_capability_card(AOW_YORK_FINAL_CHARGE)])
+ log_hits("+1", "Final Charge")
+ game.battle.final_charge = 1
+ if (game.battle.attacker === YORK) {
+ game.battle.ahits += 1
+ game.battle.dhits += 3
+ } else {
+ game.battle.ahits += 3
+ game.battle.dhits += 1
+ }
+ goto_defender_assign_hits()
+ },
+ pass() {
+ goto_defender_assign_hits()
+ },
+}
+
// === 4.4.2 BATTLE ROUNDS: ROLL BY HIT (PROTECTION ROLL, VALOUR RE-ROLL, FORCES ROUT) ===
function goto_defender_assign_hits() {
@@ -7596,6 +7554,50 @@ function finish_action_assign_hits() {
goto_defender_assign_hits()
}
+// === BATTLE EVENT: SWIFT MANEUVER ===
+
+states.swift_maneuver_1 = {
+ get inactive() {
+ view.engaged = game.battle.engagements[0]
+ return format_strike_step()
+ },
+ prompt() {
+ view.prompt = "Swift Maneuver: Reroll routed retinue?"
+ view.actions.pass = 1
+ gen_action_routed_retinue(game.who)
+ },
+ routed_retinue(lord) {
+ action_spend_valour(lord, RETINUE)
+ if (lord_has_routed_retinue(lord))
+ this.pass()
+ else
+ finish_action_assign_hits()
+ },
+ pass() {
+ game.battle.reroll = 0
+ set_active_enemy()
+ game.state = "swift_maneuver_2"
+ },
+}
+
+states.swift_maneuver_2 = {
+ inactive: "Swift Maneuver",
+ prompt() {
+ view.prompt = "Swift Maneuver: You may end the battle round immediately."
+ view.actions.end_battle_round = 1
+ view.actions.pass = 1
+ },
+ end_battle_round() {
+ logevent(EVENT_YORK_SWIFT_MANEUVER)
+ set_active_enemy()
+ goto_battle_lord_rout()
+ },
+ pass() {
+ set_active_enemy()
+ finish_action_assign_hits()
+ },
+}
+
// === 4.4.2 BATTLE ROUNDS: LORD ROUT ===
function rout_lord(lord: Lord) {
@@ -7625,6 +7627,7 @@ function will_any_friendly_lords_rout() {
function goto_battle_lord_rout() {
game.battle.step = 3
+ game.who = NOBODY
if (is_regroup_in_play()) {
goto_regroup()
@@ -7865,6 +7868,7 @@ states.battle_losses = {
action_losses(lord, MILITIA)
},
done() {
+ game.who = NOBODY
end_battle_losses()
},
}