ROTATE SECTOR asks which way: the tap marks the sector, a button turns it (UPJE)

The clockwise checkbox sat in the hint strip and defaulted on, so a
sector could spin the way nobody meant. The turn is now its own decision,
in the dock beside the board like the teleport confirm.

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-24 20:30:37 -04:00
co-authored by Claude Fable 5.1
parent 6c29f750fc
commit 991a6a0443
+33 -14
View File
@@ -379,8 +379,9 @@
let trapCells = $state<{ x: number; y: number }[]>([]); let trapCells = $state<{ x: number; y: number }[]>([]);
/** trader: first item square picked. */ /** trader: first item square picked. */
let tradeFrom = $state<{ x: number; y: number } | null>(null); let tradeFrom = $state<{ x: number; y: number } | null>(null);
/** rotate-sector direction. */ /** ROTATE SECTOR: the square tapped first marks the sector; the turn is
let rotateCW = $state(true); * chosen by its own button, so no sector spins the way nobody meant. */
let pendingRotate = $state<{ x: number; y: number } | null>(null);
/** 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 aimed at a monster: which of its two numbers to double. */ /** MEGA-MONSTER aimed at a monster: which of its two numbers to double. */
@@ -435,13 +436,12 @@
: null, : null,
); );
/** The 5x5 sector a picked-up square belongs to (its origin), or null. */ /** The 5x5 sector a picked-up or marked square belongs to (its origin), or null. */
const pendingSectorOrigin = $derived.by(() => { const pendingSectorOrigin = $derived.by(() => {
if (!view || !pendingSectorFrom) return null; const at = pendingSectorFrom ?? pendingRotate;
if (!view || !at) return null;
const p = view.board.placements.find( const p = view.board.placements.find(
(p) => (p) => at.x >= p.origin.x && at.x < p.origin.x + 5 && at.y >= p.origin.y && at.y < p.origin.y + 5,
pendingSectorFrom!.x >= p.origin.x && pendingSectorFrom!.x < p.origin.x + 5 &&
pendingSectorFrom!.y >= p.origin.y && pendingSectorFrom!.y < p.origin.y + 5,
); );
return p ? p.origin : null; return p ? p.origin : null;
}); });
@@ -475,6 +475,15 @@
return out; return out;
}); });
function rotateSector(clockwise: boolean) {
if (!selectedCard || !pendingRotate) return;
dispatch({
type: "cast", instanceId: selectedCard.instanceId,
target: { kind: "cell", cell: pendingRotate }, params: { clockwise },
});
clearSelection();
}
function confirmTeleport() { function confirmTeleport() {
if (!selectedCard || !pendingTeleport) return; if (!selectedCard || !pendingTeleport) return;
dispatch({ dispatch({
@@ -634,6 +643,9 @@
? "Tap the marked square again to jump · or pick another" ? "Tap the marked square again to jump · or pick another"
: "Choose a destination · lit squares are within 4 · ends your movement"; : "Choose a destination · lit squares are within 4 · ends your movement";
if (id === "mental-force") return "Choose the wizard, then where they go · within 3 walked squares"; if (id === "mental-force") return "Choose the wizard, then where they go · within 3 walked squares";
if (id === "rotate-sector") return pendingRotate
? "The marked sector turns · choose which way, or tap another sector"
: "Tap a square in the sector to turn · then choose which way";
if (EDGE_CARDS.has(id)) return "Tap a wall line · lit lines are legal"; if (EDGE_CARDS.has(id)) return "Tap a wall line · lit lines are legal";
if (cellSelectMode) return "Choose a square · lit squares are legal targets"; if (cellSelectMode) return "Choose a square · lit squares are legal targets";
if (selectedDef.cardType === "attack") return selectedDef.adjacent if (selectedDef.cardType === "attack") return selectedDef.adjacent
@@ -666,6 +678,7 @@
holdDoor = false; holdDoor = false;
pickChoice = false; pickChoice = false;
pendingTeleport = null; pendingTeleport = null;
pendingRotate = null;
attachedNumber = null; attachedNumber = null;
attachedMods = []; attachedMods = [];
wbDamage = 0; wbDamage = 0;
@@ -973,11 +986,8 @@
return; return;
} }
if (selectedCard?.cardId === "rotate-sector") { if (selectedCard?.cardId === "rotate-sector") {
dispatch({ // The tap marks the sector; the way it turns is the next decision.
type: "cast", instanceId: selectedCard.instanceId, pendingRotate = cell;
target: { kind: "cell", cell }, params: { clockwise: rotateCW },
});
clearSelection();
return; return;
} }
if (selectedCard && CELL_CARDS.has(selectedCard.cardId)) { if (selectedCard && CELL_CARDS.has(selectedCard.cardId)) {
@@ -3008,8 +3018,13 @@
<button class="stamp tiny" onclick={castSelfWithNumber}>Display the key</button> <button class="stamp tiny" onclick={castSelfWithNumber}>Display the key</button>
{/if} {/if}
{#if selectedCard?.cardId === "rotate-sector"} {#if selectedCard?.cardId === "rotate-sector"}
<label class="inline"><input type="checkbox" bind:checked={rotateCW} /> clockwise</label> {#if pendingRotate}
<span>— click the sector</span> <span>— the marked sector turns a quarter</span>
<button class="stamp tiny" onclick={() => rotateSector(true)}>↻ clockwise</button>
<button class="stamp tiny" onclick={() => rotateSector(false)}>↺ counter-clockwise</button>
{:else}
<span>— tap a square in the sector to turn</span>
{/if}
{/if} {/if}
{#if selectedCard?.cardId === "relocate-sector"} {#if selectedCard?.cardId === "relocate-sector"}
<span>{pendingSectorFrom <span>{pendingSectorFrom
@@ -3567,6 +3582,10 @@
{#if selectedCard?.cardId === "teleport" && pendingTeleport} {#if selectedCard?.cardId === "teleport" && pendingTeleport}
<button class="stamp tiny primary" onclick={confirmTeleport}>teleport!</button> <button class="stamp tiny primary" onclick={confirmTeleport}>teleport!</button>
{/if} {/if}
{#if selectedCard?.cardId === "rotate-sector" && pendingRotate}
<button class="stamp tiny primary" onclick={() => rotateSector(true)}>↻ clockwise</button>
<button class="stamp tiny primary" onclick={() => rotateSector(false)}>↺ counter-clockwise</button>
{/if}
{#if selectedCard && isNumberCard(selectedCard.cardId)} {#if selectedCard && isNumberCard(selectedCard.cardId)}
{@const needsAdd = view.turn.numberPlayedForMovement} {@const needsAdd = view.turn.numberPlayedForMovement}
{@const haveAdd = view.yourHand.some((c) => c.cardId === "add")} {@const haveAdd = view.yourHand.some((c) => c.cardId === "add")}