MEGA-MONSTER asks which number to double

The two choices sat in the hint strip with life-points pre-selected,
so a tap on the monster cast before the choice was seen. Tapping the
monster now asks — life-points or movement, with the monster's
current numbers shown — and the cast waits on the answer.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
Eric Wagoner
2026-09-04 17:25:34 -04:00
co-authored by Claude Fable 5.1
parent 9f98a4fc59
commit fa5a5a07a7
+37 -9
View File
@@ -294,7 +294,15 @@
/** pick-lock / master-key: prop the door for others once it opens. */ /** pick-lock / master-key: prop the door for others once it opens. */
let holdDoor = $state(false); let holdDoor = $state(false);
/** mega-monster: which stat the chosen monster doubles. */ /** mega-monster: which stat the chosen monster doubles. */
let megaBoost = $state<"life" | "movement">("life"); /** MEGA-MONSTER aimed at a monster: which of its two numbers to double. */
let megaPrompt = $state<{ instanceId: string; creatureId: string } | null>(null);
function castMega(boost: "life" | "movement") {
const m = megaPrompt;
if (!m) return;
megaPrompt = null;
dispatch(withMods({ type: "cast", instanceId: m.instanceId, target: { kind: "creature", creatureId: m.creatureId }, params: { boost } }));
clearSelection();
}
/** teleport: the marked destination awaiting its confirming second tap. */ /** teleport: the marked destination awaiting its confirming second tap. */
let pendingTeleport = $state<{ x: number; y: number } | null>(null); let pendingTeleport = $state<{ x: number; y: number } | null>(null);
/** Cards marked for discard. */ /** Cards marked for discard. */
@@ -536,7 +544,6 @@
tradeFrom = null; tradeFrom = null;
selectedCreature = null; selectedCreature = null;
selectedCard = null; selectedCard = null;
megaBoost = "life";
holdDoor = false; holdDoor = false;
pickChoice = false; pickChoice = false;
pendingTeleport = null; pendingTeleport = null;
@@ -1054,11 +1061,16 @@
clickCell(creature.position); clickCell(creature.position);
return; return;
} }
if (selectedCard && selectedCard.cardId === "mega-monster") {
// "Doubles the existing life-points OR movement rate": the choice is
// asked, not defaulted — the cast waits on the answer.
megaPrompt = { instanceId: selectedCard.instanceId, creatureId };
return;
}
if (selectedCard && (CREATURE_TARGET_CARDS.has(selectedCard.cardId) || cardDef(selectedCard.cardId).cardType === "attack")) { if (selectedCard && (CREATURE_TARGET_CARDS.has(selectedCard.cardId) || cardDef(selectedCard.cardId).cardType === "attack")) {
dispatch(withMods({ dispatch(withMods({
type: "cast", instanceId: selectedCard.instanceId, type: "cast", instanceId: selectedCard.instanceId,
target: { kind: "creature", creatureId }, target: { kind: "creature", creatureId },
...(selectedCard.cardId === "mega-monster" ? { params: { boost: megaBoost } } : {}),
})); }));
clearSelection(); clearSelection();
return; return;
@@ -1681,6 +1693,27 @@
{/if} {/if}
{/if} {/if}
{#if megaPrompt && view}
{@const beast = view.creatures.find((c) => c.id === megaPrompt!.creatureId)}
<div class="scrim attack-scrim" role="alertdialog" aria-label="mega-monster">
<div class="attack-notice">
<div class="attack-title">Mega-Monster: the {beast ? cardDef(beast.kind).name : "monster"} grows</div>
<div class="attack-power">
"Doubles the existing life-points OR movement rate of any one monster." Which?
{#if beast}
Now {Number.isFinite(beast.maxDamage) ? `${beast.maxDamage - beast.damage} of ${beast.maxDamage} hits` : "unkillable"}
and {beast.movesPerTurn} move{beast.movesPerTurn === 1 ? "" : "s"} a turn.
{/if}
</div>
<div class="attack-actions">
<button class="stamp primary" onclick={() => castMega("life")}>Double its life-points</button>
<button class="stamp primary" onclick={() => castMega("movement")}>Double its movement</button>
<button class="hint-cancel" onclick={() => (megaPrompt = null)}>never mind</button>
</div>
</div>
</div>
{/if}
{#if view?.pushPending && view.pushPending.pusheeId === view.you} {#if view?.pushPending && view.pushPending.pusheeId === view.you}
<div class="scrim attack-scrim" role="alertdialog" aria-label="you are pushed"> <div class="scrim attack-scrim" role="alertdialog" aria-label="you are pushed">
<div class="attack-notice"> <div class="attack-notice">
@@ -2424,12 +2457,7 @@
{/if} {/if}
{/if} {/if}
{#if selectedCard?.cardId === "mega-monster"} {#if selectedCard?.cardId === "mega-monster"}
<span> double its</span> <span> tap the monster, then choose whether to double its life-points or its movement</span>
<button class="stamp tiny" class:lit={megaBoost === "life"}
onclick={() => (megaBoost = "life")}>life-points</button>
<button class="stamp tiny" class:lit={megaBoost === "movement"}
onclick={() => (megaBoost = "movement")}>movement</button>
<span> then tap the monster</span>
{/if} {/if}
{#if selectedCard?.cardId === "pick-lock" || selectedCard?.cardId === "master-key"} {#if selectedCard?.cardId === "pick-lock" || selectedCard?.cardId === "master-key"}
<label class="inline"><input type="checkbox" bind:checked={holdDoor} /> hold the door open</label> <label class="inline"><input type="checkbox" bind:checked={holdDoor} /> hold the door open</label>