import { useEffect } from "react"; import "./ui/uiLayout.css"; import { DualDisplayFrame } from "./components/DualDisplayFrame"; import { installInput, releasePointerLock } from "./game/inputManager"; import { CombatBridge } from "./game/CombatBridge"; import { connectDpsMeter } from "./game/dpsMeterStore"; import { useCombatStore } from "./game/combatStore"; import { releaseDungeonGltfCache } from "./game/dungeonAssetCache"; import { clearDungeonRuntimeCaches } from "./game/dungeonRuntimeReset"; import { requireDungeonDefinition } from "./game/dungeonRegistry"; import { PartyBridge } from "./game/PartyBridge"; import { usePartyStore } from "./game/partyStore"; import { useGameStore } from "./game/store"; import { GameScene } from "./scene/GameScene"; import { LocalCompanionPanel } from "./ui/CompanionPanel"; import { Hud } from "./ui/Hud"; import { GameplayPanels } from "./ui/GameplayPanels"; import { MapPanel } from "./ui/MapPanel"; import { PauseMenu } from "./ui/PauseMenu"; import { SceneErrorBoundary } from "./ui/SceneErrorBoundary"; import { OnlineSessionBridge } from "./game/OnlineSessionBridge"; import { DungeonRunCheckpointBridge } from "./game/DungeonRunCheckpointBridge"; import { DungeonRunBridge } from "./game/DungeonRunBridge"; import { DungeonRunResults } from "./ui/DungeonRunResults"; import { DungeonEncounterEffectBridge } from "./game/DungeonEncounterEffectBridge"; import { interactWithActiveDungeonObject } from "./game/dungeonWorldInteraction"; import { DungeonInteractionPrompt } from "./ui/DungeonInteractionPrompt"; import { UiLayoutEditor } from "./ui/UiLayoutEditor"; import { EditableHudElement } from "./ui/EditableHudElement"; import { activeUiLayout, currentUiDevice } from "./game/uiLayoutStore"; import { useUiLayoutStore } from "./game/uiLayoutStore"; import { profileInputBindings } from "./game/keybindPreferences"; import { KeybindsPanel } from "./ui/KeybindsPanel"; import { lootShelvedBoss, releaseShelvedGameRuntime, ShelvedGameBridges } from "@shelvedGameRuntime"; function InputBridge() { const overlay = useGameStore((state) => state.overlay); const companionOpen = useGameStore((state) => state.companionOpen); useEffect(() => installInput({ desktopActionBarsActive: () => currentUiDevice() === "pc" && activeUiLayout().wowBars, inputSuspended: () => ["ui-layout", "keybinds", "dungeon-results"].includes(useGameStore.getState().overlay ?? ""), getBindings: (device) => { const preferences = useUiLayoutStore.getState().preferences; const bindings = profileInputBindings(preferences, device); for (let b = activeUiLayout().barCount; b < 5; b++) for (let s = 0; s < 12; s++) bindings[`bar:${b}:${s}`] = null; return bindings; }, castDesktopSlot: (bar, slot) => { const game = useGameStore.getState(); const button = activeUiLayout().bars[bar]?.slots[slot]; if (button?.abilityId) useCombatStore.getState().castAbility(button.abilityId, game.playerPosition, Date.now()); }, togglePanel: (panel) => useGameStore.getState().toggleOverlay(panel), togglePause: () => useGameStore.getState().togglePause(), toggleMap: () => useGameStore.getState().toggleMap(), toggleInventory: () => useGameStore.getState().toggleOverlay("inventory"), toggleSpellbook: () => useGameStore.getState().toggleOverlay("spellbook"), toggleTalents: () => useGameStore.getState().toggleOverlay("talents"), lootActiveBoss: () => interactWithActiveDungeonObject() || lootShelvedBoss(), castActionBinding: (layer, control) => { const game = useGameStore.getState(); useCombatStore.getState().castActionBinding(layer, control, game.playerPosition, Date.now()); }, cycleTarget: (direction) => { const game = useGameStore.getState(); usePartyStore.getState().clearSelection(); useCombatStore.getState().cycleTarget(direction, game.playerPosition); }, cyclePartyTarget: (direction) => { useCombatStore.getState().clearTarget(); usePartyStore.getState().cycleMember(direction); }, setPartyCommand: (command) => usePartyStore.getState().setCommand(command), recallParty: () => usePartyStore.getState().recallParty(), clearTarget: () => { useCombatStore.getState().clearTarget(); usePartyStore.getState().clearSelection(); }, groundTargetActive: () => useCombatStore.getState().pendingGroundTarget !== null, confirmGroundTarget: () => { useCombatStore.getState().confirmGroundTarget(); }, cancelGroundTarget: () => useCombatStore.getState().cancelGroundTarget(), gameplayActionsBlocked: () => { const game = useGameStore.getState(); return game.overlay !== null || game.companionOpen; }, setCameraLookActive: (active) => useGameStore.getState().setCameraLookActive(active), setInputMode: (mode) => useGameStore.getState().setInputMode(mode), setActionLayer: (layer) => useGameStore.getState().setActionLayer(layer), }), []); useEffect(() => () => releasePointerLock(), []); useEffect(() => { if (overlay || companionOpen) releasePointerLock(); }, [companionOpen, overlay]); return null; } export default function GameRuntime() { useEffect(connectDpsMeter, []); const editingControls = useGameStore((state) => state.overlay === "keybinds" || state.overlay === "ui-layout"); useEffect(() => () => { const activeDungeon = requireDungeonDefinition(useGameStore.getState().activeDungeonId); clearDungeonRuntimeCaches(); releaseDungeonGltfCache(activeDungeon); releaseShelvedGameRuntime(); }, []); return ( useGameStore.getState().setCompanionOpen(surface === "bottom")} top={
} bottom={} /> ); }