52 lines
2.5 KiB
TypeScript
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]);
|
|
}
|