Trigger multipliers as aura data on cards, snapshotted by an Aura Update (Other) after each Death Creation Step and on summon, and applied by one generic routine (activations) when each queued trigger starts. Baron Rivendare is content only (stacking "max"); Brann Bronzebeard is the content-only Expansion Drop. Adds play (now required) and Battlecry. Co-Authored-By: Claude Opus 5.5 <[email protected]>
54 lines
2.1 KiB
Rust
54 lines
2.1 KiB
Rust
//! 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
|
|
}
|