feat: module 04 interceptors
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 <noreply@anthropic.com>
This commit is contained in:
1 parent
8a4eba1948
commit
bcdaca0cd2
40 files changed
+4421
-1
No files matched your search
@@ -0,0 +1,90 @@
|
||||
//! Content: card definitions. Only this directory may name specific cards.
|
||||
//!
|
||||
//! Each effect is a small Rust function that returns engine actions. Module 5
|
||||
//! replaces these functions with card data the engine interprets. Auras are
|
||||
//! already data: the engine reads them, and no engine code knows these cards.
|
||||
|
||||
use crate::engine::{Action, Aura, CardDef, CardLibrary, Stacking, TriggerOn};
|
||||
|
||||
/// Every card this game knows.
|
||||
pub fn library() -> CardLibrary {
|
||||
CardLibrary::new(vec![
|
||||
// Fictional test minion with no text.
|
||||
CardDef::minion("Test Filler", 1, 1),
|
||||
// "Whenever a friendly minion takes damage, gain 1 Armor."
|
||||
CardDef::minion("Armorsmith", 1, 4).on(TriggerOn::FriendlyMinionDamaged, |c| {
|
||||
vec![Action::GainArmor {
|
||||
player: c.owner,
|
||||
amount: 1,
|
||||
}]
|
||||
}),
|
||||
// "Whenever this minion takes damage, draw a card."
|
||||
CardDef::minion("Acolyte of Pain", 1, 4).on(TriggerOn::SelfDamaged, |c| {
|
||||
vec![Action::Draw { player: c.owner }]
|
||||
}),
|
||||
// Fictional: "Whenever a minion takes damage, deal 1 damage to the enemy hero."
|
||||
CardDef::minion("Test Echo", 1, 5).on(TriggerOn::AnyMinionDamaged, |c| {
|
||||
vec![Action::Damage {
|
||||
targets: vec![c.enemy_hero()],
|
||||
amount: 1,
|
||||
}]
|
||||
}),
|
||||
// Fictional: "Whenever a hero takes damage, gain +1 Attack."
|
||||
CardDef::minion("Test Reactor", 1, 5).on(TriggerOn::HeroDamaged, |c| {
|
||||
vec![Action::GainAttack {
|
||||
id: c.minion(),
|
||||
amount: 1,
|
||||
}]
|
||||
}),
|
||||
// "Deathrattle: Draw a card."
|
||||
CardDef::minion("Loot Hoarder", 2, 1).on(TriggerOn::Deathrattle, |c| {
|
||||
vec![Action::Draw { player: c.owner }]
|
||||
}),
|
||||
// "Deathrattle: Summon a 2/1 Damaged Golem."
|
||||
CardDef::minion("Harvest Golem", 2, 3).on(TriggerOn::Deathrattle, |c| {
|
||||
vec![Action::Summon {
|
||||
card: "Damaged Golem".to_string(),
|
||||
player: c.owner,
|
||||
at: c.position,
|
||||
}]
|
||||
}),
|
||||
// Summoned by Harvest Golem; no text.
|
||||
CardDef::minion("Damaged Golem", 2, 1),
|
||||
// "Taunt. Deathrattle: Deal 1 damage to all minions." The course has no combat, so no Taunt.
|
||||
CardDef::minion("Unstable Ghoul", 1, 3).on(TriggerOn::Deathrattle, |c| {
|
||||
vec![Action::Damage {
|
||||
targets: c.world.minions_in_play(),
|
||||
amount: 1,
|
||||
}]
|
||||
}),
|
||||
// "Your minions trigger their Deathrattles twice." Two Barons still only double.
|
||||
CardDef::minion("Baron Rivendare", 1, 7).aura(Aura::TriggerMultiplier {
|
||||
trigger: TriggerOn::Deathrattle,
|
||||
times: 2,
|
||||
stacking: Stacking::Max,
|
||||
}),
|
||||
// Expansion Drop: "Your Battlecries trigger twice."
|
||||
CardDef::minion("Brann Bronzebeard", 2, 4).aura(Aura::TriggerMultiplier {
|
||||
trigger: TriggerOn::Battlecry,
|
||||
times: 2,
|
||||
stacking: Stacking::Max,
|
||||
}),
|
||||
// "Battlecry: Draw a card."
|
||||
CardDef::minion("Novice Engineer", 1, 1).on(TriggerOn::Battlecry, |c| {
|
||||
vec![Action::Draw { player: c.owner }]
|
||||
}),
|
||||
// "Deal 1 damage to ALL minions."
|
||||
CardDef::spell("Whirlwind", |c| {
|
||||
vec![Action::Damage {
|
||||
targets: c.world.minions_in_play(),
|
||||
amount: 1,
|
||||
}]
|
||||
}),
|
||||
// "Destroy all minions and locations." The course has no locations. (Module 3 Expansion Drop.)
|
||||
CardDef::spell("Twisting Nether", |c| {
|
||||
vec![Action::Destroy {
|
||||
targets: c.world.minions_in_play(),
|
||||
}]
|
||||
}),
|
||||
])
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// Content: card definitions. Only this directory may name specific cards.
|
||||
//
|
||||
// Each effect is a small function that returns engine actions. Module 5
|
||||
// replaces these functions with card data the engine interprets. Auras are
|
||||
// already data: the engine reads them, and no engine code knows these cards.
|
||||
|
||||
import { CardLibrary, minion, spell } from "../engine";
|
||||
|
||||
/** Every card this game knows. */
|
||||
export function library(): CardLibrary {
|
||||
return new CardLibrary([
|
||||
// Fictional test minion with no text.
|
||||
minion("Test Filler", 1, 1),
|
||||
// "Whenever a friendly minion takes damage, gain 1 Armor."
|
||||
minion("Armorsmith", 1, 4, [
|
||||
{ on: "friendlyMinionDamaged", effect: (c) => [{ type: "gainArmor", player: c.owner, amount: 1 }] },
|
||||
]),
|
||||
// "Whenever this minion takes damage, draw a card."
|
||||
minion("Acolyte of Pain", 1, 4, [{ on: "selfDamaged", effect: (c) => [{ type: "draw", player: c.owner }] }]),
|
||||
// Fictional: "Whenever a minion takes damage, deal 1 damage to the enemy hero."
|
||||
minion("Test Echo", 1, 5, [
|
||||
{ on: "anyMinionDamaged", effect: (c) => [{ type: "damage", targets: [c.enemyHero()], amount: 1 }] },
|
||||
]),
|
||||
// Fictional: "Whenever a hero takes damage, gain +1 Attack."
|
||||
minion("Test Reactor", 1, 5, [
|
||||
{ on: "heroDamaged", effect: (c) => [{ type: "gainAttack", id: c.minion(), amount: 1 }] },
|
||||
]),
|
||||
// "Deathrattle: Draw a card."
|
||||
minion("Loot Hoarder", 2, 1, [{ on: "deathrattle", effect: (c) => [{ type: "draw", player: c.owner }] }]),
|
||||
// "Deathrattle: Summon a 2/1 Damaged Golem."
|
||||
minion("Harvest Golem", 2, 3, [
|
||||
{
|
||||
on: "deathrattle",
|
||||
effect: (c) => [{ type: "summon", card: "Damaged Golem", player: c.owner, at: c.position }],
|
||||
},
|
||||
]),
|
||||
// Summoned by Harvest Golem; no text.
|
||||
minion("Damaged Golem", 2, 1),
|
||||
// "Taunt. Deathrattle: Deal 1 damage to all minions." The course has no combat, so no Taunt.
|
||||
minion("Unstable Ghoul", 1, 3, [
|
||||
{
|
||||
on: "deathrattle",
|
||||
effect: (c) => [{ type: "damage", targets: c.world.minionsInPlay(), amount: 1 }],
|
||||
},
|
||||
]),
|
||||
// "Your minions trigger their Deathrattles twice." Two Barons still only double.
|
||||
minion("Baron Rivendare", 1, 7, [], [
|
||||
{ type: "triggerMultiplier", trigger: "deathrattle", times: 2, stacking: "max" },
|
||||
]),
|
||||
// Expansion Drop: "Your Battlecries trigger twice."
|
||||
minion("Brann Bronzebeard", 2, 4, [], [
|
||||
{ type: "triggerMultiplier", trigger: "battlecry", times: 2, stacking: "max" },
|
||||
]),
|
||||
// "Battlecry: Draw a card."
|
||||
minion("Novice Engineer", 1, 1, [{ on: "battlecry", effect: (c) => [{ type: "draw", player: c.owner }] }]),
|
||||
// "Deal 1 damage to ALL minions."
|
||||
spell("Whirlwind", (c) => [{ type: "damage", targets: c.world.minionsInPlay(), amount: 1 }]),
|
||||
// "Destroy all minions and locations." The course has no locations. (Module 3 Expansion Drop.)
|
||||
spell("Twisting Nether", (c) => [{ type: "destroy", targets: c.world.minionsInPlay() }]),
|
||||
]);
|
||||
}
|
||||
Reference in new issue
Block a user