//! Auras, and the one routine that applies trigger multipliers. //! //! An aura is data on a card: a continuous effect its minion has while in play. //! The engine never asks "is that card on the board?" in the middle of resolving //! something. It takes a snapshot of the auras in force at defined points (an Aura //! Update) and every rule reads the snapshot. //! //! Hearthstone runs two kinds of Aura Update when the outermost Phase ends: one for //! Health/Attack auras before the Death Creation Step, and one for every other aura //! after it. Trigger multipliers are "Other" auras, so a minion that dies in a Death //! Creation Step no longer multiplies the Deathrattles of that step's Death Phase. //! Summoning a minion also runs an Aura Update. use super::card::{Aura, Stacking, TriggerOn}; use super::world::{ActiveAura, PlayerId, World}; /// Aura Update (Other): replace the snapshot with the auras of every minion now in play. pub fn aura_update_other(world: &mut World) { let mut active = Vec::new(); for id in world.minions_in_play() { for &aura in &world.card(world.card_name(id)).auras { active.push(ActiveAura { owner: world.owner_of(id), aura, }); } } world.set_active_auras(active); } /// How many times a trigger listening for `on`, on a minion `owner` controls, activates /// when it resolves. Reads the snapshot from the last Aura Update. With no multiplier in /// force the answer is 1. Multipliers with `Stacking::Max` contribute their largest /// `times`; each `Stacking::Additive` one adds `times - 1` extra activations. pub fn activations(world: &World, owner: PlayerId, on: TriggerOn) -> u32 { let mut max = 1; let mut extra = 0; for active in world.active_auras() { let Aura::TriggerMultiplier { trigger, times, stacking, } = active.aura; if active.owner != owner || trigger != on { continue; } match stacking { Stacking::Max => max = max.max(times), Stacking::Additive => extra += times - 1, } } max + extra }