import { useState, type KeyboardEvent } from "react"; import { inputKeyForEvent } from "../input/keybinds"; import { getInputPreferences, isCapturingInput } from "../input/keybindRuntime"; import { useInputBindingLabels } from "../input/useInputBindingLabels"; import { useGameStore } from "../game/store"; import { useMenuController } from "../input/useMenuController"; import { DungeonMapGraphic, type MapArtworkStatus } from "./DungeonMapGraphic"; import { requireDungeonDefinition } from "../game/dungeonRegistry"; import { resolveStagePresentation } from "../game/manastormStagePresentation"; import { useManastormStore } from "../game/manastormStore"; import { dungeonArtworkContains, dungeonArtworkFloorFor, dungeonArtworkMapFor, dungeonArtworkPoint } from "../game/dungeonArtworkMap"; export function closeMapForKey(event: Pick, close: () => void) { if (event.repeat || event.defaultPrevented || isCapturingInput()) return; const key = inputKeyForEvent(event); if (!key || key !== getInputPreferences().pc.map) return; // The gameplay listener intentionally ignores focused form controls. event.preventDefault(); event.stopPropagation(); close(); } function MapDialog() { const bindingLabel = useInputBindingLabels(); const close = useGameStore((state) => state.closeMap); const openOverlay = useGameStore((state) => state.openOverlay); const position = useGameStore((state) => state.playerPosition); const yaw = useGameStore((state) => state.cameraYaw); const area = useGameStore((state) => state.areaName); const gameMode = useGameStore((state) => state.gameMode); const encounter = useManastormStore((state) => state.currentEncounter); const activeDungeonId = useGameStore((state) => state.activeDungeonId); const dungeon = requireDungeonDefinition(activeDungeonId); const map = dungeonArtworkMapFor(dungeon); const navigationPlan = map?.kind === "runewaker" && map.source.kind === "navigation"; const [floorLevel, setFloorLevel] = useState(null); const [showPatrols, setShowPatrols] = useState(false); const [artworkStatus, setArtworkStatus] = useState(map ? "loading" : "unavailable"); const floor = map ? dungeonArtworkFloorFor(map, position, floorLevel) : null; const mapPosition = map && floor ? dungeonArtworkPoint(map, floor, position) : null; const positionOnMap = Boolean(map && floor && dungeonArtworkContains(map, floor, position)); const stagePresentation = resolveStagePresentation(gameMode, encounter, { title: dungeon.title, mapId: dungeon.mapId, areaName: area, }); useMenuController([], { onBack: () => openOverlay("pause") }); return ( ); } export function MapPanel() { const open = useGameStore((state) => state.overlay === "map"); const activeDungeonId = useGameStore((state) => state.activeDungeonId); return open ? : null; }