Files
healer-man/src/game/useArenaCombatView.ts
T
2026-09-14 22:12:49 -04:00

52 lines
2.5 KiB
TypeScript

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]);
}