forked from phenom/healer-man
Update class mechanics, stat rulesets, and CoA reference catalogs
This commit is contained in:
1 parent
b16821e92e
commit
39458d5de6
221 files changed
+2584962
-568
No files matched your search
@@ -0,0 +1,99 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const dbcDirectory = (root, patch, fileName) => path.join(root, patch, "DBFilesClient", fileName);
|
||||
|
||||
function firstExisting(candidates, exists) {
|
||||
return candidates.find((candidate) => exists(candidate)) ?? candidates.at(-1);
|
||||
}
|
||||
|
||||
/** Resolve independent source paths for classic and CoA data in the combined importer. */
|
||||
export function resolveCoaSourcePaths({
|
||||
extractedClientRoot,
|
||||
legacyExtractedRoot,
|
||||
classicSpellOverride,
|
||||
exists = fs.existsSync,
|
||||
}) {
|
||||
const area52Spell = dbcDirectory(path.join(extractedClientRoot, "area-52"), "patch-D", "Spell.dbc");
|
||||
const globalSpell = dbcDirectory(extractedClientRoot, "patch-T", "Spell.dbc");
|
||||
const legacySpell = dbcDirectory(legacyExtractedRoot, "patch-T", "Spell.dbc");
|
||||
const area52SkillLineAbility = dbcDirectory(
|
||||
path.join(extractedClientRoot, "area-52"),
|
||||
"patch-D",
|
||||
"SkillLineAbility.dbc",
|
||||
);
|
||||
const globalSkillLineAbility = dbcDirectory(extractedClientRoot, "patch-M", "SkillLineAbility.dbc");
|
||||
const legacySkillLineAbility = dbcDirectory(legacyExtractedRoot, "patch-M", "SkillLineAbility.dbc");
|
||||
|
||||
const classicSpellDbcPath = classicSpellOverride
|
||||
? path.resolve(classicSpellOverride)
|
||||
: firstExisting([area52Spell, globalSpell, legacySpell], exists);
|
||||
const classicSiblingSkillLineAbility = path.join(path.dirname(classicSpellDbcPath), "SkillLineAbility.dbc");
|
||||
|
||||
return {
|
||||
classicSpellDbcPath,
|
||||
classicSkillLineAbilityDbcPath: exists(classicSiblingSkillLineAbility)
|
||||
? classicSiblingSkillLineAbility
|
||||
: firstExisting([area52SkillLineAbility, globalSkillLineAbility, legacySkillLineAbility], exists),
|
||||
coaSpellDbcPath: firstExisting([globalSpell, legacySpell], exists),
|
||||
coaSkillLineAbilityDbcPath: firstExisting([globalSkillLineAbility, legacySkillLineAbility], exists),
|
||||
};
|
||||
}
|
||||
|
||||
/** Collect DBC IDs whose classic metadata must remain available beside CoA metadata. */
|
||||
export function collectRealmSpellIds({
|
||||
classicClassIds,
|
||||
coaClassIds,
|
||||
classSpellRows,
|
||||
classicRankCandidates,
|
||||
coaRankCandidates,
|
||||
coaEntrySpellIds,
|
||||
}) {
|
||||
const classicIds = new Set();
|
||||
const coaIds = new Set(coaEntrySpellIds ?? []);
|
||||
const classicClasses = new Set(classicClassIds);
|
||||
const coaClasses = new Set(coaClassIds);
|
||||
|
||||
for (const row of classSpellRows) {
|
||||
if (classicClasses.has(row.classId)) classicIds.add(row.id);
|
||||
if (coaClasses.has(row.classId)) coaIds.add(row.id);
|
||||
}
|
||||
for (const candidate of classicRankCandidates) classicIds.add(candidate.id);
|
||||
for (const candidate of coaRankCandidates) coaIds.add(candidate.id);
|
||||
|
||||
return { classicIds, coaIds };
|
||||
}
|
||||
|
||||
/** Return IDs that need a separate CoA wrapper to protect classic metadata. */
|
||||
export function sharedRealmSpellIds(classicIds, coaIds) {
|
||||
return [...coaIds].filter((spellId) => classicIds.has(spellId)).sort((left, right) => left - right);
|
||||
}
|
||||
|
||||
/** Include linked base-client payloads, including effect 168's miscValue spell. */
|
||||
export function expandCoaSpellIds(buffer, initialIds) {
|
||||
if (buffer.length < 20 || buffer.toString("ascii", 0, 4) !== "WDBC" || buffer.readUInt32LE(8) < 234) throw new Error("CoA Spell.dbc does not expose the 234-field WDBC schema");
|
||||
const recordCount = buffer.readUInt32LE(4);
|
||||
const recordSize = buffer.readUInt32LE(12);
|
||||
if (recordSize < 234 * 4 || 20 + recordCount * recordSize > buffer.length) throw new Error("CoA Spell.dbc has invalid record lengths");
|
||||
const rows = new Map();
|
||||
for (let index = 0; index < recordCount; index += 1) {
|
||||
const base = 20 + index * recordSize;
|
||||
const id = buffer.readUInt32LE(base);
|
||||
if (!rows.has(id)) rows.set(id, base);
|
||||
}
|
||||
const ids = new Set(initialIds);
|
||||
const queue = [...ids];
|
||||
for (let cursor = 0; cursor < queue.length; cursor += 1) {
|
||||
const base = rows.get(queue[cursor]);
|
||||
if (base === undefined) continue;
|
||||
for (let index = 0; index < 3; index += 1) {
|
||||
const childId = buffer.readUInt32LE(base + (116 + index) * 4)
|
||||
|| (buffer.readUInt32LE(base + (71 + index) * 4) === 168 ? buffer.readUInt32LE(base + (110 + index) * 4) : 0);
|
||||
if (childId > 0 && !ids.has(childId)) {
|
||||
ids.add(childId);
|
||||
queue.push(childId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
Reference in new issue
Block a user