import { rollAllInitiativeUseCase, rollInitiativeUseCase, } from "@initiative/application"; import { type CombatantId, isDomainError, type RollMode, } from "@initiative/domain"; import { useCallback, useState } from "react"; import { useBestiaryContext } from "../contexts/bestiary-context.js"; import { useEncounterContext } from "../contexts/encounter-context.js"; import { useSidePanelContext } from "../contexts/side-panel-context.js"; function rollDice(): number { return Math.floor(Math.random() * 20) + 1; } export function useInitiativeRolls() { const { encounter, makeStore, withUndo } = useEncounterContext(); const { getCreature } = useBestiaryContext(); const { showCreature } = useSidePanelContext(); const [rollSkippedCount, setRollSkippedCount] = useState(0); const [rollSingleSkipped, setRollSingleSkipped] = useState(false); const handleRollInitiative = useCallback( (id: CombatantId, mode: RollMode = "normal") => { const diceRolls: [number, ...number[]] = mode === "normal" ? [rollDice()] : [rollDice(), rollDice()]; const result = withUndo(() => rollInitiativeUseCase(makeStore(), id, diceRolls, getCreature, mode), ); if (isDomainError(result)) { setRollSingleSkipped(true); const combatant = encounter.combatants.find((c) => c.id === id); if (combatant?.creatureId) { showCreature(combatant.creatureId); } } }, [makeStore, getCreature, withUndo, encounter.combatants, showCreature], ); const handleRollAllInitiative = useCallback( (mode: RollMode = "normal") => { const result = withUndo(() => rollAllInitiativeUseCase(makeStore(), rollDice, getCreature, mode), ); if (!isDomainError(result) && result.skippedNoSource > 0) { setRollSkippedCount(result.skippedNoSource); } }, [makeStore, getCreature, withUndo], ); return { rollSkippedCount, rollSingleSkipped, dismissRollSkipped: useCallback(() => setRollSkippedCount(0), []), dismissRollSingleSkipped: useCallback( () => setRollSingleSkipped(false), [], ), handleRollInitiative, handleRollAllInitiative, } as const; }