Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c245a199b6 |
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/TempestKeepArcane",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/AuchindounDraenei",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "burning-crusade",
|
||||
"extraction": {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/Blackfathom",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [20, 30]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/BlackrockDepths",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [50, 60]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/BlackRockSpire",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/HellfireDemon",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [58, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/TempestKeepAtrium",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/DireMaul",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source-transform",
|
||||
"coordinateTransform": {"origin": [0, 0, 0], "yawDegrees": 180},
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [50, 60]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "burning-crusade",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/GnomeragonInstance",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [25, 40]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/HellfireRampart",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source-transform",
|
||||
"coordinateTransform": {"origin": [1262.4427, -60.8902, 1622.5397], "yawDegrees": 262.143},
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [58, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/Sunwell5ManFix",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [70, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/AuchindounEthereal",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/Mauradon",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [40, 55]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/TempestKeepFactory",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/OrgrimmarInstance",
|
||||
"environmentMode": "global-wmo",
|
||||
"globalWmoAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [13, 25]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/RazorfenDowns",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source-transform",
|
||||
"coordinateTransform": {"origin": [-2402.2809, 62, 1208.3219], "yawDegrees": 0},
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [35, 50]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/RazorfenKraulInstance",
|
||||
"environmentMode": "global-wmo",
|
||||
"globalWmoSourceBasis": "flip-x",
|
||||
"coordinateAlignment": "source-transform",
|
||||
"coordinateTransform": {"origin": [-1952.1803, 87.684, 1587.8923], "yawDegrees": -133},
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [25, 40]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"clientBuild": "3.3.5a",
|
||||
"mapDirectory": "World/Maps/MonasteryInstances",
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"adtSourceBasis": "z-y-negative-x",
|
||||
"difficultyVariants": [
|
||||
{ "id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [26, 45] }
|
||||
],
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/SchoolofNecromancy",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source-transform",
|
||||
"coordinateTransform": {"origin": [-141.694, 148.0683, 105.6784], "yawDegrees": 1},
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/AuchindounDemon",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/AuchindounShadow",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [65, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
"expansion": "classic",
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/Shadowfang",
|
||||
"environmentMode": "global-wmo",
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"adtSourceBasis": "z-y-negative-x",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [18, 30]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
"extraction": {"rootWmo": "World/wmo/Dungeon/LD_ShadowFang/LD_ShadowFang.wmo", "doodadSets": ["Set_$DefaultGlobal"]},
|
||||
"navigation": {"cellSize": 0.2, "cellHeight": 0.1, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50},
|
||||
"extraction": {"adtTiles": "all-present"},
|
||||
"navigation": {"cellSize": 0.2, "cellHeight": 0.1, "tileSize": 256, "retainTileIntermediates": false, "agentHeight": 1.8, "agentRadius": 0.36, "agentMaxClimb": 0.5, "agentMaxSlope": 50},
|
||||
"review": {"entrance": "required", "bossOrder": "required", "optionalEncounters": "required", "presentation": "required", "offMeshLinks": "required"},
|
||||
"exceptions": []
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/HellfireMilitary",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/CoilfangDraenei",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/CoilfangPumping",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/Stratholme",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source-transform",
|
||||
"coordinateTransform": {"origin": [-3449.6608, 144.3848, -3379.6966], "yawDegrees": 0},
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [55, 60]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/SunkenTemple",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [45, 55]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/Uldaman",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [
|
||||
{
|
||||
"id": "normal",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/CoilfangMarsh",
|
||||
"environmentMode": "global-wmo",
|
||||
"coordinateAlignment": "source",
|
||||
"difficultyVariants": [{"id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [60, 70]}],
|
||||
"clientSource": {"rootEnvironmentVariable": "WOW_CLIENT_ROOT", "relativeDefault": "../wow335a"},
|
||||
"serverSource": {"rootEnvironmentVariable": "WOW_SERVER_DATA", "adapter": "normalized-json", "readOnly": true},
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
}
|
||||
],
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"exceptions": [],
|
||||
"expansion": "wrath",
|
||||
"extraction": {
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
"clientBuild": "3.3.5a-Ascension",
|
||||
"mapDirectory": "World/Maps/TanarisInstance",
|
||||
"environmentMode": "detect",
|
||||
"coordinateAlignment": "source",
|
||||
"adtSourceBasis": "z-y-negative-x",
|
||||
"difficultyVariants": [
|
||||
{ "id": "normal", "difficulty": "normal", "spawnMask": 1, "levelRange": [40, 54] }
|
||||
],
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "healer-man",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "healer-man",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.8",
|
||||
"dependencies": {
|
||||
"@capacitor/android": "8.4.1",
|
||||
"@capacitor/core": "8.4.1",
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "healer-man",
|
||||
"private": true,
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.8",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host 0.0.0.0",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"versionName": "0.1.7",
|
||||
"versionCode": 1007
|
||||
"versionName": "0.1.8",
|
||||
"versionCode": 1008
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { NodeIO } from "@gltf-transform/core";
|
||||
import { ALL_EXTENSIONS } from "@gltf-transform/extensions";
|
||||
import { BufferAttribute, BufferGeometry, Vector3 } from "three";
|
||||
import { MeshBVH } from "three-mesh-bvh";
|
||||
import { MeshoptDecoder } from "meshoptimizer";
|
||||
|
||||
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
||||
const campaign = await import("../../src/game/generated/dungeonCampaignCatalog.json", {
|
||||
with: { type: "json" },
|
||||
}).then((module) => module.default);
|
||||
const useCollision = process.argv.includes("--collision");
|
||||
const requestedSlugs = new Set(process.argv.slice(2).filter((argument) => argument !== "--collision"));
|
||||
const definitions = campaign.definitions.filter((definition) => (
|
||||
!requestedSlugs.size || requestedSlugs.has(definition.id)
|
||||
));
|
||||
|
||||
if (!definitions.length) {
|
||||
throw new Error("No matching dungeon definitions. Pass one or more dungeon slugs.");
|
||||
}
|
||||
|
||||
await MeshoptDecoder.ready;
|
||||
const io = new NodeIO()
|
||||
.registerExtensions(ALL_EXTENSIONS)
|
||||
.registerDependencies({ "meshopt.decoder": MeshoptDecoder });
|
||||
const point = new Vector3();
|
||||
|
||||
function normalizerFor(accessor, array) {
|
||||
if (!accessor.getNormalized()) return (value) => value;
|
||||
if (array instanceof Int16Array) return (value) => Math.max(value / 32_767, -1);
|
||||
if (array instanceof Uint16Array) return (value) => value / 65_535;
|
||||
if (array instanceof Int8Array) return (value) => Math.max(value / 127, -1);
|
||||
if (array instanceof Uint8Array) return (value) => value / 255;
|
||||
return (value) => value;
|
||||
}
|
||||
|
||||
async function geometryTrees(file) {
|
||||
const document = await io.read(file);
|
||||
const trees = [];
|
||||
for (const node of document.getRoot().listNodes()) {
|
||||
const mesh = node.getMesh();
|
||||
if (!mesh) continue;
|
||||
const matrix = node.getWorldMatrix();
|
||||
for (const primitive of mesh.listPrimitives()) {
|
||||
const accessor = primitive.getAttribute("POSITION");
|
||||
const source = accessor?.getArray();
|
||||
if (!accessor || !source) continue;
|
||||
const normalize = normalizerFor(accessor, source);
|
||||
const positions = new Float32Array(source.length);
|
||||
for (let offset = 0; offset < source.length; offset += 3) {
|
||||
const x = normalize(source[offset]);
|
||||
const y = normalize(source[offset + 1]);
|
||||
const z = normalize(source[offset + 2]);
|
||||
positions[offset] = matrix[0] * x + matrix[4] * y + matrix[8] * z + matrix[12];
|
||||
positions[offset + 1] = matrix[1] * x + matrix[5] * y + matrix[9] * z + matrix[13];
|
||||
positions[offset + 2] = matrix[2] * x + matrix[6] * y + matrix[10] * z + matrix[14];
|
||||
}
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute("position", new BufferAttribute(positions, 3));
|
||||
const indices = primitive.getIndices()?.getArray();
|
||||
if (indices) geometry.setIndex(new BufferAttribute(indices, 1));
|
||||
trees.push(new MeshBVH(geometry));
|
||||
}
|
||||
}
|
||||
return trees;
|
||||
}
|
||||
|
||||
function nearestDistance(trees, position) {
|
||||
point.fromArray(position);
|
||||
let distance = Infinity;
|
||||
for (const tree of trees) {
|
||||
const result = tree.closestPointToPoint(point);
|
||||
distance = Math.min(distance, result?.distance ?? Infinity);
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
|
||||
function percentile(sorted, proportion) {
|
||||
return sorted[Math.min(sorted.length - 1, Math.floor(sorted.length * proportion))] ?? 0;
|
||||
}
|
||||
|
||||
const results = [];
|
||||
for (const definition of definitions) {
|
||||
const geometryUrls = useCollision
|
||||
? definition.assets.collision.map((chunk) => chunk.url)
|
||||
: [definition.assets.navigation.url];
|
||||
const trees = (await Promise.all(geometryUrls.map((url) => (
|
||||
geometryTrees(path.join(projectRoot, "public", url.replace(/^\//, "")))
|
||||
)))).flat();
|
||||
const samples = [
|
||||
{ id: "entrance", position: definition.entrance.footPosition },
|
||||
...definition.staticSpawns.map((spawn) => ({ id: spawn.id, position: spawn.position })),
|
||||
...definition.roamingPacks.flatMap((pack) => (
|
||||
pack.waypoints.map((position, index) => ({ id: `${pack.id}:${index}`, position }))
|
||||
)),
|
||||
];
|
||||
const distances = samples
|
||||
.map((sample) => ({ ...sample, distance: nearestDistance(trees, sample.position) }))
|
||||
.sort((left, right) => left.distance - right.distance);
|
||||
const values = distances.map((sample) => sample.distance);
|
||||
results.push({
|
||||
dungeonId: definition.id,
|
||||
geometry: useCollision ? "collision" : "navigation",
|
||||
coordinateAlignment: definition.provenance.coordinateAlignment,
|
||||
coordinateTransform: definition.provenance.coordinateTransform,
|
||||
samples: values.length,
|
||||
withinOneMeter: values.filter((distance) => distance <= 1).length,
|
||||
medianDistance: percentile(values, 0.5),
|
||||
p90Distance: percentile(values, 0.9),
|
||||
maximumDistance: values.at(-1) ?? 0,
|
||||
furthest: distances.slice(-5).reverse().map(({ id, position, distance }) => ({
|
||||
id,
|
||||
position,
|
||||
distance,
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(results, null, 2));
|
||||
@@ -175,6 +175,10 @@ function interpolate(left, right, alpha) {
|
||||
return left.map((value, axis) => rounded(value + (right[axis] - value) * alpha));
|
||||
}
|
||||
|
||||
function horizontalDistanceSquared(left, right) {
|
||||
return (left[0] - right[0]) ** 2 + (left[2] - right[2]) ** 2;
|
||||
}
|
||||
|
||||
function normalizedName(value) {
|
||||
return String(value ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "");
|
||||
}
|
||||
@@ -201,7 +205,7 @@ const ADT_SOURCE_BASES = new Set([
|
||||
"z-y-negative-x",
|
||||
]);
|
||||
const GLOBAL_WMO_SOURCE_BASES = new Set(["draft", "flip-x"]);
|
||||
const GLOBAL_WMO_ALIGNMENTS = new Set(["player-anchor", "source"]);
|
||||
const COORDINATE_ALIGNMENTS = new Set(["player-anchor", "source", "source-transform"]);
|
||||
|
||||
function sourceBasisFor(recipe, environmentMode) {
|
||||
if (environmentMode !== "adt-hybrid") {
|
||||
@@ -222,14 +226,42 @@ function sourceBasisFor(recipe, environmentMode) {
|
||||
}
|
||||
|
||||
function coordinateAlignmentFor(recipe, environmentMode) {
|
||||
if (environmentMode !== "global-wmo") return "player-anchor";
|
||||
const alignment = recipe.globalWmoAlignment ?? "player-anchor";
|
||||
if (!GLOBAL_WMO_ALIGNMENTS.has(alignment)) {
|
||||
throw new Error(`${recipe.slug}: unsupported global WMO alignment ${alignment}.`);
|
||||
const legacyGlobalWmoAlignment = environmentMode === "global-wmo"
|
||||
? recipe.globalWmoAlignment
|
||||
: undefined;
|
||||
if (
|
||||
recipe.coordinateAlignment
|
||||
&& legacyGlobalWmoAlignment
|
||||
&& recipe.coordinateAlignment !== legacyGlobalWmoAlignment
|
||||
) {
|
||||
throw new Error(`${recipe.slug}: coordinate alignment overrides disagree.`);
|
||||
}
|
||||
const alignment = recipe.coordinateAlignment ?? legacyGlobalWmoAlignment ?? "player-anchor";
|
||||
if (!COORDINATE_ALIGNMENTS.has(alignment)) {
|
||||
throw new Error(`${recipe.slug}: unsupported coordinate alignment ${alignment}.`);
|
||||
}
|
||||
return alignment;
|
||||
}
|
||||
|
||||
function sourceTransformFor(recipe, alignment) {
|
||||
const transform = recipe.coordinateTransform;
|
||||
if (alignment !== "source-transform") {
|
||||
if (transform) {
|
||||
throw new Error(`${recipe.slug}: coordinateTransform requires source-transform alignment.`);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
if (!transform || !Array.isArray(transform.origin) || transform.origin.length !== 3) {
|
||||
throw new Error(`${recipe.slug}: source-transform alignment requires a three-value coordinateTransform.origin.`);
|
||||
}
|
||||
const origin = transform.origin.map(Number);
|
||||
const yawDegrees = Number(transform.yawDegrees ?? 0);
|
||||
if (!origin.every(Number.isFinite) || !Number.isFinite(yawDegrees)) {
|
||||
throw new Error(`${recipe.slug}: coordinateTransform values must be finite numbers.`);
|
||||
}
|
||||
return { origin, yawDegrees };
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime drafts retain the original pipeline convention. wow.export ADT
|
||||
* packages have an additional horizontal basis change baked into their GLBs.
|
||||
@@ -248,10 +280,39 @@ function sourceToPackageBasis(position, environmentMode, sourceBasis) {
|
||||
: point;
|
||||
}
|
||||
|
||||
function coordinateMapper(draft, environmentMode, playerAnchor, sourceBasis, alignment) {
|
||||
function rotateAroundY(position, yawDegrees) {
|
||||
const radians = yawDegrees * Math.PI / 180;
|
||||
const cosine = Math.cos(radians);
|
||||
const sine = Math.sin(radians);
|
||||
return vector([
|
||||
position[0] * cosine - position[2] * sine,
|
||||
position[1],
|
||||
position[0] * sine + position[2] * cosine,
|
||||
]);
|
||||
}
|
||||
|
||||
function coordinateMapper(
|
||||
draft,
|
||||
environmentMode,
|
||||
playerAnchor,
|
||||
sourceBasis,
|
||||
alignment,
|
||||
sourceTransform,
|
||||
) {
|
||||
if (alignment === "source") {
|
||||
return (position) => sourceToPackageBasis(position, environmentMode, sourceBasis);
|
||||
}
|
||||
if (alignment === "source-transform") {
|
||||
const basisOrigin = sourceToPackageBasis(
|
||||
sourceTransform.origin,
|
||||
environmentMode,
|
||||
sourceBasis,
|
||||
);
|
||||
return (position) => rotateAroundY(
|
||||
subtract(sourceToPackageBasis(position, environmentMode, sourceBasis), basisOrigin),
|
||||
sourceTransform.yawDegrees,
|
||||
);
|
||||
}
|
||||
const sourceEntrance = draft?.entrance
|
||||
?? draft?.spawns?.[0]?.position
|
||||
?? playerAnchor.position;
|
||||
@@ -778,6 +839,7 @@ async function compile() {
|
||||
const environmentMode = inferEnvironmentMode(recipe, assetPackage);
|
||||
const sourceBasis = sourceBasisFor(recipe, environmentMode);
|
||||
const coordinateAlignment = coordinateAlignmentFor(recipe, environmentMode);
|
||||
const sourceTransform = sourceTransformFor(recipe, coordinateAlignment);
|
||||
const playerAnchor = assetPackage.anchors.find((anchor) => anchor.kind === "player");
|
||||
const trashAnchor = assetPackage.anchors.find((anchor) => anchor.kind === "trash");
|
||||
const bossAnchor = assetPackage.anchors.find((anchor) => anchor.kind === "boss");
|
||||
@@ -788,7 +850,7 @@ async function compile() {
|
||||
trashAnchor.position[0] - playerAnchor.position[0],
|
||||
trashAnchor.position[2] - playerAnchor.position[2],
|
||||
);
|
||||
const entranceYaw = Number.isFinite(playerAnchor.yaw)
|
||||
let entranceYaw = Number.isFinite(playerAnchor.yaw)
|
||||
? playerAnchor.yaw
|
||||
: inferredEntranceYaw;
|
||||
|
||||
@@ -809,6 +871,7 @@ async function compile() {
|
||||
playerAnchor,
|
||||
sourceBasis,
|
||||
coordinateAlignment,
|
||||
sourceTransform,
|
||||
);
|
||||
const entrancePosition = mapPosition(
|
||||
draft?.entrance
|
||||
@@ -896,16 +959,49 @@ async function compile() {
|
||||
const entry = Number(spawn.entityId.replace("entry-", ""));
|
||||
if (!bossCandidatesByEntry.has(entry)) bossCandidatesByEntry.set(entry, spawn);
|
||||
}
|
||||
const mappedNativeRoutePositions = coordinateAlignment !== "player-anchor"
|
||||
? (draft?.spawns ?? [])
|
||||
.map((spawn) => mapPosition(spawn.position))
|
||||
.filter((position) => position.every(Number.isFinite))
|
||||
.sort((left, right) => (
|
||||
horizontalDistanceSquared(left, entrancePosition)
|
||||
- horizontalDistanceSquared(right, entrancePosition)
|
||||
))
|
||||
: [];
|
||||
const entranceDirectionTarget = mappedNativeRoutePositions.find((position) => (
|
||||
Math.abs(position[1] - entrancePosition[1]) <= 3
|
||||
&& horizontalDistanceSquared(position, entrancePosition) >= 16
|
||||
));
|
||||
if (entranceDirectionTarget) {
|
||||
entranceYaw = Math.atan2(
|
||||
entranceDirectionTarget[0] - entrancePosition[0],
|
||||
entranceDirectionTarget[2] - entrancePosition[2],
|
||||
);
|
||||
}
|
||||
const entranceLevelRoutePositions = mappedNativeRoutePositions.filter(
|
||||
(position) => Math.abs(position[1] - entrancePosition[1]) <= 2.5,
|
||||
);
|
||||
const nativeRoutePositions = (
|
||||
bossCandidatesByEntry.size === 0
|
||||
&& entranceLevelRoutePositions.length >= encounters.length
|
||||
)
|
||||
? entranceLevelRoutePositions
|
||||
: mappedNativeRoutePositions;
|
||||
const usedBossSpawnIds = new Set();
|
||||
const bossObjectives = encounters.map((encounter, index) => {
|
||||
const candidate = bossCandidatesByEntry.get(Number(encounter.creatureId));
|
||||
const alpha = encounters.length <= 1 ? 1 : index / (encounters.length - 1);
|
||||
const routePosition = interpolate(trashAnchor.position, bossAnchor.position, 0.18 + alpha * 0.82);
|
||||
const routeAlpha = 0.18 + alpha * 0.82;
|
||||
const nativeRoutePosition = nativeRoutePositions.length
|
||||
? nativeRoutePositions[Math.round(routeAlpha * (nativeRoutePositions.length - 1))]
|
||||
: undefined;
|
||||
const routePosition = nativeRoutePosition
|
||||
?? interpolate(trashAnchor.position, bossAnchor.position, routeAlpha);
|
||||
const position = encounter.eventOnly
|
||||
? [-151.27, -102.82, 252.26]
|
||||
: candidate
|
||||
? mapPosition(candidate.position)
|
||||
: offsetPosition(routePosition, index % 5, 2.4);
|
||||
: nativeRoutePosition ?? offsetPosition(routePosition, index % 5, 2.4);
|
||||
const id = encounter.eventOnly
|
||||
? "mutanus-spawn"
|
||||
: candidate?.id ?? `encounter-${encounter.encounterId}`;
|
||||
@@ -1000,8 +1096,9 @@ async function compile() {
|
||||
|
||||
const allPoints = [
|
||||
entrancePosition,
|
||||
trashAnchor.position,
|
||||
bossAnchor.position,
|
||||
...(coordinateAlignment === "player-anchor" || syntheticTrash
|
||||
? [trashAnchor.position, bossAnchor.position]
|
||||
: []),
|
||||
...staticSpawns.map((spawn) => spawn.position),
|
||||
...roamingPacks.flatMap((pack) => pack.waypoints),
|
||||
];
|
||||
@@ -1032,6 +1129,8 @@ async function compile() {
|
||||
? ["Trash identities and placements are procedural; boss identities come from the installed Ascension encounter catalog."]
|
||||
: coordinateAlignment === "source"
|
||||
? [`Server positions use the packaged ${environmentMode} environment's native world coordinates.`]
|
||||
: coordinateAlignment === "source-transform"
|
||||
? [`Server positions use the packaged ${environmentMode} environment's authoritative WDT placement transform.`]
|
||||
: [`Server positions were aligned to the packaged ${environmentMode} environment at its reviewed player anchor.`]),
|
||||
];
|
||||
|
||||
@@ -1078,6 +1177,7 @@ async function compile() {
|
||||
serverGameObjects: draft?.gameObjects ?? [],
|
||||
provenance: {
|
||||
clientBuild: recipe.clientBuild,
|
||||
coordinateAlignment,
|
||||
clientArchiveHashes: assetPackage.source.checksums ?? {},
|
||||
databaseAdapter: databaseKind,
|
||||
databaseRevision: draft?.spawns?.length
|
||||
@@ -1090,6 +1190,8 @@ async function compile() {
|
||||
? sourceBasis === "z-y-negative-x"
|
||||
? "three(x,y,z)=(wow.y,wow.z,wow.x)"
|
||||
: "three(x,y,z)=(-wow.y,wow.z,wow.x)"
|
||||
: coordinateAlignment === "source-transform"
|
||||
? `three(x,y,z)=rotate-y(${sourceBasis === "flip-x" ? "(-draft.x,draft.y,draft.z)" : "draft(x,y,z)"}-[${sourceTransform.origin.join(",")}],${sourceTransform.yawDegrees}deg)`
|
||||
: coordinateAlignment === "source"
|
||||
? sourceBasis === "flip-x"
|
||||
? "three(x,y,z)=(-draft.x,draft.y,draft.z)"
|
||||
|
||||
@@ -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)");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -191,6 +191,7 @@ export interface DungeonPresentation {
|
||||
|
||||
export interface DungeonSourceProvenance {
|
||||
readonly clientBuild: string;
|
||||
readonly coordinateAlignment?: "player-anchor" | "source" | "source-transform";
|
||||
readonly clientArchiveHashes: Readonly<Record<string, string>>;
|
||||
readonly databaseAdapter: string;
|
||||
readonly databaseRevision?: string;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user