//! The Death Creation Step: the one place minions leave play. //! //! Damage and destroy effects only mark a minion (0 or less Health, or pending //! destroy). It stays in play, and keeps triggering, until the outermost Phase //! ends. Then this step removes every marked minion at once. use super::event::Event; use super::world::{EntityId, World, Zone}; /// Remove every mortally wounded or pending-destroy minion from play, simultaneously. /// Returns their Death Events in order of play; empty if nothing died. pub fn death_creation_step(world: &mut World) -> Vec { // Every neighbour is read before anything moves: removal is simultaneous. Each Death // Event remembers where its minion stood as a handle, the minion that stays to its // right, not as a board index: an index goes stale as soon as a minion further left // leaves play in the same step (Module 1: hold handles, not indexes). let mut deaths = Vec::new(); for id in world.minions_in_play() { if world.is_doomed(id) { let before = survivor_to_the_right(world, id); deaths.push(Event::Destroyed { id, before }); } } for death in &deaths { if let Event::Destroyed { id, before } = *death { world.kill(id, before); } } deaths } /// The nearest minion to the right of `id` on its board that is not leaving play in this step, if any. fn survivor_to_the_right(world: &World, id: EntityId) -> Option { world .zone(world.owner_of(id), Zone::Board) .iter() .copied() .skip_while(|&other| other != id) .skip(1) .find(|&other| !world.is_doomed(other)) }