use crate::types::*;
use crate::scene::types::*;
use crate::combat::types::*;
use crate::content::builders::*;
pub fn junction_entry() -> Scene {
scene(
"bj_entry", "breakwater_junction", "11_1",
PacingTag::Crisis,
vec![
narrate_with(
"Breakwater Junction: where three rail corridors, two telegraph \
routes, and the basin's primary water distribution all intersect. \
The machine is done pretending.",
EmotionTag::Tense,
),
narrate(
"Rail enforcement, hired guns, and a territorial marshal's \
detachment converge on the junction. The party has hours, not days.",
),
say_with("eli",
"Deadwater hurt them. This is the answer.",
EmotionTag::Tense,
),
],
vec![
choice("Prepare for the battle", vec![], to_scene("bj_preparation")),
],
vec![
set_flag("ch11_started", true),
],
)
}
pub fn preparation() -> Scene {
scene(
"bj_preparation", "breakwater_junction", "11_2",
PacingTag::Crisis,
vec![
narrate("This is the last time the full party operates at peak capacity."),
say_with("rosa", "Hold everything. Don't yield a foot.", EmotionTag::Bitter),
say_with("ada", "Evacuate civilians first. Then defend what's defensible.", EmotionTag::Tense),
say_with("miriam",
"Make the defense visible. Let the retaliation look like what it is.",
EmotionTag::Neutral,
),
say_with("eli", "Let them overcommit. Then the evidence of retaliation \
IS the next round of testimony.", EmotionTag::Dry),
say_if_with("lucien",
"Controlled demolition of the depot row. Deny them staging ground.",
vec![flag_is("lucien_captured", true)],
EmotionTag::Neutral,
),
say_if_with("narrator",
"The relay's structural proof is in the evidence bundle. \
Tom's engineering — the load calculations that proved \
deliberate failure — gives the defense a foundation. \
They're not just holding ground. They're holding proof \
that ground was taken by design.",
vec![flag_eq("relay_branch", "tom")],
EmotionTag::Quiet,
),
say_if_with("narrator",
"Nella's testimony is in the evidence bundle. A living \
witness who saw the relay fire and named the men who \
lit it. If the junction falls, the machine buries one \
more voice. The defense is personal.",
vec![flag_eq("relay_branch", "nella")],
EmotionTag::Tense,
),
say_if_with("narrator",
"The relay papers are in the evidence bundle. Transfer \
orders, payroll ghosts, the paper trail of arson. If \
Breakwater falls, the papers burn again — the same \
story, the same method, a generation later.",
vec![flag_eq("relay_branch", "papers")],
EmotionTag::Tense,
),
],
vec![
choice("Hold Breakwater", vec![], to_combat("breakwater_battle")),
],
vec![],
)
}
pub fn hand_injury() -> Scene {
scene(
"bj_hand_injury", "breakwater_junction", "11_4",
PacingTag::Intimate,
vec![
narrate_with(
"The battle turns. The party is holding. Then the price comes due.",
EmotionTag::Grief,
),
narrate(
"Galen holds a position to let Ada evacuate a wounded civilian. \
A support beam drops. His dominant hand catches against steel \
and stone.",
),
narrate_with(
"The shot he fired was correct. The cost is permanent.",
EmotionTag::Grief,
),
],
vec![
choice("Ada treats the hand", vec![
StateEffect::ApplyInjury {
character: CharacterId::new("galen"),
injury: InjuryId::new("hand_injury_permanent"),
},
set_flag("hand_wounded", true),
], to_scene("bj_ada_treatment")),
],
vec![],
)
}
pub fn ada_treatment() -> Scene {
scene(
"bj_ada_treatment", "breakwater_junction", "11_4",
PacingTag::Intimate,
vec![
narrate("Ada examines the hand. Clinical first."),
say_with("ada",
"The bones will set. Two of them clean, one with a ridge you'll \
feel when it's cold.",
EmotionTag::Neutral,
),
say_with("ada",
"Tendon damage here. Partial. You'll have strength. Not speed.",
EmotionTag::Neutral,
),
say_with("ada",
"You will hold a gun. You will aim a gun. You will fire a gun.",
EmotionTag::Neutral,
),
narrate("A beat."),
say_with("ada",
"You will not draw the way you used to. That nerve path is \
interrupted. It won't come back.",
EmotionTag::Quiet,
),
narrate_with(
"Galen looks at the hand. His hand. The one Voss trained at \
the shooting post in Cedar Wake.",
EmotionTag::Grief,
),
say_with("ada",
"The skill is still in you. It just has to travel a different \
road to your fingers now.",
EmotionTag::Quiet,
),
],
vec![
choice("Continue", vec![], to_scene("bj_victory")),
],
vec![],
)
}
pub fn victory() -> Scene {
scene_with_memory(
"bj_victory", "breakwater_junction", "11_5",
PacingTag::Pressure,
vec![
narrate_with(
"The retaliation force is broken. The junction is held. The water \
flows. The wire is up.",
EmotionTag::Warm,
),
narrate_with(
"We won. And Galen's hand — Ada wrapped it, and she looked at him \
the way you look at something that won't be the same.",
EmotionTag::Grief,
),
narrate("We won. The hand doesn't close right anymore. We won."),
],
vec![],
vec![
set_flag("ch11_complete", true),
set_flag("breakwater_held", true),
set_flag("retaliation_answered", true),
memory("breakwater_victory"),
],
vec![
MemoryRef {
object: MemoryObjectId::new("hand_injury"),
callback_type: MemoryCallbackType::Transform,
target_chapter: Some(ChapterId::new("ch13")),
},
],
)
}
pub fn breakwater_battle() -> Encounter {
Encounter {
id: EncounterId::new("breakwater_battle"),
phases: vec![
CombatPhase {
id: "main_assault".to_string(),
description: "Full retaliation force. The machine answers truth with force.".to_string(),
enemies: vec![
enemy_full("rail_enforcer_a", "Rail Enforcer", 32, 25, 11, 60, 7, 12, 7),
enemy_full("rail_enforcer_b", "Rail Enforcer", 30, 24, 10, 58, 8, 12, 7),
enemy_full("hired_gun_a", "Hired Gun", 28, 22, 9, 55, 7, 15, 6),
enemy_full("hired_gun_b", "Hired Gun", 28, 22, 9, 55, 6, 15, 6),
enemy("marshal_deputy", "Marshal's Deputy", 25, 20, 8, 52, 7),
],
npc_allies: vec![],
entry_conditions: vec![],
phase_effects: vec![],
},
],
standoff: Some(Standoff {
postures: vec![StandoffPosture::EarlyDraw, StandoffPosture::SteadyHand, StandoffPosture::Bait],
allow_focus: true,
eli_influence: true,
}),
party_slots: 4,
terrain: Terrain {
name: "Breakwater Junction".to_string(),
cover: vec![
CoverElement { name: "Rail car".to_string(), durability: 80, destructible: false },
CoverElement { name: "Water works wall".to_string(), durability: 70, destructible: false },
CoverElement { name: "Supply depot".to_string(), durability: 40, destructible: true },
CoverElement { name: "Bridge railing".to_string(), durability: 25, destructible: true },
],
hazards: vec![],
},
objectives: vec![
Objective {
id: "hold_junction".to_string(),
label: "Hold Breakwater Junction".to_string(),
objective_type: ObjectiveType::Primary,
fail_consequence: vec![set_flag("junction_lost", true)],
success_consequence: vec![set_flag("junction_held", true)],
},
Objective {
id: "protect_water_works".to_string(),
label: "Protect the water works".to_string(),
objective_type: ObjectiveType::Secondary,
fail_consequence: vec![set_flag("water_works_damaged", true)],
success_consequence: vec![set_flag("water_works_intact", true)],
},
],
outcome_effects: vec![],
escapable: true,
}
}
pub fn get_scene(id: &str) -> Option<Scene> {
match id {
"bj_entry" => Some(junction_entry()),
"bj_preparation" => Some(preparation()),
"bj_hand_injury" => Some(hand_injury()),
"bj_ada_treatment" => Some(ada_treatment()),
"bj_victory" => Some(victory()),
_ => None,
}
}
pub fn get_encounter(id: &str) -> Option<Encounter> {
match id {
"breakwater_battle" => Some(breakwater_battle()),
_ => None,
}
}