diff --git a/packages/web/src/LiveFirstPerson.svelte b/packages/web/src/LiveFirstPerson.svelte index 1841c7f..e556119 100644 --- a/packages/web/src/LiveFirstPerson.svelte +++ b/packages/web/src/LiveFirstPerson.svelte @@ -113,6 +113,27 @@ cam.x = mx; cam.y = my; cam.facing = face; }); + /** Bodies sharing the active eyes' square: inside the near plane, so + * the renderer cannot show them — the tray stands in for the sprite, + * and clicking routes exactly as clicking the sprite would. */ + const withYou = $derived.by(() => { + const body = possessed ?? me; + if (!body || !canStride) return []; + const bx = body.position.x, by = body.position.y; + const items: { kind: "player" | "creature"; id: string; art: string; label: string }[] = []; + for (const p of view.players) { + if (!p.alive || p.id === view.you) continue; + if (p.position.x !== bx || p.position.y !== by) continue; + items.push({ kind: "player", id: p.id, art: tokenArt(`wizard-${p.colorIndex}`, "players"), label: p.id }); + } + for (const c of view.creatures) { + if (c.id === possessedId) continue; + if (c.position.x !== bx || c.position.y !== by) continue; + items.push({ kind: "creature", id: c.id, art: tokenArt(c.kind, "creatures"), label: c.kind.replace(/-/g, " ") }); + } + return items; + }); + const cam = $state({ x: 0, y: 0, facing: 0 }); let camReady = false; /** While the player steers, the director keeps its hands off the @@ -409,6 +430,17 @@ {/each} {/if} + {#if withYou.length > 0} +