feat(mc-turn): Update turn-based event processing logic and adjust test wiring for event collection

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
autocommit 2026-05-19 21:24:52 -07:00
parent 59503ecf8e
commit 39aa1f25e2
2 changed files with 38 additions and 1 deletions

View file

@ -3459,9 +3459,39 @@ impl TurnProcessor {
// last city is captured. Matches the
// `eliminated_player_skipped_in_domination` test's manual
// setup at `victory.rs:798` (`p1.capital_position = None`).
if defender.capital_position == Some(pos) {
//
// Communications Phase 6 wiring: when the defender's
// capital is lost (and they still have surviving cities),
// begin a comms blackout. Drops in-flight outbound
// envelopes, penalises comm-tier, accelerates last-seen
// decay. Emits `CapitalBlackoutBegan` for the replay
// viewer; the next-turn handler enforces the 1-turn UX
// gate per `project_capital_blackout_design.md`.
let lost_capital = defender.capital_position == Some(pos);
if lost_capital {
defender.capital_position = None;
}
let defender_cities_remaining = !defender.cities.is_empty();
// End the &mut state.players[defender_pi] borrow before
// touching state.comms (also a child of state).
let _ = defender;
if lost_capital && defender_cities_remaining {
let turn_now = state.turn;
mc_comms::blackout::begin_blackout(
&mut state.comms,
defender_pi as u8,
turn_now,
);
result.events_emitted.push(
mc_replay::TurnEvent::CapitalBlackoutBegan {
turn: turn_now,
player: mc_replay::ClanId(defender_pi as u32),
lost_capital_hex: mc_replay::TileCoord::new(
pos.0, pos.1,
),
},
);
}
// Transfer to attacker.
let attacker = &mut state.players[attacker_pi];

View file

@ -232,6 +232,13 @@ fn ten_turn_run_emits_each_wired_variant() {
TurnEvent::HeartbeatMissed { .. } => "HeartbeatMissed",
TurnEvent::VisionShareCollapsed { .. } => "VisionShareCollapsed",
TurnEvent::VisionShareRestored { .. } => "VisionShareRestored",
// Communications Phase 6 (envelope-flow + link-flow) — labelled
// for exhaustiveness; the 10-turn fixture does not exercise them.
TurnEvent::EnvelopeDispatched { .. } => "EnvelopeDispatched",
TurnEvent::EnvelopeDelivered { .. } => "EnvelopeDelivered",
TurnEvent::EnvelopeIntercepted { .. } => "EnvelopeIntercepted",
TurnEvent::LinkSevered { .. } => "LinkSevered",
TurnEvent::LinkRestored { .. } => "LinkRestored",
})
.collect();