import { useEffect, useState } from 'react' import type { CSSProperties } from 'react' // How long the dice scramble before settling, and how fast the faces flicker // while they do. ROLL_MS is shared with BattlePhase so damage lands exactly // when the dice settle. Both are the base (1×) durations; the battle speed // multiplier divides them so the roll keeps pace with the rest of the replay. export const ROLL_MS = 650 const TICK_MS = 70 // DiceRoll shows one rock die per rolled face in fixed slots under the // thrower's side: they shake and flicker through faces in place, then settle // on the values the server actually rolled. Faces carry rock icons (0, 1, or // 2 rocks) — the same die the game uses, not a pip D6. Mount it with a `key` // that changes per rock event so the scramble replays every time. export function DiceRoll({ dice, side, speed = 1, }: { dice: number[] side: 'top' | 'bottom' speed?: number }) { const [display, setDisplay] = useState(dice) const [settled, setSettled] = useState(false) useEffect(() => { const flicker = window.setInterval(() => { setDisplay(dice.map(() => Math.floor(Math.random() * 3))) }, TICK_MS / speed) const stop = window.setTimeout(() => { window.clearInterval(flicker) setDisplay(dice) setSettled(true) }, ROLL_MS / speed) return () => { window.clearInterval(flicker) window.clearTimeout(stop) } // Runs once per mount; the caller remounts (via key) for each new roll. // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return (
{display.map((v, i) => (
{Array.from({ length: v }, (_, r) => ( ))}
))}
) }