import { useMemo } from "react"; import { useShellStore } from "../app/shellStore"; import { useGameStore } from "../game/store"; import { useMenuController, type MenuAction } from "../input/useMenuController"; import { ControllerButton } from "./ControllerButton"; import { sessionCanUseShelvedGmTools } from "../app/releaseFeatures"; import { DungeonIssueReportPanel } from "./DungeonIssueReportPanel"; import { BossTestingReviewPanel } from "./BossTestingReviewPanel"; import { classById } from "../app/characterCatalog"; import { specializationById, specializationIconUrl } from "../game/specializationCatalog"; import { dungeonBossCards } from "../game/dungeonBossCards"; import { requireDungeonDefinition } from "../game/dungeonRegistry"; import { DungeonBossCards } from "./DungeonBossCards"; import { useDungeonRaceStore } from "../app/dungeonRaceStore"; function PauseDialog() { const closeOverlay = useGameStore((state) => state.closeOverlay); const openOverlay = useGameStore((state) => state.openOverlay); const reset = useGameStore((state) => state.resetAtEntrance); const gameMode = useGameStore((state) => state.gameMode); const activeDungeonId = useGameStore((state) => state.activeDungeonId); const activeDifficultyId = useGameStore((state) => state.activeDifficultyId); const sessionRevision = useGameStore((state) => state.sessionRevision); const bossTest = useGameStore((state) => state.bossTest); const bossCards = useShellStore((state) => state.bossCards); const activeCharacter = useShellStore((state) => state.activeCharacter); const session = useShellStore((state) => state.session); const returnToMainMenu = useShellStore((state) => state.returnToMainMenu); const abandonManastormRun = useShellStore((state) => state.abandonManastormRun); const resume = () => { closeOverlay(); }; const returnToEntrance = () => { if (useDungeonRaceStore.getState().inGame) { void useDungeonRaceStore.getState().leave(); useGameStore.setState({ raceStartBlocked: false }); } reset(); }; const leaveDungeon = () => { if (useDungeonRaceStore.getState().inGame) void useDungeonRaceStore.getState().leave(); closeOverlay(); returnToMainMenu(); }; const abandonManastorm = () => { closeOverlay(); abandonManastormRun(); }; const skillMenuLabel = activeCharacter?.categoryId === "rom" ? "Skills" : "Talents"; const isGm = sessionCanUseShelvedGmTools(session); const characterClass = activeCharacter ? classById(activeCharacter.classId) : null; const specialization = specializationById(activeCharacter?.specializationId); const classDetail = activeCharacter?.secondaryClassId ? classById(activeCharacter.secondaryClassId).name : specialization && specialization.classId === activeCharacter?.classId ? specialization.displayName : null; const dungeonCards = useMemo(() => gameMode === "dungeon" ? dungeonBossCards(requireDungeonDefinition(activeDungeonId), activeDifficultyId, bossCards) : [], [activeDungeonId, activeDifficultyId, bossCards, gameMode, sessionRevision]); const actions = useMemo(() => [ { id: "pause-resume", run: resume, neighbors: { down: "pause-party", right: "pause-party", up: "pause-main-menu", left: "pause-main-menu" } }, { id: "pause-party", run: () => openOverlay("party"), neighbors: { up: "pause-resume" } }, { id: "pause-map", run: () => openOverlay("map") }, { id: "pause-boss-guide", run: () => openOverlay("boss-guide") }, { id: "pause-boss-cards", run: () => openOverlay("boss-cards") }, { id: "pause-inventory", run: () => openOverlay("inventory") }, { id: "pause-spellbook", run: () => openOverlay("spellbook") }, { id: "pause-talents", run: () => openOverlay("talents") }, { id: "pause-bindings", run: () => openOverlay("bindings") }, { id: "pause-options", run: () => openOverlay("options") }, { id: "pause-keybinds", run: () => openOverlay("keybinds") }, { id: "pause-ui-layout", run: () => openOverlay("ui-layout") }, ...(isGm ? [{ id: "pause-gm", run: () => openOverlay("gm") }] : []), ...(gameMode === "dungeon" ? [{ id: "pause-report-issue", run: () => openOverlay("report-issue") }] : []), ...(bossTest ? [{ id: "pause-boss-testing-review", run: () => openOverlay("boss-test-review") }] : []), ...(gameMode === "manastorm" ? [{ id: "pause-abandon-manastorm", run: abandonManastorm }] : [{ id: "pause-entrance", run: returnToEntrance }]), { id: "pause-main-menu", run: leaveDungeon }, ], [abandonManastormRun, bossTest, closeOverlay, gameMode, isGm, openOverlay, reset, returnToMainMenu]); const controller = useMenuController(actions, { columns: 2, initialId: "pause-resume", onBack: resume }); const menuButton = (id: string, label: string, run: () => void, primary = false) => ( {label} ); return (

Paused

{activeCharacter && }
{activeCharacter?.name ?? "Adventurer"} Level {activeCharacter?.level ?? 1} · {characterClass?.name ?? "Explorer"}{classDetail ? ` / ${classDetail}` : ""}
{bossTest &&

Boss Testing · {bossTest.name}

}
{gameMode === "dungeon" &&
Boss cards in this dungeon {dungeonCards.filter((card) => card.copies > 0).length} / {dungeonCards.length} collected
}
{menuButton("pause-resume", "Resume game", resume, true)}

Adventure

{menuButton("pause-party", "Party management", () => openOverlay("party"))} {menuButton("pause-map", "Dungeon map", () => openOverlay("map"))} {menuButton("pause-boss-guide", "Boss guide", () => openOverlay("boss-guide"))} {menuButton("pause-boss-cards", "Boss cards", () => openOverlay("boss-cards"))}

Character

{menuButton("pause-inventory", "Inventory & equipment", () => openOverlay("inventory"))} {menuButton("pause-spellbook", "Spellbook", () => openOverlay("spellbook"))} {menuButton("pause-talents", skillMenuLabel, () => openOverlay("talents"))} {menuButton("pause-bindings", "Ability controls", () => openOverlay("bindings"))}

Settings

{menuButton("pause-options", "Options", () => openOverlay("options"))} {menuButton("pause-keybinds", "Keybinds", () => openOverlay("keybinds"))} {menuButton("pause-ui-layout", "Edit UI & templates", () => openOverlay("ui-layout"))} {isGm && menuButton("pause-gm", "GM placement editor", () => openOverlay("gm"))}

Session

{gameMode === "dungeon" && menuButton("pause-report-issue", "Report an issue", () => openOverlay("report-issue"))} {bossTest && menuButton("pause-boss-testing-review", "Boss readiness & report", () => openOverlay("boss-test-review"))} {gameMode === "manastorm" ? menuButton("pause-abandon-manastorm", "Abandon Manastorm run", abandonManastorm) : menuButton("pause-entrance", bossTest ? "Restart boss test" : "Return to entrance", returnToEntrance)} {menuButton("pause-main-menu", "Main menu", leaveDungeon)}
); } export function PauseMenu() { const overlay = useGameStore((state) => state.overlay); if (overlay === "report-issue") return ; if (overlay === "boss-test-review") return ; return overlay === "pause" ? : null; }