Make wraparound warps usable: click the arrow to step through
The engine's warps worked all along (verified in all six directions), but the client offered no way to trigger one short of clicking the destination cell across the map. The warp arrows are now buttons: when you stand on an opening its arrow lights green — click it to step through. Clicking a far arrow behaves as a click on its cell. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
3e1fe059fa
commit
87a5067c77
@@ -263,6 +263,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clickWarp(cell: { x: number; y: number }, side: Side) {
|
||||||
|
if (!view || !isYourTurn || !me) return;
|
||||||
|
// Standing on the opening: step through. Otherwise treat it as a cell
|
||||||
|
// click on the opening square (e.g. to walk toward it).
|
||||||
|
if (me.position.x === cell.x && me.position.y === cell.y) {
|
||||||
|
net.command({ type: "move", direction: side });
|
||||||
|
} else {
|
||||||
|
clickCell(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function clickEdge(cell: { x: number; y: number }, side: Side) {
|
function clickEdge(cell: { x: number; y: number }, side: Side) {
|
||||||
if (!selectedCard || !edgeSelectMode) return;
|
if (!selectedCard || !edgeSelectMode) return;
|
||||||
net.command({
|
net.command({
|
||||||
@@ -453,6 +464,7 @@
|
|||||||
onEdgeClick={clickEdge}
|
onEdgeClick={clickEdge}
|
||||||
onPlayerClick={clickPlayer}
|
onPlayerClick={clickPlayer}
|
||||||
onCreatureClick={clickCreature}
|
onCreatureClick={clickCreature}
|
||||||
|
onWarpClick={clickWarp}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
onEdgeClick,
|
onEdgeClick,
|
||||||
onPlayerClick,
|
onPlayerClick,
|
||||||
onCreatureClick,
|
onCreatureClick,
|
||||||
|
onWarpClick,
|
||||||
}: {
|
}: {
|
||||||
view: GameView;
|
view: GameView;
|
||||||
edgeSelectMode?: boolean;
|
edgeSelectMode?: boolean;
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
onEdgeClick?: (cell: { x: number; y: number }, side: Side) => void;
|
onEdgeClick?: (cell: { x: number; y: number }, side: Side) => void;
|
||||||
onPlayerClick?: (playerId: string) => void;
|
onPlayerClick?: (playerId: string) => void;
|
||||||
onCreatureClick?: (creatureId: string) => void;
|
onCreatureClick?: (creatureId: string) => void;
|
||||||
|
onWarpClick?: (cell: { x: number; y: number }, side: Side) => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
const PLAYER_COLORS = ["#1a9c46", "#d3352b", "#c9308f", "#3a3ac0", "#2ab0c9", "#c9a72a"];
|
const PLAYER_COLORS = ["#1a9c46", "#d3352b", "#c9308f", "#3a3ac0", "#2ab0c9", "#c9a72a"];
|
||||||
@@ -199,15 +201,24 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<!-- warp openings -->
|
<!-- warp openings: click the arrow (while standing on it) to step through -->
|
||||||
{#each view.board.warps as w, i (i)}
|
{#each view.board.warps as w, i (i)}
|
||||||
<text
|
{@const wx = w.from.cell.x * CELL + CELL / 2 +
|
||||||
x={w.from.cell.x * CELL + CELL / 2 +
|
(w.from.side === "E" ? CELL * 0.42 : w.from.side === "W" ? -CELL * 0.42 : 0)}
|
||||||
(w.from.side === "E" ? CELL * 0.42 : w.from.side === "W" ? -CELL * 0.42 : 0)}
|
{@const wy = w.from.cell.y * CELL + CELL / 2 +
|
||||||
y={w.from.cell.y * CELL + CELL / 2 + 3 +
|
(w.from.side === "S" ? CELL * 0.42 : w.from.side === "N" ? -CELL * 0.42 : 0)}
|
||||||
(w.from.side === "S" ? CELL * 0.42 : w.from.side === "N" ? -CELL * 0.42 : 0)}
|
{@const standing = view.players.some((p) =>
|
||||||
class="warp"
|
p.id === view.you && p.position.x === w.from.cell.x && p.position.y === w.from.cell.y)}
|
||||||
>{w.from.side === "N" ? "↑" : w.from.side === "S" ? "↓" : w.from.side === "E" ? "→" : "←"}</text>
|
<g
|
||||||
|
class="warp-g" class:standing
|
||||||
|
role="button" tabindex="-1"
|
||||||
|
onclick={(ev) => { ev.stopPropagation(); onWarpClick?.(w.from.cell, w.from.side); }}
|
||||||
|
onkeydown={() => {}}
|
||||||
|
>
|
||||||
|
<circle cx={wx} cy={wy} r={11} class="warp-hit" />
|
||||||
|
<text x={wx} y={wy + 4.5} class="warp"
|
||||||
|
>{w.from.side === "N" ? "↑" : w.from.side === "S" ? "↓" : w.from.side === "E" ? "→" : "←"}</text>
|
||||||
|
</g>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<!-- wizards -->
|
<!-- wizards -->
|
||||||
@@ -321,7 +332,16 @@
|
|||||||
.treasure { stroke: #2b2218; stroke-width: 1.3; }
|
.treasure { stroke: #2b2218; stroke-width: 1.3; }
|
||||||
.treasure-swirl { fill: none; stroke: #2b2218; stroke-width: 1.2; stroke-dasharray: 5 2.2; }
|
.treasure-swirl { fill: none; stroke: #2b2218; stroke-width: 1.2; stroke-dasharray: 5 2.2; }
|
||||||
.treasure-core { fill: #2b2218; }
|
.treasure-core { fill: #2b2218; }
|
||||||
.warp { font-size: 14px; text-anchor: middle; fill: #2b2218; font-weight: bold; opacity: 0.65; }
|
.warp { font-size: 14px; text-anchor: middle; fill: #2b2218; font-weight: bold; opacity: 0.65; pointer-events: none; }
|
||||||
|
.warp-g { cursor: pointer; }
|
||||||
|
.warp-hit { fill: transparent; }
|
||||||
|
.warp-g:hover .warp-hit { fill: rgba(43, 34, 24, 0.12); }
|
||||||
|
.warp-g.standing .warp-hit {
|
||||||
|
fill: rgba(46, 125, 50, 0.25);
|
||||||
|
stroke: #2e7d32;
|
||||||
|
stroke-width: 2;
|
||||||
|
}
|
||||||
|
.warp-g.standing .warp { opacity: 1; }
|
||||||
.wizard { cursor: pointer; }
|
.wizard { cursor: pointer; }
|
||||||
.wizard-label {
|
.wizard-label {
|
||||||
font-family: "Oswald", sans-serif;
|
font-family: "Oswald", sans-serif;
|
||||||
|
|||||||
Reference in New Issue
Block a user