forked from phenom/healer-man
89 lines
3.1 KiB
TypeScript
89 lines
3.1 KiB
TypeScript
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
import { dirname, resolve } from "node:path";
|
|
import { CLASSES, type CoaClassId } from "../src/app/characterCatalog";
|
|
import {
|
|
COA_ABILITIES_BY_CLASS,
|
|
COA_CLASS_RESOURCES,
|
|
COA_TRIGGERED_ABILITIES_BY_SPELL_ID,
|
|
} from "../src/game/coaAbilityCatalog";
|
|
import {
|
|
COA_LIVE_SOURCE,
|
|
coaClassDefinition,
|
|
} from "../src/game/coaLiveCatalog";
|
|
import {
|
|
TALENT_NODES,
|
|
TALENT_TREES,
|
|
} from "../src/game/talentCatalog";
|
|
|
|
function writeJson(path: string, value: unknown): void {
|
|
const outputPath = resolve(path);
|
|
mkdirSync(dirname(outputPath), { recursive: true });
|
|
writeFileSync(outputPath, `${JSON.stringify(value)}\n`, "utf8");
|
|
console.log(`Wrote ${outputPath}`);
|
|
}
|
|
|
|
writeJson("src/game/generated/coaAbilityRuntimeCatalog.json", {
|
|
schemaVersion: 1,
|
|
abilitiesByClass: COA_ABILITIES_BY_CLASS,
|
|
resourcesByClass: COA_CLASS_RESOURCES,
|
|
triggeredAbilitiesBySpellId: COA_TRIGGERED_ABILITIES_BY_SPELL_ID,
|
|
});
|
|
|
|
const coaBudgetsByClass = Object.fromEntries(CLASSES
|
|
.filter((definition) => definition.mode === "conquest")
|
|
.map((definition) => {
|
|
const classId = definition.id as CoaClassId;
|
|
const live = coaClassDefinition(classId);
|
|
return [classId, {
|
|
maximumAbility: live.maxAbilityEssence,
|
|
maximumTalent: live.maxTalentEssence,
|
|
}];
|
|
}));
|
|
|
|
const talentSnapshot = {
|
|
schemaVersion: 1,
|
|
maximumCoaLevel: COA_LIVE_SOURCE.maximumLevel,
|
|
coaBudgetsByClass,
|
|
trees: TALENT_TREES.map(({ id, classId }) => ({ id, classId })),
|
|
nodes: TALENT_NODES.map((node) => ({
|
|
id: node.id,
|
|
treeId: node.treeId,
|
|
index: node.index,
|
|
row: node.row,
|
|
maxRank: node.maxRank,
|
|
name: node.name,
|
|
prerequisites: node.prerequisites,
|
|
rankDescriptions: node.rankDescriptions,
|
|
system: node.system,
|
|
abilityEssenceCost: node.abilityEssenceCost,
|
|
talentEssenceCost: node.talentEssenceCost,
|
|
requiredClassPoints: node.requiredClassPoints,
|
|
requiredSpecPoints: node.requiredSpecPoints,
|
|
requiredLevel: node.requiredLevel,
|
|
isPassive: node.isPassive,
|
|
})),
|
|
};
|
|
|
|
if (process.argv.includes("--coa-only")) {
|
|
const previous = JSON.parse(readFileSync("src/game/generated/talentRuntimeCatalog.json", "utf8"));
|
|
const coaClasses = new Set(CLASSES.filter((definition) => definition.mode === "conquest").map((definition) => definition.id));
|
|
const coaTrees = new Set(talentSnapshot.trees.filter((tree) => coaClasses.has(tree.classId)).map((tree) => tree.id));
|
|
function replaceCoa<T>(oldRecords: T[], newRecords: T[], isCoa: (record: T) => boolean): T[] {
|
|
const result: T[] = [];
|
|
let inserted = false;
|
|
for (const record of oldRecords) {
|
|
if (!isCoa(record)) result.push(record);
|
|
else if (!inserted) {
|
|
result.push(...newRecords.filter(isCoa));
|
|
inserted = true;
|
|
}
|
|
}
|
|
if (!inserted) result.push(...newRecords.filter(isCoa));
|
|
return result;
|
|
}
|
|
talentSnapshot.trees = replaceCoa(previous.trees, talentSnapshot.trees, (tree) => coaClasses.has(tree.classId));
|
|
talentSnapshot.nodes = replaceCoa(previous.nodes, talentSnapshot.nodes, (node) => coaTrees.has(node.treeId));
|
|
}
|
|
|
|
writeJson("src/game/generated/talentRuntimeCatalog.json", talentSnapshot);
|