feat: summoned minions enter the grid in Module 10 (a fourth seam; Clay Golem, Clay Shard)
Summoned records its summoner (the minion whose trigger is resolving) inside the engine; the harness log is unchanged. When a Sequence ends, SpellGrid writes spawned text, places each summoned minion with a noun on its summoner's tile, removes the dead, reparses and syncs rule auras. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
820b378929
commit
4eaf24eed2
23 files changed
+361
-42
No files matched your search
@@ -1,7 +1,7 @@
|
||||
//! Part III: SpellGrid, the two engines in one level.
|
||||
//!
|
||||
//! Part I (the card engine) and Part II (the grid engine, `puzzle`) don't use each
|
||||
//! other. This file is the only place that knows both, and they meet at three seams:
|
||||
//! other. This file is the only place that knows both, and they meet at four seams:
|
||||
//!
|
||||
//! 1. Rules become modifiers. After every reparse, the rules in force that join a
|
||||
//! trigger word to a multiplier word (`DEATHRATTLE IS DOUBLE`) are compiled into
|
||||
@@ -15,6 +15,10 @@
|
||||
//! ends, the text its effects asked for (`TextSpawned` events) is written, the
|
||||
//! minions that died (`Destroyed` events) leave the grid, and the rules are parsed
|
||||
//! again, before anything else happens.
|
||||
//! 4. Summoned minions enter the grid. In the same place, before the dead leave: a
|
||||
//! minion that a minion's ability summoned (`Summoned` events with a `by`), whose card
|
||||
//! has a noun, becomes an object of that noun on its summoner's tile. One summoned by
|
||||
//! a spell, or with no noun, is in play but not on the grid.
|
||||
//!
|
||||
//! One id space: a minion's id is its grid object's id. Every other card (a hero, a
|
||||
//! card in hand) gets an id from the same counter that no object will have.
|
||||
@@ -338,13 +342,13 @@ impl CardSide {
|
||||
self.sequence(level, Action::Destroy { targets: minions });
|
||||
}
|
||||
|
||||
/// Run one Sequence in Part I, then seam 3: apply its grid changes and reparse.
|
||||
/// Run one Sequence in Part I, then seams 3 and 4: apply its grid changes and reparse.
|
||||
fn sequence(&mut self, level: &mut Level, action: Action) {
|
||||
let from = self.world.log().len();
|
||||
run_sequence(&mut self.world, action);
|
||||
let events = self.world.log()[from..].to_vec();
|
||||
// Text first, while every minion that wrote it is still on its tile. A minion
|
||||
// with no id (summoned by this Sequence) is not on the grid: nowhere to write.
|
||||
// with no id (summoned by this Sequence) is not on the grid yet: nowhere to write.
|
||||
for event in &events {
|
||||
if let Event::TextSpawned { source, word } = event {
|
||||
let tile = self
|
||||
@@ -358,6 +362,27 @@ impl CardSide {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Seam 4: summoned minions, in summon order, on their summoner's tile. The dead are
|
||||
// still on the grid here, so a Deathrattle's summoner is found where it died; a
|
||||
// minion summoned earlier in the list is already placed, so it can be a summoner too.
|
||||
for event in &events {
|
||||
let Event::Summoned { id, by: Some(by) } = *event else {
|
||||
continue;
|
||||
};
|
||||
let card = self.world.card_name(id).to_string();
|
||||
if self.ids.contains_key(&id) || self.world.card(&card).def.noun.is_none() {
|
||||
continue;
|
||||
}
|
||||
let tile = self
|
||||
.ids
|
||||
.get(&by)
|
||||
.and_then(|&object| level.board().find(object))
|
||||
.map(|o| (o.x, o.y));
|
||||
if let Some((x, y)) = tile {
|
||||
let object = level.board_mut().place(self.noun_of(&card), x, y);
|
||||
self.link(id, object);
|
||||
}
|
||||
}
|
||||
for event in &events {
|
||||
if let Event::Destroyed { id, .. } = event {
|
||||
if let Some(&object) = self.ids.get(id) {
|
||||
|
||||
Reference in new issue
Block a user