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,114 @@
|
||||
import assert from "node:assert/strict";
|
||||
import path from "node:path";
|
||||
import test from "node:test";
|
||||
import {
|
||||
collectRealmSpellIds,
|
||||
expandCoaSpellIds,
|
||||
resolveCoaSourcePaths,
|
||||
sharedRealmSpellIds,
|
||||
} from "./coa-source-policy.mjs";
|
||||
|
||||
test("CoA payload closure includes effect-168 links, cycles and absent IDs without overlay fallback", () => {
|
||||
const buffer = Buffer.alloc(20 + 3 * 234 * 4);
|
||||
buffer.write("WDBC");
|
||||
buffer.writeUInt32LE(3, 4);
|
||||
buffer.writeUInt32LE(234, 8);
|
||||
buffer.writeUInt32LE(234 * 4, 12);
|
||||
const write = (row, field, value) => buffer.writeUInt32LE(value, 20 + (row * 234 + field) * 4);
|
||||
write(0, 0, 100);
|
||||
write(0, 71, 168);
|
||||
write(0, 110, 200);
|
||||
write(1, 0, 200);
|
||||
write(1, 116, 300);
|
||||
write(2, 0, 300);
|
||||
write(2, 116, 100);
|
||||
write(2, 117, 400);
|
||||
assert.deepEqual([...expandCoaSpellIds(buffer, [100])], [100, 200, 300, 400]);
|
||||
assert.throws(() => expandCoaSpellIds(Buffer.from("invalid"), [100]), /234-field/);
|
||||
});
|
||||
|
||||
test("CoA source resolution selects global patch-T and patch-M while classic keeps Area52 priority", () => {
|
||||
const root = path.resolve("fixture/client-current");
|
||||
const legacy = path.resolve("fixture/legacy");
|
||||
const exists = new Set([
|
||||
path.join(root, "area-52", "patch-D", "DBFilesClient", "Spell.dbc"),
|
||||
path.join(root, "area-52", "patch-D", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
path.join(root, "patch-T", "DBFilesClient", "Spell.dbc"),
|
||||
path.join(root, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
path.join(legacy, "patch-T", "DBFilesClient", "Spell.dbc"),
|
||||
path.join(legacy, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
]);
|
||||
const sources = resolveCoaSourcePaths({
|
||||
extractedClientRoot: root,
|
||||
legacyExtractedRoot: legacy,
|
||||
exists: (candidate) => exists.has(candidate),
|
||||
});
|
||||
|
||||
assert.equal(sources.classicSpellDbcPath, path.join(root, "area-52", "patch-D", "DBFilesClient", "Spell.dbc"));
|
||||
assert.equal(sources.classicSkillLineAbilityDbcPath, path.join(root, "area-52", "patch-D", "DBFilesClient", "SkillLineAbility.dbc"));
|
||||
assert.equal(sources.coaSpellDbcPath, path.join(root, "patch-T", "DBFilesClient", "Spell.dbc"));
|
||||
assert.equal(sources.coaSkillLineAbilityDbcPath, path.join(root, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"));
|
||||
});
|
||||
|
||||
test("CoA sources fall back only to global legacy files, never Area52", () => {
|
||||
const root = path.resolve("fixture/client-current");
|
||||
const legacy = path.resolve("fixture/legacy");
|
||||
const exists = new Set([
|
||||
path.join(root, "area-52", "patch-D", "DBFilesClient", "Spell.dbc"),
|
||||
path.join(root, "area-52", "patch-D", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
path.join(legacy, "patch-T", "DBFilesClient", "Spell.dbc"),
|
||||
path.join(legacy, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
]);
|
||||
const sources = resolveCoaSourcePaths({
|
||||
extractedClientRoot: root,
|
||||
legacyExtractedRoot: legacy,
|
||||
exists: (candidate) => exists.has(candidate),
|
||||
});
|
||||
|
||||
assert.equal(sources.coaSpellDbcPath, path.join(legacy, "patch-T", "DBFilesClient", "Spell.dbc"));
|
||||
assert.equal(sources.coaSkillLineAbilityDbcPath, path.join(legacy, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"));
|
||||
});
|
||||
|
||||
test("classic SkillLineAbility follows the selected Spell.dbc when that sibling exists", () => {
|
||||
const root = path.resolve("fixture/client-current");
|
||||
const legacy = path.resolve("fixture/legacy");
|
||||
const exists = new Set([
|
||||
path.join(root, "area-52", "patch-D", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
path.join(root, "patch-T", "DBFilesClient", "Spell.dbc"),
|
||||
path.join(root, "patch-T", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
path.join(root, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
path.join(legacy, "patch-T", "DBFilesClient", "Spell.dbc"),
|
||||
path.join(legacy, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
||||
]);
|
||||
const sources = resolveCoaSourcePaths({
|
||||
extractedClientRoot: root,
|
||||
legacyExtractedRoot: legacy,
|
||||
exists: (candidate) => exists.has(candidate),
|
||||
});
|
||||
|
||||
assert.equal(sources.classicSpellDbcPath, path.join(root, "patch-T", "DBFilesClient", "Spell.dbc"));
|
||||
assert.equal(sources.classicSkillLineAbilityDbcPath, path.join(root, "patch-T", "DBFilesClient", "SkillLineAbility.dbc"));
|
||||
});
|
||||
|
||||
test("realm spell ownership protects classic references and includes CoA tree ranks", () => {
|
||||
const { classicIds, coaIds } = collectRealmSpellIds({
|
||||
classicClassIds: [11],
|
||||
coaClassIds: [27],
|
||||
classSpellRows: [
|
||||
{ id: 100, classId: 11 },
|
||||
{ id: 200, classId: 27 },
|
||||
{ id: 300, classId: 27 },
|
||||
{ id: 400, classId: 11 },
|
||||
{ id: 400, classId: 27 },
|
||||
],
|
||||
classicRankCandidates: [{ id: 101 }],
|
||||
coaRankCandidates: [{ id: 201 }],
|
||||
coaEntrySpellIds: [300, 301],
|
||||
});
|
||||
|
||||
assert.deepEqual([...classicIds].sort(), [100, 101, 400]);
|
||||
assert.deepEqual([...coaIds].sort(), [200, 201, 300, 301, 400]);
|
||||
assert.ok(classicIds.has(100) && coaIds.has(300) && classicIds.has(400) && coaIds.has(400));
|
||||
assert.deepEqual(sharedRealmSpellIds(classicIds, coaIds), [400]);
|
||||
assert.deepEqual(sharedRealmSpellIds(new Set([401]), new Set([401])), [401]);
|
||||
});
|
||||
Reference in new issue
Block a user