107 lines
3.8 KiB
TypeScript
107 lines
3.8 KiB
TypeScript
import {
|
|
mkdirSync,
|
|
readFileSync,
|
|
readdirSync,
|
|
unlinkSync,
|
|
writeFileSync,
|
|
} from "node:fs";
|
|
import { basename, resolve } from "node:path";
|
|
import {
|
|
CLASSES,
|
|
COA_CLASS_IDS,
|
|
type ClassId,
|
|
type CoaClassId,
|
|
} from "../src/app/characterCatalog";
|
|
import { TALENT_NODES, TALENT_TREES } from "../src/game/talentCatalog";
|
|
|
|
const projectRoot = resolve(import.meta.dirname, "..");
|
|
const talentOutputDirectory = resolve(projectRoot, "src/game/generated/talentUi");
|
|
const coaAbilityOutputDirectory = resolve(projectRoot, "src/game/generated/coaAbilities");
|
|
|
|
function writeJson(file: string, value: unknown): void {
|
|
writeFileSync(file, `${JSON.stringify(value)}\n`, "utf8");
|
|
console.log(`Wrote ${file}`);
|
|
}
|
|
|
|
function removeStaleJson(directory: string, expectedNames: ReadonlySet<string>): void {
|
|
for (const name of readdirSync(directory)) {
|
|
if (!name.endsWith(".json") || expectedNames.has(name)) continue;
|
|
unlinkSync(resolve(directory, name));
|
|
}
|
|
}
|
|
|
|
mkdirSync(talentOutputDirectory, { recursive: true });
|
|
const talentClassIds = new Set<ClassId>(TALENT_TREES.map((tree) => tree.classId));
|
|
const talentFileNames = new Set([...talentClassIds].map((classId) => `${classId}.json`));
|
|
removeStaleJson(talentOutputDirectory, talentFileNames);
|
|
|
|
for (const classId of talentClassIds) {
|
|
const trees = TALENT_TREES.filter((tree) => tree.classId === classId).map((tree) => ({
|
|
id: tree.id,
|
|
classId: tree.classId,
|
|
name: tree.name,
|
|
icon: tree.icon,
|
|
background: tree.background,
|
|
description: tree.description,
|
|
system: tree.system,
|
|
}));
|
|
const treeIds = new Set(trees.map((tree) => tree.id));
|
|
const nodes = TALENT_NODES.filter((node) => treeIds.has(node.treeId)).map((node) => ({
|
|
id: node.id,
|
|
treeId: node.treeId,
|
|
index: node.index,
|
|
prerequisiteId: node.prerequisiteId,
|
|
prerequisiteRank: node.prerequisiteRank,
|
|
prerequisites: node.prerequisites,
|
|
column: node.column,
|
|
row: node.row,
|
|
icon: node.icon,
|
|
maxRank: node.maxRank,
|
|
name: node.name,
|
|
description: node.description,
|
|
rankDescriptions: node.rankDescriptions,
|
|
system: node.system,
|
|
entryType: node.entryType,
|
|
abilityEssenceCost: node.abilityEssenceCost,
|
|
talentEssenceCost: node.talentEssenceCost,
|
|
requiredClassPoints: node.requiredClassPoints,
|
|
requiredSpecPoints: node.requiredSpecPoints,
|
|
requiredLevel: node.requiredLevel,
|
|
isPassive: node.isPassive,
|
|
}));
|
|
writeJson(resolve(talentOutputDirectory, `${classId}.json`), {
|
|
schemaVersion: 1,
|
|
classId,
|
|
trees,
|
|
nodes,
|
|
});
|
|
}
|
|
|
|
interface CoaAbilitySnapshot {
|
|
readonly schemaVersion: 1;
|
|
readonly abilitiesByClass: Readonly<Record<CoaClassId, readonly unknown[]>>;
|
|
readonly resourcesByClass: Readonly<Record<CoaClassId, unknown>>;
|
|
readonly triggeredAbilitiesBySpellId: Readonly<Record<string, { readonly classId?: ClassId }>>;
|
|
}
|
|
|
|
const coaAbilityInput = resolve(projectRoot, "src/game/generated/coaAbilityRuntimeCatalog.json");
|
|
const coaSnapshot = JSON.parse(readFileSync(coaAbilityInput, "utf8")) as CoaAbilitySnapshot;
|
|
mkdirSync(coaAbilityOutputDirectory, { recursive: true });
|
|
const coaAbilityFileNames = new Set(COA_CLASS_IDS.map((classId) => `${classId}.json`));
|
|
removeStaleJson(coaAbilityOutputDirectory, coaAbilityFileNames);
|
|
|
|
for (const classId of COA_CLASS_IDS) {
|
|
const triggeredAbilitiesBySpellId = Object.fromEntries(Object.entries(
|
|
coaSnapshot.triggeredAbilitiesBySpellId,
|
|
).filter(([, ability]) => ability.classId === classId));
|
|
writeJson(resolve(coaAbilityOutputDirectory, `${classId}.json`), {
|
|
schemaVersion: 1,
|
|
classId,
|
|
abilities: coaSnapshot.abilitiesByClass[classId] ?? [],
|
|
resource: coaSnapshot.resourcesByClass[classId],
|
|
triggeredAbilitiesBySpellId,
|
|
});
|
|
}
|
|
|
|
console.log(`Generated ${talentFileNames.size} talent UI shards and ${coaAbilityFileNames.size} Conquest ability shards from ${basename(coaAbilityInput)}.`);
|