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
@@ -0,0 +1,93 @@
|
||||
import type { ClassId } from "../app/characterCatalog";
|
||||
|
||||
export interface TalentUiTree {
|
||||
readonly id: string;
|
||||
readonly classId: ClassId;
|
||||
readonly name: string;
|
||||
readonly icon: string;
|
||||
readonly background: string;
|
||||
readonly description: string;
|
||||
readonly system?: "classic" | "coa";
|
||||
}
|
||||
|
||||
export interface TalentUiNode {
|
||||
readonly id: string;
|
||||
readonly treeId: string;
|
||||
readonly index: number;
|
||||
readonly prerequisiteId: string | null;
|
||||
readonly prerequisiteRank: number | null;
|
||||
readonly prerequisites: readonly {
|
||||
readonly talentId: string;
|
||||
readonly requiredRank: number;
|
||||
}[];
|
||||
readonly column: number;
|
||||
readonly row: number;
|
||||
readonly icon: string;
|
||||
readonly maxRank: number;
|
||||
readonly name: string;
|
||||
readonly description: string;
|
||||
readonly rankDescriptions: readonly string[];
|
||||
readonly system?: "classic" | "coa";
|
||||
readonly entryType?: "Ability" | "Talent";
|
||||
readonly abilityEssenceCost?: number;
|
||||
readonly talentEssenceCost?: number;
|
||||
readonly requiredClassPoints?: number;
|
||||
readonly requiredSpecPoints?: number;
|
||||
readonly requiredLevel?: number;
|
||||
readonly isPassive?: boolean;
|
||||
}
|
||||
|
||||
export interface TalentUiCatalog {
|
||||
readonly schemaVersion: 1;
|
||||
readonly classId: ClassId;
|
||||
readonly trees: readonly TalentUiTree[];
|
||||
readonly nodes: readonly TalentUiNode[];
|
||||
}
|
||||
|
||||
interface TalentUiCatalogModule {
|
||||
readonly default: TalentUiCatalog;
|
||||
}
|
||||
|
||||
const shardLoaders = import.meta.glob<TalentUiCatalogModule>("./generated/talentUi/*.json");
|
||||
const loadCache = new Map<ClassId, Promise<TalentUiCatalog>>();
|
||||
|
||||
export function loadTalentUiCatalog(classId: ClassId): Promise<TalentUiCatalog> {
|
||||
const cached = loadCache.get(classId);
|
||||
if (cached) return cached;
|
||||
const key = `./generated/talentUi/${classId}.json`;
|
||||
const loader = shardLoaders[key];
|
||||
if (!loader) return Promise.reject(new Error(`No talent UI catalog exists for ${classId}.`));
|
||||
const pending = loader().then((module) => {
|
||||
if (module.default.schemaVersion !== 1 || module.default.classId !== classId) {
|
||||
throw new Error(`Talent UI catalog ${classId} has incompatible metadata.`);
|
||||
}
|
||||
return module.default;
|
||||
}).catch((error: unknown) => {
|
||||
loadCache.delete(classId);
|
||||
throw error;
|
||||
});
|
||||
loadCache.set(classId, pending);
|
||||
return pending;
|
||||
}
|
||||
|
||||
export function talentUiDescriptionForRank(node: TalentUiNode, rank: number): string {
|
||||
const normalizedRank = Math.min(
|
||||
node.maxRank,
|
||||
Math.max(1, Math.trunc(Number.isFinite(rank) ? rank : 1)),
|
||||
);
|
||||
return node.rankDescriptions[normalizedRank - 1] ?? node.description;
|
||||
}
|
||||
|
||||
export function talentUiTreeById(catalog: TalentUiCatalog, treeId: string): TalentUiTree | null {
|
||||
return catalog.trees.find((tree) => tree.id === treeId) ?? null;
|
||||
}
|
||||
|
||||
export function talentUiNodeById(catalog: TalentUiCatalog, nodeId: string): TalentUiNode | null {
|
||||
return catalog.nodes.find((node) => node.id === nodeId) ?? null;
|
||||
}
|
||||
|
||||
export function talentUiNodesForTree(catalog: TalentUiCatalog, treeId: string): readonly TalentUiNode[] {
|
||||
return catalog.nodes
|
||||
.filter((node) => node.treeId === treeId)
|
||||
.sort((left, right) => left.row - right.row || left.index - right.index);
|
||||
}
|
||||
Reference in new issue
Block a user