Slow Death's draw is one blow, countered against its total (table ruling)
Two cards drawn is a two-point blow: ABSORB soaks up to three of the total, BLUNT halves it rounding up (so it finally earns a place — 2 becomes 1), counters may chain, declining takes the rest. The client labels each counter with the exact points it leaves; the bots weigh the total against their floor. Amends rev 13 minutes after it shipped; every production ledger still replays clean. 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
92613d7386
commit
8cfd911a3e
@@ -1563,23 +1563,29 @@
|
||||
{/if}
|
||||
|
||||
{#if view?.slowDeathPending && view.slowDeathPending.playerId === view.you}
|
||||
{@const sdAbsorbs = view.yourHand.filter((c) => c.cardId === "absorb")}
|
||||
{@const sdPoints = view.slowDeathPending.points}
|
||||
{@const sdAbsorb = view.yourHand.find((c) => c.cardId === "absorb")}
|
||||
{@const sdBlunt = view.yourHand.find((c) => c.cardId === "blunt")}
|
||||
<div class="scrim attack-scrim" role="alertdialog" aria-label="slow death bites">
|
||||
<div class="attack-notice">
|
||||
<div class="attack-title">Slow Death bites for {view.slowDeathPending.points}!</div>
|
||||
<div class="attack-title">Slow Death bites for {sdPoints}!</div>
|
||||
<div class="attack-power">
|
||||
"ABSORB against SLOW DEATH will only stop the damage incurred by
|
||||
one card" — each Absorb you spend soaks exactly one point.
|
||||
The draw's bites land as one blow — counter the total: Absorb
|
||||
soaks up to three points, Blunt halves it (fractions round up).
|
||||
</div>
|
||||
<div class="attack-actions">
|
||||
{#if sdAbsorbs.length > 0}
|
||||
{@const firstAbsorb = sdAbsorbs[0]!}
|
||||
{#if sdAbsorb}
|
||||
<button class="stamp primary"
|
||||
onclick={() => dispatch({ type: "slowDeathChoice", absorbInstanceId: firstAbsorb.instanceId })}>
|
||||
Absorb a point ({sdAbsorbs.length} in hand)</button>
|
||||
onclick={() => dispatch({ type: "slowDeathChoice", counterInstanceId: sdAbsorb.instanceId })}>
|
||||
Absorb — take {Math.max(0, sdPoints - 3)} instead</button>
|
||||
{/if}
|
||||
{#if sdBlunt}
|
||||
<button class="stamp" disabled={Math.ceil(sdPoints / 2) >= sdPoints}
|
||||
onclick={() => dispatch({ type: "slowDeathChoice", counterInstanceId: sdBlunt.instanceId })}>
|
||||
Blunt — take {Math.ceil(sdPoints / 2)} instead</button>
|
||||
{/if}
|
||||
<button class="hint-cancel" onclick={() => dispatch({ type: "slowDeathChoice" })}>
|
||||
take {view.slowDeathPending.points === 1 ? "the point" : `all ${view.slowDeathPending.points}`}</button>
|
||||
take {sdPoints === 1 ? "the point" : `all ${sdPoints}`}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -82,8 +82,8 @@ export function humanize(e: GameEvent): string | null {
|
||||
case "safeOpened": return `${e.player}'s ${cardDef(e.withCardId).name} clicks the safe open — until turn's end.`;
|
||||
case "safeDamaged": return `${e.attacker} batters the safe — ${e.amount} damage (${e.total}/15).`;
|
||||
case "safeSmashed": return `💥 The safe BURSTS open under ${e.attacker}'s assault!`;
|
||||
case "slowDeathWindow": return `Slow Death bites ${e.player} for ${e.points} — an Absorb hovers over the wound…`;
|
||||
case "slowDeathAbsorbed": return `${e.player}'s Absorb soaks one point of the rot (${e.remaining} to go).`;
|
||||
case "slowDeathWindow": return `Slow Death bites ${e.player} for ${e.points} — a counter hovers over the wound…`;
|
||||
case "slowDeathCountered": return `${e.player}'s ${cardDef(e.cardId).name} blunts the rot — ${e.remaining} point${e.remaining === 1 ? "" : "s"} still coming.`;
|
||||
case "spellSustained": return `${spellName(e.cardId)} settles over ${e.target} (${e.turns} turn${e.turns === 1 ? "" : "s"}).`;
|
||||
case "spellExpired": return `${spellName(e.cardId)} wears off ${e.target}.`;
|
||||
case "teleported": return e.by === e.player
|
||||
|
||||
Reference in New Issue
Block a user