Flourishes: the spells become visible (branch only — not for the droplet yet)
A cosmetic effects layer on the board svg, fed by the same event stream that writes the log. Fireballs streak and burst; waterbolts arc and splash; lightning jags and flickers; teleports shimmer at both ends; walls rise and fall in dust; stopped attacks flash a golden shield; hits ring red; misses whiff; other attack spells sparkle at the caster. Successive visuals from one command stagger by a beat, everything self-expires, reduced-motion hides the layer whole, and nothing here touches game state — the effects are mapped from events in fx.ts and drawn in Board.svelte, online and hotseat alike. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
b01e27c644
commit
bca34ae9e4
@@ -6,6 +6,7 @@
|
||||
import Card from "./Card.svelte";
|
||||
import Help from "./Help.svelte";
|
||||
import Replay from "./Replay.svelte";
|
||||
import { fxForEvents, fxTtl, type BoardFx } from "./fx";
|
||||
import { local } from "./local.svelte";
|
||||
import { allCardDefs, cardDef, isNumberCard, SIDES, stepTarget, cellKey, isMovableObject, sightedCellsFor, type GameView, eligibleCellsFor } from "@wizwar/engine";
|
||||
import type { CardInstance, Side } from "@wizwar/engine";
|
||||
@@ -27,6 +28,22 @@
|
||||
}
|
||||
/** Which pending attack the player has already acknowledged (modal dismissed). */
|
||||
let attackNoticeSeen = $state<string | null>(null);
|
||||
/** Live spell flourishes on the board (cosmetic, self-expiring). */
|
||||
let boardFx = $state<BoardFx[]>([]);
|
||||
function playFx(events: Parameters<typeof fxForEvents>[0]) {
|
||||
if (!view) return;
|
||||
for (const { fx, delay } of fxForEvents(events, view)) {
|
||||
setTimeout(() => {
|
||||
boardFx = [...boardFx, fx];
|
||||
setTimeout(() => (boardFx = boardFx.filter((f) => f.id !== fx.id)), fxTtl(fx.kind));
|
||||
}, delay);
|
||||
}
|
||||
}
|
||||
$effect(() => {
|
||||
net.onFx = playFx;
|
||||
local.onFx = playFx;
|
||||
return () => { net.onFx = null; local.onFx = null; };
|
||||
});
|
||||
const openingRolls = $derived(net.openingRolls ?? local.openingRolls);
|
||||
function dismissRolls() {
|
||||
net.openingRolls = null;
|
||||
@@ -1251,6 +1268,7 @@
|
||||
onWarpClick={clickWarp}
|
||||
markedCell={tradeFrom ?? pendingTeleport}
|
||||
markedCells={trapCells.length > 0 ? trapCells : null}
|
||||
effects={boardFx}
|
||||
markedSector={pendingSectorOrigin}
|
||||
ghostSlots={relocateGhosts}
|
||||
onGhostClick={clickGhostSlot}
|
||||
|
||||
Reference in New Issue
Block a user