41 lines
3.1 KiB
TypeScript
41 lines
3.1 KiB
TypeScript
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<T, K extends keyof T>(state: T, keys: readonly K[]): Pick<T, K> {
|
|
return Object.fromEntries(keys.map((key) => [key, state[key]])) as Pick<T, K>;
|
|
}
|
|
|
|
/** 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<typeof currentHudSnapshot>;
|