import { useEffect, useRef } from "react"; import type { CharacterProfile } from "../app/types"; import { useShellStore } from "../app/shellStore"; import { useCombatStore } from "./combatStore"; import { activateCharacterUi } from "./uiLayoutStore"; import { usePartyStore } from "./partyStore"; import { useGameStore } from "./store"; import { useArenaStore } from "./arenaStore"; import type { ArenaActorSnapshot } from "./arenaTypes"; /** Existing character panels read this view; the arena server owns combat. */ export function useArenaCombatView(character: CharacterProfile | null, actor: ArenaActorSnapshot | null) { const mirroring = useRef(false); useEffect(() => { if (!character) return; const previous = useCombatStore.getState(); const previousParty = usePartyStore.getState(); const previousGame = useGameStore.getState(); useCombatStore.getState().initializeCharacter(character); activateCharacterUi(character); usePartyStore.setState({ members: [] }); useGameStore.setState({ overlay: null, paused: false, companionOpen: false }); const unsubscribe = useCombatStore.subscribe((state, before) => { if (mirroring.current) return; if (state.actionBindings !== before.actionBindings) { useArenaStore.getState().intent({ type: "bindings", actionBindings: state.actionBindings }); useShellStore.getState().saveActiveActionBindings(state.actionBindings); } if (state.settings !== before.settings) useShellStore.getState().saveActiveSettings(state.settings); }); return () => { unsubscribe(); useCombatStore.setState(previous, true); usePartyStore.setState(previousParty, true); useGameStore.setState(previousGame, true); }; }, [character?.id]); useEffect(() => { if (!actor) return; mirroring.current = true; const runtime = actor.combat; useCombatStore.setState({ health: actor.health, maxHealth: actor.maxHealth, resource: actor.resource, maxResource: actor.maxResource, level: actor.level, ...(actor.actionBindings ? { actionBindings: actor.actionBindings } : {}), ...(runtime ? { resourcePools: runtime.resourcePools, maxResourcePools: runtime.maxResourcePools, deathKnightRunes: runtime.runes, comboPoints: runtime.comboPoints, comboTargetId: runtime.comboTargetId, shield: runtime.shield, activeCast: runtime.activeCast, talentRanks: runtime.talentRanks, gearStats: runtime.gearStats, specializationId: runtime.specializationId } : {}) }); mirroring.current = false; }, [actor]); }