forked from phenom/healer-man
Release Healer Man 0.1.8
This commit is contained in:
1 parent
eca6b5db9b
commit
c245a199b6
90 files changed
+8249
-232
No files matched your search
@@ -5,6 +5,61 @@ import generated from "./generated/dungeonCampaignCatalog.json";
|
||||
import manastormPackages from "./generated/manastormAssetPackages.json";
|
||||
import { DUNGEON_DEFINITIONS, requireDungeonDefinition } from "./dungeonRegistry";
|
||||
|
||||
const SOURCE_NATIVE_DUNGEON_IDS = [
|
||||
"ahnkahet-old-kingdom",
|
||||
"arcatraz",
|
||||
"auchenai-crypts",
|
||||
"azjol-nerub",
|
||||
"black-morass",
|
||||
"blackfathom-deeps",
|
||||
"blackrock-depths",
|
||||
"blackrock-spire",
|
||||
"blood-furnace",
|
||||
"botanica",
|
||||
"culling-of-stratholme",
|
||||
"draktharon-keep",
|
||||
"escape-from-durnholde",
|
||||
"forge-of-souls",
|
||||
"gnomeregan",
|
||||
"gundrak",
|
||||
"halls-of-lightning",
|
||||
"halls-of-reflection",
|
||||
"halls-of-stone",
|
||||
"magisters-terrace",
|
||||
"mana-tombs",
|
||||
"maraudon",
|
||||
"mechanar",
|
||||
"pit-of-saron",
|
||||
"ragefire-chasm",
|
||||
"scarlet-monastery",
|
||||
"sethekk-halls",
|
||||
"shadow-labyrinth",
|
||||
"shadowfang-keep",
|
||||
"shattered-halls",
|
||||
"slave-pens",
|
||||
"steamvault",
|
||||
"stormwind-stockade",
|
||||
"sunken-temple",
|
||||
"the-nexus",
|
||||
"the-oculus",
|
||||
"trial-of-the-champion",
|
||||
"uldaman",
|
||||
"underbog",
|
||||
"utgarde-keep",
|
||||
"utgarde-pinnacle",
|
||||
"violet-hold",
|
||||
"zulfarrak",
|
||||
] as const;
|
||||
|
||||
const WDT_PLACEMENT_DUNGEON_IDS = [
|
||||
"dire-maul",
|
||||
"hellfire-ramparts",
|
||||
"razorfen-downs",
|
||||
"razorfen-kraul",
|
||||
"scholomance",
|
||||
"stratholme",
|
||||
] as const;
|
||||
|
||||
describe("generated dungeon campaign catalog", () => {
|
||||
it("covers only reviewed five-player instances with loadable assets and combat content", () => {
|
||||
expect(generated.definitions).toHaveLength(54);
|
||||
@@ -240,17 +295,124 @@ describe("generated dungeon campaign catalog", () => {
|
||||
expect(targorr?.position).toEqual([-159.582, -25.6062, 1.2531]);
|
||||
});
|
||||
|
||||
it("starts Ragefire Chasm in the dungeon instead of the Orgrimmar portal annex", () => {
|
||||
const ragefire = requireDungeonDefinition("ragefire-chasm");
|
||||
const firstSpawn = ragefire.staticSpawns.find(
|
||||
(spawn) => spawn.id === "creature-38041",
|
||||
);
|
||||
const jergosh = ragefire.staticSpawns.find(
|
||||
(spawn) => spawn.id === "creature-48740",
|
||||
);
|
||||
|
||||
expect(ragefire.environmentMode).toBe("global-wmo");
|
||||
expect(ragefire.provenance.coordinateTransform)
|
||||
.toBe("three(x,y,z)=draft(x,y,z)");
|
||||
expect(ragefire.entrance.footPosition).toEqual([-3.81, -17.84, -14.82]);
|
||||
expect(firstSpawn?.position).toEqual([45.0298, -21.2917, -27.7645]);
|
||||
expect(jergosh?.position).toEqual([376.811, -21.801, 209.224]);
|
||||
});
|
||||
|
||||
it("keeps every navigation-audited dungeon in its native source coordinates", () => {
|
||||
const sourceAligned = generated.definitions
|
||||
.filter((dungeon) => dungeon.provenance.coordinateAlignment === "source")
|
||||
.map((dungeon) => dungeon.id)
|
||||
.sort();
|
||||
|
||||
expect(sourceAligned).toEqual([...SOURCE_NATIVE_DUNGEON_IDS].sort());
|
||||
for (const dungeonId of SOURCE_NATIVE_DUNGEON_IDS) {
|
||||
const dungeon = requireDungeonDefinition(dungeonId);
|
||||
expect(dungeon.provenance.coordinateAlignment, dungeonId).toBe("source");
|
||||
expect(dungeon.provenance.coordinateTransform, dungeonId)
|
||||
.not.toContain("package-anchor-translation");
|
||||
expect(
|
||||
dungeon.validation.warnings.some((warning) => (
|
||||
warning.includes("native world coordinates")
|
||||
)),
|
||||
dungeonId,
|
||||
).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("pins representative global-WMO and ADT entrances to their source basis", () => {
|
||||
const expectedEntrances = {
|
||||
"blackfathom-deeps": [151.89, -39.87, 106.96],
|
||||
"blackrock-depths": [-456.929, -68.0896, 34.0923],
|
||||
"blood-furnace": [3.9967, -44.8009, 14.6363],
|
||||
"the-nexus": [-145.87, -16.636, -10.554],
|
||||
"violet-hold": [803.93, 44.364, 1808.82],
|
||||
"black-morass": [7034.7, 32.5619, -1496.24],
|
||||
"culling-of-stratholme": [556.92, 36.69, 1431.1],
|
||||
} as const;
|
||||
|
||||
for (const [dungeonId, expected] of Object.entries(expectedEntrances)) {
|
||||
expect(requireDungeonDefinition(dungeonId).entrance.footPosition, dungeonId)
|
||||
.toEqual(expected);
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps scripted Trial of the Champion objectives on the native arena floor", () => {
|
||||
const trial = requireDungeonDefinition("trial-of-the-champion");
|
||||
const [entranceX, , entranceZ] = trial.entrance.footPosition;
|
||||
|
||||
expect(trial.objectiveOrder).toHaveLength(5);
|
||||
for (const objective of trial.objectiveOrder) {
|
||||
expect(objective.position[1], objective.name).toBeGreaterThanOrEqual(411);
|
||||
expect(objective.position[1], objective.name).toBeLessThanOrEqual(413);
|
||||
expect(
|
||||
Math.hypot(objective.position[0] - entranceX, objective.position[2] - entranceZ),
|
||||
objective.name,
|
||||
).toBeLessThan(150);
|
||||
}
|
||||
});
|
||||
|
||||
it("uses client WDT placement records for rotated or translated root WMOs", () => {
|
||||
for (const dungeonId of WDT_PLACEMENT_DUNGEON_IDS) {
|
||||
expect(
|
||||
requireDungeonDefinition(dungeonId).provenance.coordinateAlignment,
|
||||
dungeonId,
|
||||
).toBe("source-transform");
|
||||
expect(
|
||||
requireDungeonDefinition(dungeonId).provenance.coordinateTransform,
|
||||
dungeonId,
|
||||
).toContain("rotate-y");
|
||||
expect(
|
||||
requireDungeonDefinition(dungeonId).provenance.coordinateTransform,
|
||||
dungeonId,
|
||||
).not.toContain("package-anchor-translation");
|
||||
}
|
||||
});
|
||||
|
||||
it("pins every map found by the portal-map coordinate audit to its dungeon entrance", () => {
|
||||
const expectedEntrances = {
|
||||
arcatraz: [1.2316, -0.2043, 0.0143],
|
||||
"dire-maul": [44.4499, -2.712, 154.822],
|
||||
"hellfire-ramparts": [5.7204, 129.1393, -94.4661],
|
||||
"razorfen-downs": [-190.2691, -10.71, -100.8219],
|
||||
"razorfen-kraul": [-37.901, -5.684, 22.7908],
|
||||
"scarlet-monastery": [1053.48, 18.6775, 1688.99],
|
||||
scholomance: [-55.0407, -13.1583, 20.4141],
|
||||
"shadowfang-keep": [2109.18, 76.8898, -229.135],
|
||||
stratholme: [-143.4892, -5.8848, -266.8634],
|
||||
zulfarrak: [841.59, 8.93, 1213.52],
|
||||
} as const;
|
||||
|
||||
for (const [dungeonId, expected] of Object.entries(expectedEntrances)) {
|
||||
expect(requireDungeonDefinition(dungeonId).entrance.footPosition, dungeonId)
|
||||
.toEqual(expected);
|
||||
}
|
||||
});
|
||||
|
||||
it("starts Razorfen Kraul inside the portal and maps its first pack into the WMO", () => {
|
||||
const razorfenKraul = requireDungeonDefinition("razorfen-kraul");
|
||||
const firstPackSpawn = razorfenKraul.staticSpawns.find(
|
||||
(spawn) => spawn.id === "creature-87284",
|
||||
);
|
||||
|
||||
expect(razorfenKraul.entrance.footPosition).toEqual([-33.81, -5.2481, 21.522]);
|
||||
expect(razorfenKraul.entrance.footPosition).toEqual([-37.901, -5.684, 22.7908]);
|
||||
expect(firstPackSpawn).toBeTruthy();
|
||||
expect(firstPackSpawn!.position[0]).toBeGreaterThan(razorfenKraul.entrance.footPosition[0]);
|
||||
expect(firstPackSpawn!.position[0]).toBeLessThan(100);
|
||||
expect(razorfenKraul.provenance.coordinateTransform)
|
||||
.toBe("three(x,y,z)=(-draft.x,draft.y,draft.z)+package-anchor-translation");
|
||||
.toBe("three(x,y,z)=rotate-y(draft(x,y,z)-[-1952.1803,87.684,1587.8923],-133deg)");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user