Update Healer Man server

This commit is contained in:
phenom committed 2026-09-24 16:42:43 -04:00
1 parent a64b2cb575
commit 71246e5b75
502 files changed
+4245 -19

No files matched your search

@@ -1,5 +1,6 @@
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
@@ -8,6 +9,7 @@ import {
decodeWotlkSpellVisualKitRow,
parseDbc,
parseRunewakerImageRecords,
runewakerSoundPathsForModel,
} from "./generate-manifest.mjs";
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
@@ -180,6 +182,26 @@ test("classifies paths from fixed RuneWaker ImageObject records", () => {
assert.deepEqual(records.get(573727), ["model/fx/skill/fire/act_fireball01_f_i.ros"]);
});
test("matches RuneWaker sound siblings without guessing unrelated cues", () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rom-sound-fixture-"));
try {
const soundRoot = path.join(root, "sound", "fx", "skill", "fire");
fs.mkdirSync(soundRoot, { recursive: true });
fs.writeFileSync(path.join(soundRoot, "act_fireball_t_hit.ros.mp3"), "fixture");
assert.deepEqual(runewakerSoundPathsForModel(
"model/fx/skill/fire/act_fireball_t_hit.ros", root,
), ["sound/fx/skill/fire/act_fireball_t_hit.ros.mp3"]);
assert.deepEqual(runewakerSoundPathsForModel(
"model/fx/skill/fire/act_other_t_hit.ros", root,
), []);
assert.deepEqual(runewakerSoundPathsForModel(
"model/../../sound/fx/skill/fire/act_fireball_t_hit.ros", root,
), []);
} finally {
fs.rmSync(root, { recursive: true, force: true });
}
});
test("decodes WotLK MD20 particle tracks from their real record offsets", () => {
const decoded = decodeWotlkM2Effects(wotlkParticleFixture(), "fixture");
const particle = decoded.particles[0];
@@ -320,3 +342,45 @@ test("generated coverage packages every referenced source sound", () => {
assert.ok(fs.existsSync(path.join(projectRoot, "public", sound.url)));
}
});
test("primary-five RuneWaker spells retain source phases and packaged sound cues", () => {
const manifest = JSON.parse(fs.readFileSync(path.join(projectRoot, "public/assets/game/combat-effects/manifest.json"), "utf8"));
const entry = (id) => manifest.entries.find((candidate) => candidate.key === `runewaker:${id}`);
assert.ok(entry(490261).phases["cast-start"].some((asset) => asset.model === "model/fx/skill/holy/act_casting_c_hand.ros"));
assert.ok(entry(490261).sounds.some((sound) => sound.phase === "cast-start" && sound.url));
assert.ok(entry(491128).phases.release.some((asset) => asset.model.includes("act_gustwindarrow_f_hit_point_i.ros")));
assert.ok(entry(491128).phases.impact.some((asset) => asset.model.includes("act_gustwindarrow_t_hit_point_e.ros")));
assert.ok(entry(490495).sounds.some((sound) => sound.sourcePath === "sound/fx/skill/holy/act_godshield_c_down.mp3"));
});
test("only browser-verified RuneWaker particle phases use original graphs", () => {
const manifest = JSON.parse(fs.readFileSync(path.join(projectRoot, "public/assets/game/combat-effects/manifest.json"), "utf8"));
const expected = new Set([
"491147:cast-start:model/fx/skill/holy/act_casting_c_hand.ros",
"490261:cast-start:model/fx/skill/holy/act_casting_c_hand.ros",
"490281:cast-start:model/fx/skill/holy/act_casting_c_hand.ros",
"490150:cast-start:model/fx/skill/physical/act_charge02_c_down.ros",
"490175:impact:model/fx/hit_fx/act_shieldstorm_t_freeze_hit_e.ros",
"491168:release:model/fx/skill/wind/act_electric_ball_f_i.ros",
]);
const actual = new Set();
for (const entry of manifest.entries.filter((candidate) => candidate.source === "runewaker")) {
for (const [phase, assets] of Object.entries(entry.phases ?? {})) for (const asset of assets) {
if (!asset.effectGraphUrl) continue;
const key = `${entry.spellId}:${phase}:${asset.model}`;
actual.add(key);
assert.equal(asset.effectKind, "runewaker-particles");
if (entry.spellId === 490175) assert.equal(asset.scale, 2.5);
const graph = JSON.parse(fs.readFileSync(path.join(projectRoot, "public", asset.effectGraphUrl.slice(1)), "utf8"));
assert.equal(graph.rendererReady, true);
assert.equal(graph.sourceModel, asset.model);
}
}
assert.deepEqual(actual, expected);
for (const spellId of [491147, 490261, 490281]) {
const entry = manifest.entries.find((candidate) => candidate.key === `runewaker:${spellId}`);
assert.ok(entry.sounds.some((sound) => sound.phase === "cast-start"
&& sound.sourcePath === "sound/fx/skill/holy/act_casting_c_hand.wav"
&& sound.loopDuringCast === true));
}
});