Release Healer Man 0.1.4

This commit is contained in:
phenom committed 2026-08-18 12:06:04 -04:00
1 parent 5bb170039a
commit f4c9cf356c
63 files changed
+2694 -81

No files matched your search

+46 -3
View File
@@ -1,5 +1,6 @@
import { lazy, Suspense, useMemo } from "react";
import { lazy, Suspense, useEffect, useMemo } from "react";
import { classById } from "../app/characterCatalog";
import { useShellStore } from "../app/shellStore";
import { useCombatStore } from "../game/combatStore";
import {
abilityAtLevel,
@@ -13,7 +14,41 @@ import { EquipmentPanel } from "./EquipmentPanel";
import { RomSkillsPanel } from "./RomSkillsPanel";
const PartyManagementPanel = lazy(() => import("./PartyManagementPanel").then((module) => ({ default: module.PartyManagementPanel })));
const TalentGameplayPanel = lazy(() => import("./TalentGameplayPanel"));
let talentGameplayPanelModule: Promise<typeof import("./TalentGameplayPanel")> | null = null;
function loadTalentGameplayPanel() {
if (!talentGameplayPanelModule) {
talentGameplayPanelModule = import("./TalentGameplayPanel").catch((error: unknown) => {
talentGameplayPanelModule = null;
throw error;
});
}
return talentGameplayPanelModule;
}
function preloadTalentGameplayPanel() {
void loadTalentGameplayPanel().catch(() => undefined);
}
const TalentGameplayPanel = lazy(loadTalentGameplayPanel);
function TalentsPanelLoading() {
const openOverlay = useGameStore((state) => state.openOverlay);
return (
<div className="modal-backdrop game-panel-backdrop" role="presentation">
<section className="game-panel talents-panel talents-panel--loading" role="dialog" aria-modal="true" aria-labelledby="talents-loading-title">
<header className="game-panel__header">
<div>
<p className="eyebrow">Specialization</p>
<h2 id="talents-loading-title">Talents</h2>
</div>
<button type="button" className="icon-button" onClick={() => openOverlay("pause")} aria-label="Return to pause menu">×</button>
</header>
<p className="game-panel__empty" role="status">Preparing talent trees…</p>
</section>
</div>
);
}
/** Maps the data-driven combat catalogs into the full-screen game panels. */
export function GameplayPanels() {
@@ -22,9 +57,14 @@ export function GameplayPanels() {
const abilities = useCombatStore((state) => state.abilities);
const talentRanks = useCombatStore((state) => state.talentRanks);
const settings = useCombatStore((state) => state.settings);
const presentationSettings = useShellStore((state) => state.combatPresentationSettings);
const overlay = useGameStore((state) => state.overlay);
const classDefinition = classById(classId);
useEffect(() => {
if (overlay === "pause" && !classId.startsWith("rom-")) preloadTalentGameplayPanel();
}, [classId, overlay]);
const spellbookAbilities = useMemo(() => [...abilities]
.sort((left, right) => left.unlockLevel - right.unlockLevel)
.map((catalogAbility) => {
@@ -76,12 +116,15 @@ export function GameplayPanels() {
{overlay === "talents"
? classId.startsWith("rom-")
? <RomSkillsPanel />
: <Suspense fallback={null}><TalentGameplayPanel /></Suspense>
: <Suspense fallback={<TalentsPanelLoading />}><TalentGameplayPanel /></Suspense>
: null}
<OptionsPanel
settings={settings}
onChange={(patch) => useCombatStore.getState().updateSettings(patch)}
onReset={() => useCombatStore.getState().resetSettings()}
presentationSettings={presentationSettings}
onPresentationChange={(patch) => useShellStore.getState().updateCombatPresentationSettings(patch)}
onPresentationReset={() => useShellStore.getState().resetCombatPresentationSettings()}
/>
</>
);