diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte
index ac61596..a9e9404 100644
--- a/packages/web/src/App.svelte
+++ b/packages/web/src/App.svelte
@@ -379,8 +379,9 @@
let trapCells = $state<{ x: number; y: number }[]>([]);
/** trader: first item square picked. */
let tradeFrom = $state<{ x: number; y: number } | null>(null);
- /** rotate-sector direction. */
- let rotateCW = $state(true);
+ /** ROTATE SECTOR: the square tapped first marks the sector; the turn is
+ * 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. */
let holdDoor = $state(false);
/** MEGA-MONSTER aimed at a monster: which of its two numbers to double. */
@@ -435,13 +436,12 @@
: 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(() => {
- if (!view || !pendingSectorFrom) return null;
+ const at = pendingSectorFrom ?? pendingRotate;
+ if (!view || !at) return null;
const p = view.board.placements.find(
- (p) =>
- pendingSectorFrom!.x >= p.origin.x && pendingSectorFrom!.x < p.origin.x + 5 &&
- pendingSectorFrom!.y >= p.origin.y && pendingSectorFrom!.y < p.origin.y + 5,
+ (p) => at.x >= p.origin.x && at.x < p.origin.x + 5 && at.y >= p.origin.y && at.y < p.origin.y + 5,
);
return p ? p.origin : null;
});
@@ -475,6 +475,15 @@
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() {
if (!selectedCard || !pendingTeleport) return;
dispatch({
@@ -634,6 +643,9 @@
? "Tap the marked square again to jump · or pick another"
: "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 === "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 (cellSelectMode) return "Choose a square · lit squares are legal targets";
if (selectedDef.cardType === "attack") return selectedDef.adjacent
@@ -666,6 +678,7 @@
holdDoor = false;
pickChoice = false;
pendingTeleport = null;
+ pendingRotate = null;
attachedNumber = null;
attachedMods = [];
wbDamage = 0;
@@ -973,11 +986,8 @@
return;
}
if (selectedCard?.cardId === "rotate-sector") {
- dispatch({
- type: "cast", instanceId: selectedCard.instanceId,
- target: { kind: "cell", cell }, params: { clockwise: rotateCW },
- });
- clearSelection();
+ // The tap marks the sector; the way it turns is the next decision.
+ pendingRotate = cell;
return;
}
if (selectedCard && CELL_CARDS.has(selectedCard.cardId)) {
@@ -3008,8 +3018,13 @@
{/if}
{#if selectedCard?.cardId === "rotate-sector"}
-
- — click the sector
+ {#if pendingRotate}
+ — the marked sector turns a quarter
+
+
+ {:else}
+ — tap a square in the sector to turn
+ {/if}
{/if}
{#if selectedCard?.cardId === "relocate-sector"}
{pendingSectorFrom
@@ -3567,6 +3582,10 @@
{#if selectedCard?.cardId === "teleport" && pendingTeleport}
{/if}
+ {#if selectedCard?.cardId === "rotate-sector" && pendingRotate}
+
+
+ {/if}
{#if selectedCard && isNumberCard(selectedCard.cardId)}
{@const needsAdd = view.turn.numberPlayedForMovement}
{@const haveAdd = view.yourHand.some((c) => c.cardId === "add")}