forked from phenom/healer-man
Release Healer Man 0.1.7
This commit is contained in:
1 parent
b12fb84859
commit
eca6b5db9b
99 files changed
+1931
-150
No files matched your search
@@ -4,14 +4,18 @@ import {
|
||||
learnedPartyTalentSelections,
|
||||
upcomingPartyTalentSelections,
|
||||
type PartyTalentSelection,
|
||||
} from "../game/partyTalents";
|
||||
} from "../game/partyTalentUi";
|
||||
import {
|
||||
PARTY_ROLE_LABELS,
|
||||
usePartyStore,
|
||||
type PartyCommand,
|
||||
type PartyMember,
|
||||
} from "../game/partyStore";
|
||||
import { talentTreeById } from "../game/talentCatalog";
|
||||
import {
|
||||
loadTalentUiCatalog,
|
||||
talentUiTreeById,
|
||||
type TalentUiCatalog,
|
||||
} from "../game/talentUiCatalog";
|
||||
import { useGameStore } from "../game/store";
|
||||
import { useMenuController, type MenuAction } from "../input/useMenuController";
|
||||
import { ControllerButton } from "./ControllerButton";
|
||||
@@ -70,6 +74,8 @@ function PartyManagementDialog() {
|
||||
const command = usePartyStore((state) => state.command);
|
||||
const openOverlay = useGameStore((state) => state.openOverlay);
|
||||
const [inspectedMemberId, setInspectedMemberId] = useState(() => members[0]?.id ?? "");
|
||||
const [talentCatalog, setTalentCatalog] = useState<TalentUiCatalog | null>(null);
|
||||
const [talentCatalogErrorClassId, setTalentCatalogErrorClassId] = useState<string | null>(null);
|
||||
const close = useCallback(() => openOverlay("pause"), [openOverlay]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -79,13 +85,45 @@ function PartyManagementDialog() {
|
||||
}, [inspectedMemberId, members]);
|
||||
|
||||
const inspectedMember = members.find((member) => member.id === inspectedMemberId) ?? members[0] ?? null;
|
||||
const learned = useMemo(() => inspectedMember
|
||||
? learnedPartyTalentSelections(inspectedMember.classId, inspectedMember.specialization, inspectedMember.level)
|
||||
: [], [inspectedMember]);
|
||||
useEffect(() => {
|
||||
const classId = inspectedMember?.classId;
|
||||
if (!classId || classId.startsWith("rom-")) {
|
||||
setTalentCatalog(null);
|
||||
setTalentCatalogErrorClassId(null);
|
||||
return;
|
||||
}
|
||||
let active = true;
|
||||
setTalentCatalogErrorClassId(null);
|
||||
void loadTalentUiCatalog(classId).then((catalog) => {
|
||||
if (active) setTalentCatalog(catalog);
|
||||
}).catch(() => {
|
||||
if (!active) return;
|
||||
setTalentCatalog(null);
|
||||
setTalentCatalogErrorClassId(classId);
|
||||
});
|
||||
return () => { active = false; };
|
||||
}, [inspectedMember?.classId]);
|
||||
const activeTalentCatalog = inspectedMember && talentCatalog?.classId === inspectedMember.classId
|
||||
? talentCatalog
|
||||
: null;
|
||||
const learned = useMemo(() => inspectedMember && activeTalentCatalog
|
||||
? learnedPartyTalentSelections(
|
||||
activeTalentCatalog,
|
||||
inspectedMember.classId,
|
||||
inspectedMember.specialization,
|
||||
inspectedMember.level,
|
||||
)
|
||||
: [], [activeTalentCatalog, inspectedMember]);
|
||||
const currentTalents = useMemo(() => currentTalentRanks(learned), [learned]);
|
||||
const upcomingTalents = useMemo(() => inspectedMember
|
||||
? upcomingPartyTalentSelections(inspectedMember.classId, inspectedMember.specialization, inspectedMember.level, 3)
|
||||
: [], [inspectedMember]);
|
||||
const upcomingTalents = useMemo(() => inspectedMember && activeTalentCatalog
|
||||
? upcomingPartyTalentSelections(
|
||||
activeTalentCatalog,
|
||||
inspectedMember.classId,
|
||||
inspectedMember.specialization,
|
||||
inspectedMember.level,
|
||||
3,
|
||||
)
|
||||
: [], [activeTalentCatalog, inspectedMember]);
|
||||
|
||||
const actions = useMemo<MenuAction[]>(() => [
|
||||
...members.map((member) => ({
|
||||
@@ -106,7 +144,9 @@ function PartyManagementDialog() {
|
||||
|
||||
const memberClass = inspectedMember ? classById(inspectedMember.classId) : null;
|
||||
const memberRace = inspectedMember ? raceById(inspectedMember.raceId) : null;
|
||||
const primaryTree = inspectedMember ? talentTreeById(inspectedMember.talentTreeId) : null;
|
||||
const primaryTree = inspectedMember && activeTalentCatalog
|
||||
? talentUiTreeById(activeTalentCatalog, inspectedMember.talentTreeId)
|
||||
: null;
|
||||
const primaryPoints = inspectedMember
|
||||
? learned.filter((selection) => selection.treeId === inspectedMember.talentTreeId).length
|
||||
: 0;
|
||||
@@ -210,7 +250,14 @@ function PartyManagementDialog() {
|
||||
</header>
|
||||
<div className="party-management__talent-list">
|
||||
{currentTalents.map((selection) => <TalentSelectionCard key={selection.nodeId} selection={selection} />)}
|
||||
{!currentTalents.length && (
|
||||
{!activeTalentCatalog && (
|
||||
<p className="party-management__empty-talents">
|
||||
{talentCatalogErrorClassId === inspectedMember.classId
|
||||
? "Talent details are temporarily unavailable."
|
||||
: "Preparing this class's talent catalog…"}
|
||||
</p>
|
||||
)}
|
||||
{activeTalentCatalog && !currentTalents.length && (
|
||||
<p className="party-management__empty-talents">
|
||||
Talent training begins at level 10. This build will advance automatically with you.
|
||||
</p>
|
||||
@@ -227,7 +274,7 @@ function PartyManagementDialog() {
|
||||
{upcomingTalents.map((selection) => (
|
||||
<TalentSelectionCard key={`${selection.level}-${selection.nodeId}`} selection={selection} upcoming />
|
||||
))}
|
||||
{!upcomingTalents.length && (
|
||||
{activeTalentCatalog && !upcomingTalents.length && (
|
||||
<p className="party-management__empty-talents">This party member has completed the level 80 talent plan.</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user