Rev 21: collapsing walls crush anyone — monsters included
DESTROY WALL's "anyone in either square next to the wall takes 4 points" swept only wizards; a troll leaned on the falling masonry untouched. The expansion sheet is explicit — "if a card specifies 'Opponent' or 'Anyone' as a target, this includes Monsters" — so the collapse now crushes creatures in both squares, at the rim breach's far side too. Earlier ledgers keep their charmed monsters. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
6380fae134
commit
7df58d29fa
@@ -1108,6 +1108,13 @@ const CARD_EFFECTS: Record<string, AttackEffect | NeutralEffect | CounterEffect>
|
||||
applyDamage(state, events, p, 4, "collapsing wall", caster.id, "physical");
|
||||
}
|
||||
}
|
||||
if ((state.config.deckRev ?? 1) >= 21) {
|
||||
for (const cr of [...state.creatures]) {
|
||||
if (cellKey(cr.position) === cellKey(far.cell)) {
|
||||
damageCreature(state, events, cr, 4, "collapsing wall");
|
||||
}
|
||||
}
|
||||
}
|
||||
state.board.warps.push(
|
||||
{ from: { cell, side }, to: { cell: far.cell, side: far.side } },
|
||||
{ from: { cell: far.cell, side: far.side }, to: { cell, side } },
|
||||
@@ -1121,6 +1128,15 @@ const CARD_EFFECTS: Record<string, AttackEffect | NeutralEffect | CounterEffect>
|
||||
applyDamage(state, events, p, 4, "collapsing wall", caster.id, "physical");
|
||||
}
|
||||
}
|
||||
// "Anyone in either square" includes monsters — the expansion sheet
|
||||
// says so in as many words (rules rev 21).
|
||||
if ((state.config.deckRev ?? 1) >= 21) {
|
||||
for (const cr of [...state.creatures]) {
|
||||
if (cellKey(cr.position) === cellKey(c)) {
|
||||
damageCreature(state, events, cr, 4, "collapsing wall");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checkVictory(state, events);
|
||||
return null;
|
||||
|
||||
@@ -640,3 +640,46 @@ describe("a mid-round democratic monster claws on the next turn (rules rev 18)",
|
||||
expect(r.state.stack?.creatureId ?? null).toBe(fresh.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("collapsing walls crush monsters too (rules rev 21)", () => {
|
||||
function wallRig(deckRev: number) {
|
||||
let { state } = createGame({ playerIds: ["a", "b"], seed: 42, sets: ["basic", "expansion1"], deckRev });
|
||||
state = toRound2(state);
|
||||
const view = boardView(state);
|
||||
for (const [key, edge] of Object.entries(view.edges)) {
|
||||
if (edge !== "wall") continue;
|
||||
const [kind, coords] = key.split(":") as [string, string];
|
||||
const [x, y] = coords.split(",").map(Number) as [number, number];
|
||||
const side = kind === "V" ? ("E" as Side) : ("S" as Side);
|
||||
const other = { x: x + (side === "E" ? 1 : 0), y: y + (side === "S" ? 1 : 0) };
|
||||
if (!view.cells[cellKey(other)]) continue;
|
||||
const caster = activePlayer(state);
|
||||
caster.position = { x, y };
|
||||
state.creatures.push({
|
||||
id: "tr1", kind: "troll", controllerId: caster.id,
|
||||
position: { ...other }, damage: 0, maxDamage: 6, movesPerTurn: 3,
|
||||
movementUsed: 0, attackUsed: false, justCreated: false,
|
||||
wallPassesPerTurn: 0, wallPassUsed: 0, scorchedThisTurn: [],
|
||||
});
|
||||
const dw = giveCard(state, caster.id, "destroy-wall");
|
||||
const r = applyCommand(state, caster.id, {
|
||||
type: "cast", instanceId: dw.instanceId, target: { kind: "edge", cell: { x, y }, side },
|
||||
});
|
||||
if (!r.ok) throw new Error(r.error);
|
||||
return r.state;
|
||||
}
|
||||
throw new Error("setup: no interior wall found");
|
||||
}
|
||||
|
||||
it("rev 21: the adjacent troll takes the four points", () => {
|
||||
const state = wallRig(21);
|
||||
const troll = state.creatures.find((c) => c.id === "tr1");
|
||||
// Four points on a six-point troll: hurt but standing (or regenerating).
|
||||
expect(troll?.damage).toBe(4);
|
||||
});
|
||||
|
||||
it("earlier revisions leave the troll dusty but unharmed", () => {
|
||||
const state = wallRig(20);
|
||||
expect(state.creatures.find((c) => c.id === "tr1")!.damage).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,7 +54,7 @@ export interface Room {
|
||||
const rooms = new Map<string, Room>();
|
||||
|
||||
/** Rules revision new games are dealt under (stored games keep their own). */
|
||||
const RULES_REV = 20;
|
||||
const RULES_REV = 21;
|
||||
|
||||
const ROOM_CODE_ALPHABET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ class LocalGame {
|
||||
seed,
|
||||
sets: expansion ? ["basic", "expansion1"] : ["basic"],
|
||||
...(colors ? { colors } : {}),
|
||||
deckRev: 20,
|
||||
deckRev: 21,
|
||||
};
|
||||
const { state, events } = createGame(config);
|
||||
for (const e of events) {
|
||||
|
||||
Reference in New Issue
Block a user