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">
|
<script lang="ts">
|
||||||
import Board from "./Board.svelte";
|
import Board from "./Board.svelte";
|
||||||
import { humanize } from "./net.svelte";
|
import { humanize } from "./net.svelte";
|
||||||
|
import { fxForEvents, fxTtl, type BoardFx } from "./fx";
|
||||||
import type { GameEvent, GameView } from "@wizwar/engine";
|
import type { GameEvent, GameView } from "@wizwar/engine";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -20,6 +21,21 @@
|
|||||||
);
|
);
|
||||||
const atEnd = $derived(idx >= steps.length - 1);
|
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(() => {
|
$effect(() => {
|
||||||
if (!playing) return;
|
if (!playing) return;
|
||||||
const t = setInterval(() => {
|
const t = setInterval(() => {
|
||||||
@@ -47,7 +63,7 @@
|
|||||||
<button class="replay-skip" onclick={onclose}>{atEnd ? "back to the game" : "skip to now"}</button>
|
<button class="replay-skip" onclick={onclose}>{atEnd ? "back to the game" : "skip to now"}</button>
|
||||||
</header>
|
</header>
|
||||||
<div class="replay-board">
|
<div class="replay-board">
|
||||||
<Board view={step.view} />
|
<Board view={step.view} effects={boardFx} />
|
||||||
</div>
|
</div>
|
||||||
<div class="replay-caption">
|
<div class="replay-caption">
|
||||||
<strong>{step.actor}</strong>
|
<strong>{step.actor}</strong>
|
||||||
|
|||||||
Reference in New Issue
Block a user