Crowded squares: every token type gets its own zone, multiples fan out
A square can legally hold terrain, a wizard or three, two treasures (the win condition itself), floor objects, creatures, a warp token, and a boobytrap disc all at once. The cell is now zoned: terrain underlays the whole square, wizards fan across the top, treasures fan across the bottom, floor objects stack bottom-left, creatures fan in from the right, the dimensional warp shrinks into the top-left corner, and boobytrap discs sit top-right. Two treasures on a home base — the winning tableau — now reads as two treasures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bd8ca99dc0
commit
002dbd2547
@@ -150,9 +150,15 @@
|
||||
class="home-star" fill={playerColor(p.id)}
|
||||
/>
|
||||
{/each}
|
||||
{#each view.treasures as t (t.id)}
|
||||
{#each [...view.treasures.reduce((m, t) => {
|
||||
if (!t.position) return m;
|
||||
const k = `${t.position.x},${t.position.y}`;
|
||||
m.set(k, [...(m.get(k) ?? []), t]);
|
||||
return m;
|
||||
}, new Map()).entries()] as [tKey, group] (tKey)}
|
||||
{#each group as t, ti (t.id)}
|
||||
{#if t.position}
|
||||
{@const tx = t.position.x * CELL + CELL / 2}
|
||||
{@const tx = t.position.x * CELL + CELL / 2 + (group.length > 1 ? (ti - (group.length - 1) / 2) * CELL * 0.3 : 0)}
|
||||
{@const ty = t.position.y * CELL + CELL * 0.72}
|
||||
{#if USE_TOKEN_ART}
|
||||
<image
|
||||
@@ -171,6 +177,7 @@
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
{/each}
|
||||
|
||||
<!-- terrain: solid stone and thornbushes -->
|
||||
{#each Object.entries(view.squareContents) as [key, content] (key)}
|
||||
@@ -209,8 +216,8 @@
|
||||
{#if USE_TOKEN_ART}
|
||||
<image
|
||||
href="/tokens/dimensional-warp.png"
|
||||
x={tok.x * CELL + CELL * 0.16} y={tok.y * CELL + CELL * 0.16}
|
||||
width={CELL * 0.68} height={CELL * 0.68}
|
||||
x={tok.x * CELL + CELL * 0.04} y={tok.y * CELL + CELL * 0.04}
|
||||
width={CELL * 0.44} height={CELL * 0.44}
|
||||
preserveAspectRatio="xMidYMid slice" class="token-art"
|
||||
/>
|
||||
{:else}
|
||||
@@ -223,7 +230,7 @@
|
||||
<!-- boobytrap tokens: face-down for everyone (the caster knows the real one) -->
|
||||
{#each view.boobytraps as trap, ti (ti)}
|
||||
{#each trap.cells as tc, i (i)}
|
||||
<circle cx={tc.x * CELL + CELL * 0.26} cy={tc.y * CELL + CELL * 0.26} r="6"
|
||||
<circle cx={tc.x * CELL + CELL * 0.82} cy={tc.y * CELL + CELL * 0.18} r="6"
|
||||
class="trap-token" class:trap-real={trap.realCell != null && tc.x === trap.realCell.x && tc.y === trap.realCell.y} />
|
||||
{/each}
|
||||
{/each}
|
||||
@@ -353,9 +360,14 @@
|
||||
{/each}
|
||||
{/each}
|
||||
|
||||
<!-- creatures -->
|
||||
{#each view.creatures as c (c.id)}
|
||||
{@const ccx = c.position.x * CELL + CELL * 0.72}
|
||||
<!-- creatures (fanned when several share a square) -->
|
||||
{#each [...view.creatures.reduce((m, c) => {
|
||||
const k = `${c.position.x},${c.position.y}`;
|
||||
m.set(k, [...(m.get(k) ?? []), c]);
|
||||
return m;
|
||||
}, new Map()).entries()] as [cKey, cGroup] (cKey)}
|
||||
{#each cGroup as c, ci (c.id)}
|
||||
{@const ccx = c.position.x * CELL + CELL * 0.72 - (cGroup.length > 1 ? ci * CELL * 0.26 : 0)}
|
||||
{@const ccy = c.position.y * CELL + CELL * 0.7}
|
||||
<g
|
||||
role="button" tabindex="-1" class="creature"
|
||||
@@ -394,6 +406,7 @@
|
||||
{/if}
|
||||
</g>
|
||||
{/each}
|
||||
{/each}
|
||||
|
||||
<!-- edge selection hitboxes -->
|
||||
{#each edgeHitboxes as h (`${h.cell.x},${h.cell.y},${h.side}`)}
|
||||
|
||||
Reference in New Issue
Block a user