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 { 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 { ManastormBridge } from "./game/ManastormBridge"; import { releaseActiveManastormStage } from "./game/manastormStageLoader"; import { lootCurrentManastormBoss } from "./game/manastormLoot"; 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 { GmWorldEditor } from "./ui/GmWorldEditor"; import { GmReviewCard } from "./ui/GmReviewCard"; import { OnlineSessionBridge } from "./game/OnlineSessionBridge"; import { DungeonRunCheckpointBridge } from "./game/DungeonRunCheckpointBridge"; 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 { actionKeyForEvent, desktopSlotForKey } from "./game/uiLayout"; function InputBridge() { const overlay = useGameStore((state) => state.overlay); const companionOpen = useGameStore((state) => state.companionOpen); useEffect(() => installInput({ desktopActionBarsActive: () => currentUiDevice() === "pc" && activeUiLayout().wowBars, handleCustomKey: (event) => { const game = useGameStore.getState(); if (game.overlay === "ui-layout") return !["Tab", "Enter", "Space", "ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(event.code); if (currentUiDevice() !== "pc" || game.overlay || game.companionOpen || useCombatStore.getState().pendingGroundTarget) return false; const button = desktopSlotForKey(activeUiLayout(), actionKeyForEvent(event)); if (!button) return false; if (!event.repeat && button.abilityId) useCombatStore.getState().castAbility(button.abilityId, game.playerPosition, Date.now()); game.setInputMode("keyboard"); return true; }, 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() || lootCurrentManastormBoss(), 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(() => () => { const activeDungeon = requireDungeonDefinition(useGameStore.getState().activeDungeonId); clearDungeonRuntimeCaches(); releaseDungeonGltfCache(activeDungeon); releaseActiveManastormStage(); }, []); return ( useGameStore.getState().setCompanionOpen(surface === "bottom")} top={
} bottom={} /> ); }