Flourishes play on the reel too
Replay steps carry the same events the live table saw, so the spells flare on catch-up reels and whole-game replays alike — retroactively: stored games re-derive their events on replay, so every fireball ever thrown bursts again. Step changes clear pending effects so scrubbing backward does not smear. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
bca34ae9e4
commit
70d7b4babb
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import Board from "./Board.svelte";
|
||||
import { humanize } from "./net.svelte";
|
||||
import { fxForEvents, fxTtl, type BoardFx } from "./fx";
|
||||
import type { GameEvent, GameView } from "@wizwar/engine";
|
||||
|
||||
let {
|
||||
@@ -20,6 +21,21 @@
|
||||
);
|
||||
const atEnd = $derived(idx >= steps.length - 1);
|
||||
|
||||
/** Each step's spells flare on the reel exactly as they did at the table. */
|
||||
let boardFx = $state<BoardFx[]>([]);
|
||||
$effect(() => {
|
||||
const step = steps[Math.min(idx, steps.length - 1)];
|
||||
if (!step) return;
|
||||
const timers: ReturnType<typeof setTimeout>[] = [];
|
||||
for (const { fx, delay } of fxForEvents(step.events, step.view)) {
|
||||
timers.push(setTimeout(() => {
|
||||
boardFx = [...boardFx, fx];
|
||||
timers.push(setTimeout(() => (boardFx = boardFx.filter((f) => f.id !== fx.id)), fxTtl(fx.kind)));
|
||||
}, delay));
|
||||
}
|
||||
return () => { timers.forEach(clearTimeout); boardFx = []; };
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (!playing) return;
|
||||
const t = setInterval(() => {
|
||||
@@ -47,7 +63,7 @@
|
||||
<button class="replay-skip" onclick={onclose}>{atEnd ? "back to the game" : "skip to now"}</button>
|
||||
</header>
|
||||
<div class="replay-board">
|
||||
<Board view={step.view} />
|
||||
<Board view={step.view} effects={boardFx} />
|
||||
</div>
|
||||
<div class="replay-caption">
|
||||
<strong>{step.actor}</strong>
|
||||
|
||||
Reference in New Issue
Block a user