The full telepath audit: every private glimpse held up, every silence voiced
A sweep of all 142 engine events against the client found three more telepath-class drops and eight silent chronicle gaps. THOUGHT STEAL's plunder and a kill's hand-spoils now get the reveal modal (generalized from the mind-read one — title, note, the cards fanned out); your own end-of-turn draw names its cards in the log. The mute events speak: dispels, walls of fire rising/burning/guttering, filled squares, crashing waterwalls, clattering thrown objects, and REUSE SPELL's retrieval. Also verified clean: every param-taking card has collection UI, and every cell/edge-targeting card is aimable on the board. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
6165d43639
commit
813f92d419
+33
-12
@@ -54,9 +54,10 @@
|
||||
let trapNotice = $state<string | null>(null);
|
||||
/** A Ward sprung on YOU earns the same courtesy. */
|
||||
let wardBite = $state<{ owner: string; amount: number } | null>(null);
|
||||
/** A mind YOU read: the stolen glimpse arrives once, in an event — hold
|
||||
* it up until dismissed, or it is lost to the scrollback. */
|
||||
let mindRead = $state<{ player: string; cards: CardInstance[] } | null>(null);
|
||||
/** Cards revealed to YOU alone (a read mind, plunder, spoils): the
|
||||
* glimpse arrives once, in an event — hold it up until dismissed, or it
|
||||
* is lost to the scrollback. */
|
||||
let cardReveal = $state<{ title: string; note: string; cards: CardInstance[] } | null>(null);
|
||||
/** An easy-to-regret play awaiting its "are you sure?" (see prefs.cautions). */
|
||||
let caution = $state<{ reasons: string[]; go: () => void } | null>(null);
|
||||
function withCaution(reasons: string[], go: () => void) {
|
||||
@@ -96,7 +97,27 @@
|
||||
for (const e of events) {
|
||||
if (e.type === "trapSprung" && e.player === view.you && e.cardId) trapNotice = e.cardId;
|
||||
if (e.type === "handRevealedPrivate" && e.visibleTo === view.you) {
|
||||
mindRead = { player: e.player, cards: e.cards };
|
||||
cardReveal = {
|
||||
title: `${e.player}'s mind, laid bare`,
|
||||
note: "Commit them to memory — the glimpse does not linger.",
|
||||
cards: e.cards,
|
||||
};
|
||||
}
|
||||
if (e.type === "cardsStolenPrivate" && e.visibleTo === view.you) {
|
||||
const pub = events.find((s) => s.type === "cardsStolen" && s.to === view!.you);
|
||||
cardReveal = {
|
||||
title: pub?.type === "cardsStolen" ? `Plucked from ${pub.from}'s thoughts` : "Plucked from their thoughts",
|
||||
note: "Yours now — already in your hand.",
|
||||
cards: e.cards,
|
||||
};
|
||||
}
|
||||
if (e.type === "handTakenPrivate" && e.visibleTo === view.you) {
|
||||
const pub = events.find((s) => s.type === "handTaken" && s.to === view!.you);
|
||||
cardReveal = {
|
||||
title: pub?.type === "handTaken" ? `The spoils of ${pub.from}` : "The spoils",
|
||||
note: "The fallen wizard's hand — already in yours.",
|
||||
cards: e.cards,
|
||||
};
|
||||
}
|
||||
if (e.type === "wardSprung" && e.victim === view.you) {
|
||||
const dmg = events.find((d) => d.type === "damaged" && d.player === e.victim && d.source === "warded treasure");
|
||||
@@ -1444,24 +1465,24 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if mindRead}
|
||||
<div class="scrim attack-scrim" role="alertdialog" aria-label="a mind read">
|
||||
{#if cardReveal}
|
||||
<div class="scrim attack-scrim" role="alertdialog" aria-label="cards revealed to you">
|
||||
<div class="attack-notice mind-read">
|
||||
<div class="attack-headline">{mindRead.player}'s mind, laid bare</div>
|
||||
<div class="attack-headline">{cardReveal.title}</div>
|
||||
<div class="mind-cards">
|
||||
{#each mindRead.cards as card (card.instanceId)}
|
||||
{#each cardReveal.cards as card (card.instanceId)}
|
||||
<Card {card} onfaq={(id) => (faqCardId = id)} />
|
||||
{/each}
|
||||
{#if mindRead.cards.length === 0}
|
||||
{#if cardReveal.cards.length === 0}
|
||||
<div class="attack-power">Nothing — their thoughts are empty-handed.</div>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="attack-power">
|
||||
{mindRead.cards.length > 0
|
||||
? `${mindRead.cards.length} card${mindRead.cards.length === 1 ? "" : "s"} — commit them to memory; the glimpse does not linger.`
|
||||
{cardReveal.cards.length > 0
|
||||
? `${cardReveal.cards.length} card${cardReveal.cards.length === 1 ? "" : "s"} — ${cardReveal.note}`
|
||||
: ""}
|
||||
</div>
|
||||
<button class="stamp big" onclick={() => (mindRead = null)}>Enough</button>
|
||||
<button class="stamp big" onclick={() => (cardReveal = null)}>Enough</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -88,6 +88,17 @@ export function humanize(e: GameEvent): string | null {
|
||||
: `${e.player} wasn't holding that card — the erasure fizzles.`;
|
||||
case "cardsStolen": return `${e.to} steals ${e.count} card(s) from ${e.from}'s thoughts!`;
|
||||
case "handRevealed": return `${e.to} reads ${e.player}'s mind — their hand is revealed.`;
|
||||
case "cardsDrawnPrivate": return e.cards.length > 0
|
||||
? `You draw ${e.cards.map((c) => cardDef(c.cardId).name).join(", ")}.`
|
||||
: null;
|
||||
case "creationDispelled": return `The ${e.what.replace(/-/g, " ")} unravels — dispelled!`;
|
||||
case "firewallCreated": return `A wall of fire roars up (${e.turns} turn${e.turns === 1 ? "" : "s"})!`;
|
||||
case "firewallExpired": return `The wall of fire gutters out.`;
|
||||
case "firewallBurned": return `${e.player} steps through the flames!`;
|
||||
case "squareFilled": return `The square fills with ${e.kind === "stone" ? "solid stone" : e.kind === "slime" ? "green slime" : e.kind.replace(/-/g, " ")}!`;
|
||||
case "waterwallCrashes": return `A wall of water crashes down!`;
|
||||
case "objectThrown": return `The ${cardDef(e.cardId).name.toLowerCase()} clatters to the floor.`;
|
||||
case "spellReused": return `${e.player}'s ${cardDef(e.card.cardId).name} leaps back to their hand!`;
|
||||
case "doorUnlocked": return `${e.player} unlocks a door.`;
|
||||
case "doorHeld": return `${e.player} holds the door open.`;
|
||||
case "doorReleased": return `The held door swings shut.`;
|
||||
|
||||
Reference in New Issue
Block a user