The ward's bite gets its name, and shrink slips past the giant
Two chronicle truths from tonight's table: the cardless ward stack fell through to 'punch from <owner>' — stacks now carry a sourceName, and the bite reads 'warded treasure' as it always did pre-rev-9. And a SHRUNK wizard walks straight through BIG MAN's square (table ruling: small enough to slip between the giant's boots) — a widening, shipped ungated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
This commit is contained in:
co-authored by
Claude Fable 5
parent
d334b267a2
commit
7bcad12449
@@ -215,6 +215,9 @@ export interface CastStack {
|
||||
/** STRENGTH's tear: "this would be an attack" — the grab rides the stack
|
||||
* like a punch, and the clutch roll waits for the counteractions. */
|
||||
tearTreasure?: true;
|
||||
/** What a cardless stack's blow is called in the chronicle (the WARD's
|
||||
* bite); without it the source falls back to "punch from <attacker>". */
|
||||
sourceName?: string;
|
||||
}
|
||||
|
||||
export interface CastParams {
|
||||
@@ -4233,12 +4236,15 @@ function doMove(prev: GameState, direction: Side, over = false): CommandResult {
|
||||
// Square contents at the destination.
|
||||
let content = state.squareContents[cellKey(p.position)];
|
||||
if (content?.kind === "stone") return err("that square is solid stone");
|
||||
// BIG MAN: nobody enters his square.
|
||||
for (const other of state.players) {
|
||||
if (other.id !== p.id && other.alive && cellKey(other.position) === cellKey(p.position) &&
|
||||
sustainedOn(state, other.id, "big-man").length > 0) {
|
||||
p.position = from;
|
||||
return err("a giant fills that corridor");
|
||||
// BIG MAN: nobody enters his square — except a SHRUNK wizard, small
|
||||
// enough to slip between the giant's boots (table ruling).
|
||||
if (sustainedOn(state, p.id, "shrink").length === 0) {
|
||||
for (const other of state.players) {
|
||||
if (other.id !== p.id && other.alive && cellKey(other.position) === cellKey(p.position) &&
|
||||
sustainedOn(state, other.id, "big-man").length > 0) {
|
||||
p.position = from;
|
||||
return err("a giant fills that corridor");
|
||||
}
|
||||
}
|
||||
}
|
||||
// BIG MAN pushes: "You can push monsters or other players (in an adjacent
|
||||
@@ -4663,7 +4669,7 @@ function doWardChoice(prev: GameState, play: boolean): CommandResult {
|
||||
// recorded the instant bite and replay it.
|
||||
if ((state.config.deckRev ?? 1) >= 9) {
|
||||
openCardlessStack(state, owner.id, taker.id, {
|
||||
params: { damage: 3 }, kind: "spell", trapped: true,
|
||||
params: { damage: 3 }, kind: "spell", trapped: true, sourceName: "warded treasure",
|
||||
});
|
||||
} else {
|
||||
applyDamage(state, events, taker, 3, "warded treasure", null);
|
||||
@@ -6120,7 +6126,7 @@ function resolveStack(state: GameState, events: GameEvent[]): void {
|
||||
} else if (pipe.damage > 0) {
|
||||
const source = stack.reflectedBase
|
||||
? `${attackId} (reflected)`
|
||||
: attackId ??
|
||||
: attackId ?? stack.sourceName ??
|
||||
(attackingCreature ? `${attackingCreature.kind}'s blow` : `punch from ${attacker.id}`);
|
||||
applyDamage(state, events, defender, pipe.damage, source, attacker.id, pipe.kind);
|
||||
damageDealt = pipe.damage;
|
||||
|
||||
Reference in New Issue
Block a user