Add 3D dice roll animation for thrown rocks

Emit the individual rock-die faces (0/0/1/1/2/2) from the battle
resolver so the client can render a real CSS 3D cube per die that
tumbles and settles on the rolled face, replacing the flat random
damage number. Falls back to the flying-rock cue for older battle logs
without per-die data.
This commit is contained in:
Greyson Parrelli
2026-07-23 01:01:00 -04:00
parent da00d0fcd7
commit 71fa20493a
5 changed files with 169 additions and 9 deletions
+11 -6
View File
@@ -1,6 +1,7 @@
import { useEffect, useMemo, useState } from 'react'
import type { BattleEvent, Card, ClientMessage, GameView } from '../types'
import { CardView } from './CardView'
import { DiceTray } from './Dice'
import { artFor } from '../petArt'
interface Props {
@@ -28,7 +29,7 @@ const EVENT_MS: Record<BattleEvent['type'], number> = {
reveal: 800,
summon: 1000,
mill: 700,
rock: 1200,
rock: 1500,
clash: 1400,
shield: 900,
strip: 1100,
@@ -312,11 +313,15 @@ export function BattlePhase({ view, send }: Props) {
<div className="battlefield">
{renderSide(youSeat, 'left')}
<div className="battle-center" aria-hidden>
{!done && lastEvent?.type === 'rock' && (
<div className={`rock-fly ${lastEvent.target === youSeat ? 'rock-fly-left' : 'rock-fly-right'}`}>
🪨
</div>
)}
{!done && lastEvent?.type === 'rock' &&
(lastEvent.dice && lastEvent.dice.length > 0 ? (
// Remount per rock event (keyed by step) so the tumble replays.
<DiceTray key={step} dice={lastEvent.dice} />
) : (
<div className={`rock-fly ${lastEvent.target === youSeat ? 'rock-fly-left' : 'rock-fly-right'}`}>
🪨
</div>
))}
<span className="battle-center-bolt"></span>
</div>
{renderSide(oppSeat, 'right')}