The cockpit learns to aim: marked beings, verdict-bearing crosshair

While a targeted card is armed, wizards and creatures standing on
castable ground wear a pulsing ember ring at their feet — drawn behind
the body, only when the walls actually show it, and only when the card
could land on a being (creations still light floor alone). The hover
cue now carries a verdict: gold outline and bright name for what the
cast can reach, cold slate for what stands beyond it. The workshop
poses it all: ?aim=1 arms a pretend cast and ?rival=x,y stands the
Rival wherever the shot needs them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
This commit is contained in:
Eric Wagoner
2026-09-01 11:41:27 -04:00
co-authored by Claude Fable 5
parent afa0e17483
commit b996c2bc93
4 changed files with 64 additions and 7 deletions
+3 -2
View File
@@ -17,7 +17,7 @@
import { onDestroy, untrack } from "svelte";
import type { GameEvent, GameView, Side } from "@wizwar/engine";
let { view, batch, onhide, onstride = null, canStride = false, ontarget = null, onfacing = null, litCells = null, edgeSelect = false, onpickup = null, onCreatureMove = null, onCreatureAttack = null, onbody = null, onWarpStep = null }: {
let { view, batch, onhide, onstride = null, canStride = false, ontarget = null, onfacing = null, litCells = null, aimBeings = false, edgeSelect = false, onpickup = null, onCreatureMove = null, onCreatureAttack = null, onbody = null, onWarpStep = null }: {
view: GameView;
/** The latest live event batch, numbered so each plays once, with
* the view the server sent alongside it. */
@@ -34,6 +34,7 @@
onfacing?: ((side: Side) => void) | null;
/** Cell-card eligibility, shared with the board's dimming aid. */
litCells?: Set<string> | null;
aimBeings?: boolean;
/** An edge-target card is raised: wall faces offer themselves. */
edgeSelect?: boolean;
/** The at-your-feet tray's grab: the pane cannot look down, so what
@@ -470,7 +471,7 @@
<FirstPerson {view} povId={cutawayShot ? "" : (possessedId ?? povId)}
x={cam.x} y={cam.y} facing={cam.facing} width={960} height={400}
fx={fpFx} posOverride={actorPos}
ontarget={handleTarget} {litCells} {edgeSelect} />
ontarget={handleTarget} {litCells} {aimBeings} {edgeSelect} />
<button class="drive" onclick={() => manualTurn(1)} aria-label="turn right"></button>
</div>
<div class="bezel-bottom">