Files
healer-man/src/ui/TalentGameplayPanel.tsx
T
2026-09-14 13:20:20 -04:00

56 lines
2.1 KiB
TypeScript

import { use, useMemo } from "react";
import { classById, type CoaClassId } from "../app/characterCatalog";
import { useCombatStore } from "../game/combatStore";
import {
runtimeSpentTalentPointsInTree,
runtimeUnspentCoaEssence,
runtimeUnspentTalentPoints,
} from "../game/talentRuntimeCatalog";
import { loadedTalentUiCatalog, loadTalentUiCatalog, talentUiNodesForTree } from "../game/talentUiCatalog";
import { TalentsPanel } from "./TalentsPanel";
function treeSigil(name: string): string {
return name.split(/\s+/).map((word) => word[0]).join("").slice(0, 2).toUpperCase();
}
export default function TalentGameplayPanel({ readOnly = false, open, onClose }: {
readOnly?: boolean;
open?: boolean;
onClose?: () => void;
} = {}) {
const classId = useCombatStore((state) => state.classId);
const level = useCombatStore((state) => state.level);
const talentRanks = useCombatStore((state) => state.talentRanks);
const classDefinition = classById(classId);
const catalog = loadedTalentUiCatalog(classId) ?? use(loadTalentUiCatalog(classId));
const talentTrees = useMemo(() => catalog.trees.map((tree) => ({
id: tree.id,
name: tree.name,
description: tree.description,
points: runtimeSpentTalentPointsInTree(talentRanks, tree.id),
color: classDefinition.color,
sigil: treeSigil(tree.name),
iconUrl: tree.icon,
backgroundUrl: tree.background,
nodes: talentUiNodesForTree(catalog, tree.id),
})), [catalog, classDefinition.color, talentRanks]);
const coaEssence = classDefinition.mode === "conquest"
? runtimeUnspentCoaEssence(level, talentRanks, classId as CoaClassId)
: null;
return <TalentsPanel
trees={talentTrees}
ranks={talentRanks}
classId={classId}
playerLevel={level}
availablePoints={runtimeUnspentTalentPoints(level, talentRanks, classId)}
abilityEssence={coaEssence?.ability}
talentEssence={coaEssence?.talent}
onInvest={(nodeId) => { if (!readOnly) useCombatStore.getState().allocateTalent(nodeId); }}
onReset={() => { if (!readOnly) useCombatStore.getState().resetTalents(); }}
readOnly={readOnly}
open={open}
onClose={onClose}
/>;
}