Release Healer Man 0.1.46

This commit is contained in:
phenom committed 2026-09-16 14:30:58 -04:00
1 parent f82daf1c13
commit 9ff574ac0b
73 files changed
+33486 -174

No files matched your search

+39 -18
View File
@@ -9,11 +9,12 @@ import { ControllerButton } from "./ControllerButton";
import { ContentManagerScreen } from "./ContentManagerScreen";
import { BrandMark, ControllerLegend, FrontSurface } from "./FrontSurface";
import { OnlineGroupPanel } from "./OnlineGroupPanel";
import { sessionCanUseShelvedGmTools, SHELVED_MODES_ENABLED } from "../app/releaseFeatures";
import { sessionCanUseGmTools, SHELVED_MODES_ENABLED } from "../app/releaseFeatures";
import { DungeonReportsScreen } from "./DungeonReportsScreen";
import { MainMenuCharacterEditor, type MainMenuEditor } from "./MainMenuCharacterEditor";
const BossCardCollectionScreen = lazy(() => import("./BossCardCollection"));
const BossTestingScreen = lazy(() => import("./BossTestingScreen").then((module) => ({ default: module.BossTestingScreen })));
const BalanceLabScreen = lazy(() => import("./BalanceLabScreen").then((module) => ({ default: module.BalanceLabScreen })));
const GAME_MODES = [
{
@@ -71,20 +72,23 @@ export function MainMenuScreen() {
const [reportsOpen, setReportsOpen] = useState(false);
const [cardsOpen, setCardsOpen] = useState(false);
const [bossTestingOpen, setBossTestingOpen] = useState(false);
const [balanceLabOpen, setBalanceLabOpen] = useState(false);
const [editor, setEditor] = useState<MainMenuEditor | null>(null);
if (editor) return <MainMenuCharacterEditor editor={editor} onClose={() => setEditor(null)} />;
if (bossTestingOpen) return <Suspense fallback={<p role="status">Opening Boss Testing…</p>}><BossTestingScreen onClose={() => setBossTestingOpen(false)} /></Suspense>;
if (balanceLabOpen) return <Suspense fallback={<p role="status">Opening Balance Lab…</p>}><BalanceLabScreen onClose={() => setBalanceLabOpen(false)} /></Suspense>;
if (cardsOpen) return <Suspense fallback={<p role="status">Opening collection log…</p>}><BossCardCollectionScreen onClose={() => setCardsOpen(false)} /></Suspense>;
if (contentManagerOpen) return <ContentManagerScreen onClose={() => setContentManagerOpen(false)} />;
if (reportsOpen) return <DungeonReportsScreen onClose={() => setReportsOpen(false)} />;
return <MainMenuDestinations onOpenDownloads={() => setContentManagerOpen(true)} onOpenReports={() => setReportsOpen(true)} onOpenCards={() => setCardsOpen(true)} onOpenBossTesting={() => setBossTestingOpen(true)} onOpenEditor={setEditor} />;
return <MainMenuDestinations onOpenDownloads={() => setContentManagerOpen(true)} onOpenReports={() => setReportsOpen(true)} onOpenCards={() => setCardsOpen(true)} onOpenBossTesting={() => setBossTestingOpen(true)} onOpenBalanceLab={() => setBalanceLabOpen(true)} onOpenEditor={setEditor} />;
}
function MainMenuDestinations({ onOpenDownloads, onOpenReports, onOpenCards, onOpenBossTesting, onOpenEditor }: {
function MainMenuDestinations({ onOpenDownloads, onOpenReports, onOpenCards, onOpenBossTesting, onOpenBalanceLab, onOpenEditor }: {
readonly onOpenDownloads: () => void;
readonly onOpenReports: () => void;
readonly onOpenCards: () => void;
readonly onOpenBossTesting: () => void;
readonly onOpenBalanceLab: () => void;
readonly onOpenEditor: (editor: MainMenuEditor) => void;
}) {
const activeCharacter = useShellStore((state) => state.activeCharacter);
@@ -99,7 +103,7 @@ function MainMenuDestinations({ onOpenDownloads, onOpenReports, onOpenCards, onO
const openGmAdmin = useShellStore((state) => state.openGmAdmin);
const character = activeCharacter ?? rosterCharacter;
const isRom = character?.categoryId === "rom";
const isGm = sessionCanUseShelvedGmTools(session);
const isGm = sessionCanUseGmTools(session);
const actions = useMemo<MenuAction[]>(() => [
{
@@ -132,11 +136,14 @@ function MainMenuDestinations({ onOpenDownloads, onOpenReports, onOpenCards, onO
{ id: "mode-keybinds", run: () => onOpenEditor("keybinds") },
{ id: "mode-bindings", run: () => onOpenEditor("bindings") },
] : []),
...(isGm ? [{ id: "mode-gm-tools", run: openGmAdmin }] : []),
...(isGm ? [
{ id: "mode-gm-tools", run: openGmAdmin },
{ id: "mode-balance-lab", run: onOpenBalanceLab },
] : []),
{ id: "mode-reports", run: onOpenReports },
{ id: "mode-cards", run: onOpenCards },
{ id: "mode-boss-testing", run: onOpenBossTesting },
], [character, isGm, onOpenBossTesting, onOpenCards, onOpenDownloads, onOpenEditor, onOpenReports, openArenas, openClassHall, openDungeons, openGmAdmin, openManastorms, returnToCharacters]);
], [character, isGm, onOpenBalanceLab, onOpenBossTesting, onOpenCards, onOpenDownloads, onOpenEditor, onOpenReports, openArenas, openClassHall, openDungeons, openGmAdmin, openManastorms, returnToCharacters]);
const controller = useMenuController(actions, {
initialId: "mode-dungeons",
onBack: returnToCharacters,
@@ -221,18 +228,32 @@ function MainMenuDestinations({ onOpenDownloads, onOpenReports, onOpenCards, onO
<em>Open</em>
</ControllerButton>
{isGm && (
<ControllerButton
controlId="mode-gm-tools"
selectedId={controller.selectedId}
select={controller.select}
className="front-button main-menu-mode main-menu-mode--available main-menu-mode--gm"
type="button"
onClick={openGmAdmin}
>
<b aria-hidden="true">GM</b>
<span><strong>GM Tools</strong><small>Manage Manastorm rules, boss readiness, and encounter placement.</small></span>
<em>Authorized</em>
</ControllerButton>
<div className="main-menu-gm-stack">
<ControllerButton
controlId="mode-gm-tools"
selectedId={controller.selectedId}
select={controller.select}
className="front-button main-menu-mode main-menu-mode--available main-menu-mode--gm"
type="button"
onClick={openGmAdmin}
>
<b aria-hidden="true">GM</b>
<span><strong>GM Tools</strong><small>Run dungeon route simulations, inspect findings, and review recordings.</small></span>
<em>Authorized</em>
</ControllerButton>
<ControllerButton
controlId="mode-balance-lab"
selectedId={controller.selectedId}
select={controller.select}
className="front-button main-menu-mode main-menu-mode--available main-menu-mode--gm"
type="button"
onClick={onOpenBalanceLab}
>
<b aria-hidden="true">BL</b>
<span><strong>Balance Lab</strong><small>Queue automatic party and boss simulations on the game server.</small></span>
<em>Server</em>
</ControllerButton>
</div>
)}
{character && (
<ControllerButton