diff --git a/packages/engine/src/game.ts b/packages/engine/src/game.ts index 1c33f5f..a2e7ef3 100644 --- a/packages/engine/src/game.ts +++ b/packages/engine/src/game.ts @@ -602,7 +602,7 @@ export type GameEvent = | { type: "cardDisplayed"; player: PlayerId; card: CardInstance } | { type: "extraTurnGranted"; player: PlayerId } | { type: "lifeTraded"; player: PlayerId; points: number; newAllowance: number } - | { type: "trapSprung"; player: PlayerId } + | { type: "trapSprung"; player: PlayerId; cardId?: string } | { type: "died"; player: PlayerId; killedBy: PlayerId | null } | { type: "handTaken"; from: PlayerId; to: PlayerId; count: number } | { type: "handTakenPrivate"; visibleTo: PlayerId; cards: CardInstance[] } @@ -5639,13 +5639,13 @@ function doEndTurn(prev: GameState, draw: number): CommandResult { if (isTrap(card.cardId)) { state.discard.push(card); p.lostTurns++; - events.push({ type: "trapSprung", player: p.id }); + events.push({ type: "trapSprung", player: p.id, cardId: card.cardId }); continue; } if (card.cardId === "gift-from-below") { // "You lose 3 points to magical damage, now ... then discard and redraw." state.discard.push(card); - events.push({ type: "trapSprung", player: p.id }); + events.push({ type: "trapSprung", player: p.id, cardId: card.cardId }); applyDamage(state, events, p, 3, "gift from below", null); checkVictory(state, events); if (!p.alive) break; diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index cbe1c65..ebd8330 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -47,8 +47,13 @@ /** Live spell flourishes on the board (cosmetic, self-expiring). */ let boardFx = $state([]); let fxCancels: (() => void)[] = []; + /** A trap drawn by YOU earns a modal; buried log lines get missed. */ + let trapNotice = $state(null); function playFx(events: Parameters[0]) { if (!view) return; + for (const e of events) { + if (e.type === "trapSprung" && e.player === view.you && e.cardId) trapNotice = e.cardId; + } fxCancels.push(scheduleFx( events, view, (fx) => (boardFx = [...boardFx, fx]), @@ -1029,6 +1034,21 @@ {/if} + {#if trapNotice} +
+
+
A cruel draw!
+
+
+ {trapNotice === "gift-from-below" + ? "It bites for 3 points, then the deck deals you another." + : "The trap snaps shut — you lose a turn."} +
+ +
+
+ {/if} + {#if view && view.outOfTurnWindow?.playerId === view.you && !momentSeen}
diff --git a/packages/web/src/net.svelte.ts b/packages/web/src/net.svelte.ts index d50430b..86dd701 100644 --- a/packages/web/src/net.svelte.ts +++ b/packages/web/src/net.svelte.ts @@ -57,7 +57,9 @@ export function humanize(e: GameEvent): string | null { case "wallCreated": return `A wall appears!`; case "wallDestroyed": return e.wasDoor ? `A door is blasted to rubble!` : `A wall crumbles!`; case "extraTurnGranted": return `${e.player} speeds up — extra turn banked.`; - case "trapSprung": return `${e.player} walked into an old TRAP! Lose a turn.`; + case "trapSprung": return e.cardId === "gift-from-below" + ? `${e.player} draws GIFT FROM BELOW — it bites for 3, then deals again!` + : `${e.player} walked into an old TRAP! Lose a turn.`; case "attackMissed": return e.because === "invisible" ? `The attack passes through empty air — ${e.defender} is invisible!` : `${e.defender} is too small to hit — the attack misses!`;