import { useCombatStore } from "../game/combatStore"; import { useGameStore } from "../game/store"; import { usePartyStore } from "../game/partyStore"; import { useManastormStore } from "../game/manastormStore"; import { useDungeonRunStore } from "../game/dungeonRunStore"; import { useOnlineSessionStore } from "../app/onlineSessionStore"; import { useOnlineGroupStore } from "../app/onlineGroupStore"; import { useShellStore } from "../app/shellStore"; import { useUiLayoutStore } from "../game/uiLayoutStore"; import { useDpsMeterStore } from "../game/dpsMeterStore"; import { activeDungeonRunIsComplete } from "../game/dungeonEncounterRuntime"; import { activeDungeonInteractionCandidate } from "../game/dungeonWorldInteraction"; import { requireDungeonDefinition } from "../game/dungeonRegistry"; function pick(state: T, keys: readonly K[]): Pick { return Object.fromEntries(keys.map((key) => [key, state[key]])) as Pick; } /** Presentation data only. The lower WebView never starts another simulation. */ export function currentHudSnapshot() { const game = useGameStore.getState(); const run = useDungeonRunStore.getState().progress; const candidate = game.overlay ? null : activeDungeonInteractionCandidate(); return { game: pick(game, ["activeDungeonId", "gameMode", "gmTestMode", "bossTest", "areaName", "distanceTravelled", "playerPosition", "cameraYaw", "hasMoved", "cameraLookActive", "inputMode", "actionLayer", "assetStatus", "assetMessage", "overlay", "paused", "companionOpen"]), bossTestingDungeon: game.bossTest ? { definition: requireDungeonDefinition(game.activeDungeonId), sourceDungeonId: game.bossTest.sourceDungeonId } : null, combat: pick(useCombatStore.getState(), ["classId", "secondaryClassId", "specializationId", "level", "xp", "xpToNext", "health", "maxHealth", "shield", "shieldExpiresAt", "resource", "maxResource", "resourcePools", "maxResourcePools", "resourceName", "abilities", "talentRanks", "talentModifiers", "auras", "effects", "summons", "actors", "actionBindings", "cooldowns", "globalCooldownEndsAt", "activeCast", "pendingGroundTarget", "feedback", "selectedTargetId", "selectedFriendlyActorId", "mobs", "settings"]), party: pick(usePartyStore.getState(), ["members", "selectedMemberId", "selfSelected", "playerRole", "command", "routeBlocked"]), manastorm: pick(useManastormStore.getState(), ["currentEncounter", "resurrectionCharges"]), shell: pick(useShellStore.getState(), ["activeCharacter", "activeDungeonRole"]), onlineSession: useOnlineSessionStore.getState().snapshot, onlineGroup: pick(useOnlineGroupStore.getState(), ["snapshot", "activeActivity"]), ui: pick(useUiLayoutStore.getState(), ["preferences", "draft", "device", "selectedElement"]), run, dps: useDpsMeterStore.getState(), completion: game.gameMode === "dungeon" && (activeDungeonRunIsComplete(game.activeDungeonId) || (run?.dungeonId === game.activeDungeonId && run.finishedAt !== null)), interaction: candidate ? { prompt: candidate.object.interaction!.prompt, name: candidate.object.name, label: candidate.state.label } : null, }; } export type HudSnapshot = ReturnType;