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]>
164 lines
4.2 KiB
Rust
164 lines
4.2 KiB
Rust
// Module 4: Interceptors and "trigger twice". Each test matches a heading in scenarios.md.
|
|
use engine::harness::*;
|
|
|
|
fn game_with_deck() -> Game {
|
|
new_game(GameOpts {
|
|
decks: Some([vec!["Test Filler".to_string(); 5], vec![]]),
|
|
})
|
|
}
|
|
|
|
fn damaged(target: Id, amount: i32) -> GameEvent {
|
|
GameEvent::Damaged { target, amount }
|
|
}
|
|
|
|
fn triggered(source: Id, trigger: &str) -> GameEvent {
|
|
GameEvent::Triggered {
|
|
source,
|
|
trigger: trigger.to_string(),
|
|
}
|
|
}
|
|
|
|
fn spell_cast(card: &str) -> GameEvent {
|
|
GameEvent::SpellCast {
|
|
card: card.to_string(),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_04_baron_doubles() {
|
|
let mut g = game_with_deck();
|
|
let b = g.summon("Baron Rivendare", 0);
|
|
let h = g.summon("Loot Hoarder", 0);
|
|
let golem = g.summon("Harvest Golem", 0);
|
|
g.deal_damage(golem, 2);
|
|
g.clear_log();
|
|
|
|
g.cast("Whirlwind", 0, None);
|
|
|
|
let hand = g.hand(0);
|
|
assert_eq!(hand.len(), 2);
|
|
let (c1, c2) = (hand[0], hand[1]);
|
|
let board = g.board(0);
|
|
assert_eq!(board.len(), 3);
|
|
assert_eq!(board[0], b);
|
|
let (d1, d2) = (board[1], board[2]);
|
|
assert_eq!(
|
|
g.log(),
|
|
vec![
|
|
spell_cast("Whirlwind"),
|
|
damaged(b, 1),
|
|
damaged(h, 1),
|
|
damaged(golem, 1),
|
|
GameEvent::Destroyed { id: h },
|
|
GameEvent::Destroyed { id: golem },
|
|
GameEvent::DeathPhase { round: 1 },
|
|
triggered(h, "deathrattle"),
|
|
GameEvent::Drew { player: 0, id: c1 },
|
|
triggered(h, "deathrattle"),
|
|
GameEvent::Drew { player: 0, id: c2 },
|
|
triggered(golem, "deathrattle"),
|
|
GameEvent::Summoned { id: d1 },
|
|
triggered(golem, "deathrattle"),
|
|
GameEvent::Summoned { id: d2 },
|
|
]
|
|
);
|
|
assert_eq!(g.name_of(d1), "Damaged Golem");
|
|
assert_eq!(g.name_of(d2), "Damaged Golem");
|
|
assert_eq!(g.health(b), 6);
|
|
}
|
|
|
|
#[test]
|
|
fn test_04_simultaneous_death_not_doubled() {
|
|
let mut g = game_with_deck();
|
|
let b = g.summon("Baron Rivendare", 0);
|
|
let h = g.summon("Loot Hoarder", 0);
|
|
g.clear_log();
|
|
|
|
g.cast("Twisting Nether", 0, None);
|
|
|
|
assert_eq!(g.hand(0).len(), 1);
|
|
let hoarder_triggers = g
|
|
.log()
|
|
.into_iter()
|
|
.filter(|e| *e == triggered(h, "deathrattle"))
|
|
.count();
|
|
assert_eq!(hoarder_triggers, 1);
|
|
assert_eq!(g.zone_of(b), Zone::Graveyard);
|
|
assert_eq!(g.zone_of(h), Zone::Graveyard);
|
|
}
|
|
|
|
#[test]
|
|
fn test_04_two_barons_do_not_stack() {
|
|
let mut g = game_with_deck();
|
|
g.summon("Baron Rivendare", 0);
|
|
g.summon("Baron Rivendare", 0);
|
|
let h = g.summon("Loot Hoarder", 0);
|
|
g.clear_log();
|
|
|
|
g.deal_damage(h, 1);
|
|
|
|
let hand = g.hand(0);
|
|
assert_eq!(hand.len(), 2);
|
|
let (c1, c2) = (hand[0], hand[1]);
|
|
assert_eq!(
|
|
g.log(),
|
|
vec![
|
|
damaged(h, 1),
|
|
GameEvent::Destroyed { id: h },
|
|
GameEvent::DeathPhase { round: 1 },
|
|
triggered(h, "deathrattle"),
|
|
GameEvent::Drew { player: 0, id: c1 },
|
|
triggered(h, "deathrattle"),
|
|
GameEvent::Drew { player: 0, id: c2 },
|
|
]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_04_aura_timing_order() {
|
|
let mut g = game_with_deck();
|
|
let h = g.summon("Loot Hoarder", 0);
|
|
let b = g.summon("Baron Rivendare", 0);
|
|
g.clear_log();
|
|
|
|
g.cast("Twisting Nether", 0, None);
|
|
|
|
let hand = g.hand(0);
|
|
assert_eq!(hand.len(), 1);
|
|
let c = hand[0];
|
|
assert_eq!(
|
|
g.log(),
|
|
vec![
|
|
spell_cast("Twisting Nether"),
|
|
GameEvent::Destroyed { id: h },
|
|
GameEvent::Destroyed { id: b },
|
|
GameEvent::DeathPhase { round: 1 },
|
|
triggered(h, "deathrattle"),
|
|
GameEvent::Drew { player: 0, id: c },
|
|
]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_04_battlecry_on_play() {
|
|
let mut g = game_with_deck();
|
|
let e = g.add_to_hand("Novice Engineer", 0);
|
|
g.clear_log();
|
|
|
|
g.play(e);
|
|
|
|
let hand = g.hand(0);
|
|
assert_eq!(hand.len(), 1);
|
|
let c = hand[0];
|
|
assert_eq!(
|
|
g.log(),
|
|
vec![
|
|
GameEvent::Summoned { id: e },
|
|
triggered(e, "battlecry"),
|
|
GameEvent::Drew { player: 0, id: c },
|
|
]
|
|
);
|
|
assert_eq!(g.zone_of(e), Zone::Board);
|
|
assert_eq!(g.board(0), vec![e]);
|
|
}
|