import { touchCharacter } from "./accountRepository"; import { useShellStore } from "./shellStore"; import { registerGeneratedManastormStageAssets } from "../game/manastormAssetRegistry"; import { isGameMasterSession, resolvedBossAdminCatalog, } from "../game/manastormAdminConfig"; import { useManastormAdminStore } from "../game/manastormAdminStore"; import { INSTALLED_MANASTORM_RUNTIME_CATALOG } from "../game/manastormInstalledCatalog"; import { installedManastormStageBinding } from "../game/manastormInstalledStages"; import { registerManastormStageBindingResolver } from "../game/manastormStagePopulation"; import { activateManastormStage } from "../game/manastormStageLoader"; import { manastormModeForCharacterLevel, setManastormCatalog } from "../game/manastorm"; import { createEmptyManastormProgress, manastormModeProgress } from "../game/manastormProgress"; import { manastormActiveSpellLoadoutModel } from "../game/manastormSpellLoadout"; import { useManastormStore } from "../game/manastormStore"; import { defaultPartyRoleForClass } from "../game/partyRoles"; import { useGameStore } from "../game/store"; export function enterGmManastormTest(bossKey: string): boolean { const shell = useShellStore.getState(); if (!isGameMasterSession(shell.session) || !shell.selectedCharacterId) { useShellStore.setState({ notice: "Game Master access is required." }); return false; } const activeCharacter = touchCharacter(shell.session!.ownerId, shell.selectedCharacterId) ?? shell.characters.find((character) => character.id === shell.selectedCharacterId) ?? null; if (!activeCharacter) { useShellStore.setState({ notice: "Select a character before testing a boss." }); return false; } const adminConfig = useManastormAdminStore.getState().config; const entry = resolvedBossAdminCatalog(adminConfig).find((candidate) => candidate.key === bossKey); if (!entry || entry.status === "not-ready" || !entry.runnable || !entry.stage) { useShellStore.setState({ notice: entry?.validationIssues[0] ?? "That boss is not available for GM testing." }); return false; } registerGeneratedManastormStageAssets(); registerManastormStageBindingResolver(installedManastormStageBinding); const modeId = manastormModeForCharacterLevel(activeCharacter.level, INSTALLED_MANASTORM_RUNTIME_CATALOG); const { milestoneLevel: _milestoneLevel, ...stageWithoutMilestone } = entry.stage; const testStage = Object.freeze({ ...stageWithoutMilestone, modeIds: [modeId], stageKind: "standard" as const, unlockLevel: 1, chaoticLinkEnabled: adminConfig.global.chaoticLinkEnabled, }); const testCatalog = Object.freeze({ ...INSTALLED_MANASTORM_RUNTIME_CATALOG, stages: [testStage], fallbackPolicy: "none" as const, runtimeOptions: Object.freeze({ ...adminConfig.global }), }); setManastormCatalog(testCatalog); useManastormStore.getState().resetRun(); const progress = activeCharacter.manastormProgress ?? createEmptyManastormProgress(); const modeProgress = manastormModeProgress(progress, modeId); const spellLoadout = manastormActiveSpellLoadoutModel( activeCharacter.classId, activeCharacter.level, activeCharacter.talentRanks, ); let encounter; try { encounter = useManastormStore.getState().startRun({ partySize: 5, startingLevel: 1, unlockedThroughLevel: 1, modeId, activeSpellLoadout: { available: spellLoadout.options, selectedIds: progress.loadout, maxSelections: spellLoadout.maxSelections, provenance: spellLoadout.provenance, }, cacheMeter: modeProgress.cacheMeter, rewardCaches: modeProgress.rewardCaches, random: () => 0, }); } catch { useShellStore.setState({ notice: "The configured boss could not be prepared for testing." }); return false; } if (!activateManastormStage(encounter, undefined, false, true).activated) { useManastormStore.getState().resetRun(); useShellStore.setState({ notice: "The configured dungeon or stage package is not loadable." }); return false; } useGameStore.getState().setCompanionOpen(false); useShellStore.setState({ phase: "game", activeCharacter, activeDungeonId: encounter.dungeonId, activeDungeonRole: defaultPartyRoleForClass(activeCharacter.classId), notice: `GM test: ${entry.name}`, }); return true; }