azeroth-shell 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1163) hide show
  1. package/README.md +138 -2
  2. package/bin/azsh.mjs +19 -0
  3. package/docs/aifid/eventai-texts.json +4414 -0
  4. package/docs/dungeons/atlas/atlas-rows-dungeons.json +8989 -0
  5. package/docs/dungeons/survey/pack-id-migration.json +2418 -0
  6. package/package.json +26 -4
  7. package/src/autopilot/bossSkip.ts +26 -0
  8. package/src/autopilot/combatRotation.ts +824 -0
  9. package/src/autopilot/config.ts +533 -0
  10. package/src/autopilot/consumables.ts +58 -0
  11. package/src/autopilot/encounterStand.ts +121 -0
  12. package/src/autopilot/objectGatePlan.ts +53 -0
  13. package/src/autopilot/pathEngage.ts +229 -0
  14. package/src/autopilot/plan.ts +1643 -0
  15. package/src/autopilot/questPolicy.ts +274 -0
  16. package/src/autopilot/routeStep.ts +69 -0
  17. package/src/autopilot/sessionReport.ts +88 -0
  18. package/src/autopilot/topOffPower.ts +26 -0
  19. package/src/autopilot/view.ts +476 -0
  20. package/src/cli/bootCheck.mjs +34 -0
  21. package/src/cli/bootData.mjs +57 -0
  22. package/src/cli/combatLogFilter.ts +153 -0
  23. package/src/cli/combatLogFormat.ts +613 -0
  24. package/src/cli/fileRepository.mjs +105 -0
  25. package/src/cli/gzLoader.mjs +31 -0
  26. package/src/cli/liveGauntletEscort.ts +978 -0
  27. package/src/cli/liveStratUndead.ts +305 -0
  28. package/src/cli/macroHostCombat.ts +545 -0
  29. package/src/cli/macroHostWorld.ts +330 -0
  30. package/src/cli/prefs.mjs +31 -0
  31. package/src/cli/register.mjs +4 -0
  32. package/src/cli/repl.mjs +693 -0
  33. package/src/cli/rotationText.mjs +226 -0
  34. package/src/cli/squad.mjs +105 -0
  35. package/src/cli/term.mjs +126 -0
  36. package/src/cli/text.mjs +122 -0
  37. package/src/cli/tui.mjs +626 -0
  38. package/src/cli/tuiArena.mjs +109 -0
  39. package/src/cli/tuiAutopilotSettings.mjs +93 -0
  40. package/src/cli/tuiBags.mjs +180 -0
  41. package/src/cli/tuiBars.mjs +133 -0
  42. package/src/cli/tuiBg.mjs +243 -0
  43. package/src/cli/tuiBulk.mjs +162 -0
  44. package/src/cli/tuiCheck.mjs +1882 -0
  45. package/src/cli/tuiCity.mjs +396 -0
  46. package/src/cli/tuiCompanionKit.mjs +300 -0
  47. package/src/cli/tuiCompanions.mjs +471 -0
  48. package/src/cli/tuiDev.mjs +62 -0
  49. package/src/cli/tuiDungeon.mjs +606 -0
  50. package/src/cli/tuiEnchantTarget.mjs +120 -0
  51. package/src/cli/tuiFight.mjs +577 -0
  52. package/src/cli/tuiFightPanes.mjs +228 -0
  53. package/src/cli/tuiFloor.mjs +506 -0
  54. package/src/cli/tuiGear.mjs +158 -0
  55. package/src/cli/tuiHonor.mjs +74 -0
  56. package/src/cli/tuiLoot.mjs +97 -0
  57. package/src/cli/tuiMacros.mjs +144 -0
  58. package/src/cli/tuiOutfitter.mjs +115 -0
  59. package/src/cli/tuiPet.mjs +116 -0
  60. package/src/cli/tuiProfessions.mjs +800 -0
  61. package/src/cli/tuiRaid.mjs +127 -0
  62. package/src/cli/tuiRep.mjs +65 -0
  63. package/src/cli/tuiSaves.mjs +69 -0
  64. package/src/cli/tuiSearch.mjs +363 -0
  65. package/src/cli/tuiSettings.mjs +151 -0
  66. package/src/cli/tuiSimLab.mjs +80 -0
  67. package/src/cli/tuiTalents.mjs +60 -0
  68. package/src/cli/tuiViews.mjs +1178 -0
  69. package/src/cli/tuiWiki.mjs +181 -0
  70. package/src/cli/tuiWorld.mjs +361 -0
  71. package/src/cli/wikiIndex.ts +259 -0
  72. package/src/cli/wikiSources.ts +355 -0
  73. package/src/data/alteracValley.ts +176 -0
  74. package/src/data/appearanceOptions.ts +534 -0
  75. package/src/data/applyLootChanceSanity.ts +21 -0
  76. package/src/data/createFlavor.ts +96 -0
  77. package/src/data/customItems.ts +33 -0
  78. package/src/data/dataStore.ts +1904 -0
  79. package/src/data/dungeonGameObjects.ts +84 -0
  80. package/src/data/dungeonPlateCover.ts +66 -0
  81. package/src/data/dungeonSpawns.ts +294 -0
  82. package/src/data/dungeons/alterac-valley.ts +135 -0
  83. package/src/data/dungeons/apply-dungeon-rooms.ts +29 -0
  84. package/src/data/dungeons/apply-encounter-outdoors.ts +72 -0
  85. package/src/data/dungeons/apply-instance-geometry.ts +65 -0
  86. package/src/data/dungeons/apply-spawn-placement.ts +171 -0
  87. package/src/data/dungeons/blackfathom-deeps.ts +539 -0
  88. package/src/data/dungeons/blackrock-depths.ts +1410 -0
  89. package/src/data/dungeons/blackwing-lair.ts +129 -0
  90. package/src/data/dungeons/boss-eventai.ts +8 -0
  91. package/src/data/dungeons/deadmines.ts +410 -0
  92. package/src/data/dungeons/dire-maul-east.ts +980 -0
  93. package/src/data/dungeons/dire-maul-north.ts +661 -0
  94. package/src/data/dungeons/dire-maul-west.ts +785 -0
  95. package/src/data/dungeons/dungeon-rooms.json +5479 -0
  96. package/src/data/dungeons/encounter-outdoors.json +359 -0
  97. package/src/data/dungeons/eventai/blackfathom-deeps.ts +308 -0
  98. package/src/data/dungeons/eventai/blackrock-depths.ts +1257 -0
  99. package/src/data/dungeons/eventai/deadmines.ts +264 -0
  100. package/src/data/dungeons/eventai/dire-maul-east.ts +320 -0
  101. package/src/data/dungeons/eventai/gnomeregan.ts +213 -0
  102. package/src/data/dungeons/eventai/helpers.ts +79 -0
  103. package/src/data/dungeons/eventai/index.ts +133 -0
  104. package/src/data/dungeons/eventai/lbrs.ts +372 -0
  105. package/src/data/dungeons/eventai/maraudon.ts +323 -0
  106. package/src/data/dungeons/eventai/ragefire-chasm.ts +108 -0
  107. package/src/data/dungeons/eventai/razorfen-downs.ts +207 -0
  108. package/src/data/dungeons/eventai/razorfen-kraul.ts +326 -0
  109. package/src/data/dungeons/eventai/scholomance.ts +680 -0
  110. package/src/data/dungeons/eventai/shadowfang-keep.ts +230 -0
  111. package/src/data/dungeons/eventai/sm-cathedral.ts +75 -0
  112. package/src/data/dungeons/eventai/sm-graveyard.ts +150 -0
  113. package/src/data/dungeons/eventai/sm-library.ts +55 -0
  114. package/src/data/dungeons/eventai/stratholme-undead.ts +127 -0
  115. package/src/data/dungeons/eventai/sunken-temple.ts +582 -0
  116. package/src/data/dungeons/eventai/the-stockade.ts +228 -0
  117. package/src/data/dungeons/eventai/ubrs.ts +225 -0
  118. package/src/data/dungeons/eventai/uldaman.ts +355 -0
  119. package/src/data/dungeons/eventai/wailing-caverns.ts +396 -0
  120. package/src/data/dungeons/eventai/zul-farrak.ts +591 -0
  121. package/src/data/dungeons/gnomeregan.ts +909 -0
  122. package/src/data/dungeons/index.ts +126 -0
  123. package/src/data/dungeons/instance-geometry.json +5233 -0
  124. package/src/data/dungeons/key-sources.json +169 -0
  125. package/src/data/dungeons/lbrs.ts +996 -0
  126. package/src/data/dungeons/maraudon.ts +786 -0
  127. package/src/data/dungeons/molten-core.ts +194 -0
  128. package/src/data/dungeons/naxxramas.ts +173 -0
  129. package/src/data/dungeons/onyxias-lair.ts +71 -0
  130. package/src/data/dungeons/pack-from-clusters.ts +1256 -0
  131. package/src/data/dungeons/ragefire-chasm.ts +238 -0
  132. package/src/data/dungeons/razorfen-downs.ts +698 -0
  133. package/src/data/dungeons/razorfen-kraul.ts +766 -0
  134. package/src/data/dungeons/ruins-of-ahnqiraj.ts +121 -0
  135. package/src/data/dungeons/scholomance.ts +1076 -0
  136. package/src/data/dungeons/shadowfang-keep.ts +740 -0
  137. package/src/data/dungeons/sm-armory.ts +266 -0
  138. package/src/data/dungeons/sm-cathedral.ts +430 -0
  139. package/src/data/dungeons/sm-graveyard.ts +482 -0
  140. package/src/data/dungeons/sm-library.ts +337 -0
  141. package/src/data/dungeons/stratholme-live.ts +808 -0
  142. package/src/data/dungeons/stratholme-undead.ts +1164 -0
  143. package/src/data/dungeons/sunken-temple.ts +931 -0
  144. package/src/data/dungeons/temple-of-ahnqiraj.ts +119 -0
  145. package/src/data/dungeons/the-stockade.ts +282 -0
  146. package/src/data/dungeons/ubrs.ts +1286 -0
  147. package/src/data/dungeons/uldaman.ts +685 -0
  148. package/src/data/dungeons/wailing-caverns.ts +356 -0
  149. package/src/data/dungeons/zul-farrak.ts +686 -0
  150. package/src/data/dungeons/zul-gurub.ts +142 -0
  151. package/src/data/dungeons.ts +42 -0
  152. package/src/data/fixtures.ts +446 -0
  153. package/src/data/gameobject-data.json.gz +0 -0
  154. package/src/data/item-data.json.gz +0 -0
  155. package/src/data/loot-data.json.gz +0 -0
  156. package/src/data/maps/atlas-approach-maps.json +1425 -0
  157. package/src/data/maps/atlas-landmarks.json +1711 -0
  158. package/src/data/maps/dungeon-viewports.json +392 -0
  159. package/src/data/materializeModDamagePercentTaken.ts +70 -0
  160. package/src/data/materializeModHealthRegen.ts +89 -0
  161. package/src/data/materializeSpellReputation.ts +26 -0
  162. package/src/data/pageTexts.ts +19 -0
  163. package/src/data/profession-data.json.gz +0 -0
  164. package/src/data/raid-plans/blackfathom-deeps.json +86 -0
  165. package/src/data/raid-plans/blackrock-depths.json +419 -0
  166. package/src/data/raid-plans/blackwing-lair.json +328 -0
  167. package/src/data/raid-plans/deadmines.json +55 -0
  168. package/src/data/raid-plans/dire-maul-east.json +94 -0
  169. package/src/data/raid-plans/dire-maul-north.json +70 -0
  170. package/src/data/raid-plans/dire-maul-west.json +75 -0
  171. package/src/data/raid-plans/gnomeregan.json +131 -0
  172. package/src/data/raid-plans/lbrs.json +176 -0
  173. package/src/data/raid-plans/maraudon.json +102 -0
  174. package/src/data/raid-plans/molten-core.json +169 -0
  175. package/src/data/raid-plans/naxxramas.json +354 -0
  176. package/src/data/raid-plans/onyxias-lair.json +18 -0
  177. package/src/data/raid-plans/ragefire-chasm.json +30 -0
  178. package/src/data/raid-plans/razorfen-downs.json +75 -0
  179. package/src/data/raid-plans/razorfen-kraul.json +53 -0
  180. package/src/data/raid-plans/ruins-of-ahnqiraj.json +110 -0
  181. package/src/data/raid-plans/scholomance.json +170 -0
  182. package/src/data/raid-plans/shadowfang-keep.json +87 -0
  183. package/src/data/raid-plans/sm-armory.json +53 -0
  184. package/src/data/raid-plans/sm-cathedral.json +72 -0
  185. package/src/data/raid-plans/sm-graveyard.json +63 -0
  186. package/src/data/raid-plans/sm-library.json +23 -0
  187. package/src/data/raid-plans/stratholme-live.json +129 -0
  188. package/src/data/raid-plans/stratholme-undead.json +73 -0
  189. package/src/data/raid-plans/sunken-temple.json +159 -0
  190. package/src/data/raid-plans/temple-of-ahnqiraj.json +163 -0
  191. package/src/data/raid-plans/the-stockade.json +42 -0
  192. package/src/data/raid-plans/ubrs.json +53 -0
  193. package/src/data/raid-plans/uldaman.json +131 -0
  194. package/src/data/raid-plans/wailing-caverns.json +90 -0
  195. package/src/data/raid-plans/zul-farrak.json +156 -0
  196. package/src/data/raid-plans/zul-gurub.json +307 -0
  197. package/src/data/raidInstanceCreatures.mjs +473 -0
  198. package/src/data/rotations/index.ts +152 -0
  199. package/src/data/rotations/layout.mjs +72 -0
  200. package/src/data/rotations/pve/druid/balance.json +754 -0
  201. package/src/data/rotations/pve/druid/feral-tank.json +2448 -0
  202. package/src/data/rotations/pve/druid/feral.json +2660 -0
  203. package/src/data/rotations/pve/druid/restoration.json +424 -0
  204. package/src/data/rotations/pve/hunter/beast-mastery.json +1288 -0
  205. package/src/data/rotations/pve/hunter/marksmanship.json +1260 -0
  206. package/src/data/rotations/pve/hunter/survival.json +1373 -0
  207. package/src/data/rotations/pve/mage/arcane-leveling.json +1798 -0
  208. package/src/data/rotations/pve/mage/fire-leveling.json +2003 -0
  209. package/src/data/rotations/pve/mage/frost-leveling.json +1912 -0
  210. package/src/data/rotations/pve/paladin/holy.json +755 -0
  211. package/src/data/rotations/pve/paladin/protection.json +962 -0
  212. package/src/data/rotations/pve/paladin/retribution.json +924 -0
  213. package/src/data/rotations/pve/priest/discipline.json +772 -0
  214. package/src/data/rotations/pve/priest/holy.json +707 -0
  215. package/src/data/rotations/pve/priest/shadow.json +787 -0
  216. package/src/data/rotations/pve/rogue/assassination.json +2477 -0
  217. package/src/data/rotations/pve/rogue/combat.json +2483 -0
  218. package/src/data/rotations/pve/rogue/subtlety.json +2523 -0
  219. package/src/data/rotations/pve/shaman/elemental.json +1157 -0
  220. package/src/data/rotations/pve/shaman/enhancement.json +1085 -0
  221. package/src/data/rotations/pve/shaman/restoration.json +592 -0
  222. package/src/data/rotations/pve/warlock/affliction.json +1185 -0
  223. package/src/data/rotations/pve/warlock/demonology.json +1165 -0
  224. package/src/data/rotations/pve/warlock/destruction.json +1177 -0
  225. package/src/data/rotations/pve/warrior/arms.json +3020 -0
  226. package/src/data/rotations/pve/warrior/fury.json +2996 -0
  227. package/src/data/rotations/pve/warrior/protection.json +2509 -0
  228. package/src/data/rotations/pvp/druid/balance.json +593 -0
  229. package/src/data/rotations/pvp/druid/feral.json +3276 -0
  230. package/src/data/rotations/pvp/druid/restoration.json +662 -0
  231. package/src/data/rotations/pvp/hunter/beast-mastery.json +665 -0
  232. package/src/data/rotations/pvp/hunter/marksmanship.json +2406 -0
  233. package/src/data/rotations/pvp/hunter/survival.json +635 -0
  234. package/src/data/rotations/pvp/mage/arcane.json +574 -0
  235. package/src/data/rotations/pvp/mage/fire.json +570 -0
  236. package/src/data/rotations/pvp/mage/frost.json +4048 -0
  237. package/src/data/rotations/pvp/paladin/holy.json +1498 -0
  238. package/src/data/rotations/pvp/paladin/protection.json +567 -0
  239. package/src/data/rotations/pvp/paladin/retribution.json +1110 -0
  240. package/src/data/rotations/pvp/priest/discipline.json +1848 -0
  241. package/src/data/rotations/pvp/priest/holy.json +6340 -0
  242. package/src/data/rotations/pvp/priest/shadow.json +2329 -0
  243. package/src/data/rotations/pvp/rogue/assassination.json +1322 -0
  244. package/src/data/rotations/pvp/rogue/combat.json +5258 -0
  245. package/src/data/rotations/pvp/rogue/subtlety.json +586 -0
  246. package/src/data/rotations/pvp/shaman/elemental.json +1404 -0
  247. package/src/data/rotations/pvp/shaman/enhancement.json +1277 -0
  248. package/src/data/rotations/pvp/shaman/restoration.json +2490 -0
  249. package/src/data/rotations/pvp/warlock/affliction.json +1017 -0
  250. package/src/data/rotations/pvp/warlock/demonology.json +1503 -0
  251. package/src/data/rotations/pvp/warlock/destruction.json +638 -0
  252. package/src/data/rotations/pvp/warrior/arms.json +5665 -0
  253. package/src/data/rotations/pvp/warrior/fury.json +850 -0
  254. package/src/data/rotations/pvp/warrior/protection.json +777 -0
  255. package/src/data/schema/bundle.ts +511 -0
  256. package/src/data/schema/constants.ts +49 -0
  257. package/src/data/schema/creature.ts +454 -0
  258. package/src/data/schema/encounter.ts +155 -0
  259. package/src/data/schema/faction.ts +48 -0
  260. package/src/data/schema/item.ts +297 -0
  261. package/src/data/schema/itemEnchant.ts +105 -0
  262. package/src/data/schema/npc.ts +44 -0
  263. package/src/data/schema/primitives.ts +295 -0
  264. package/src/data/schema/profession.ts +226 -0
  265. package/src/data/schema/quest.ts +154 -0
  266. package/src/data/schema/spell.ts +1149 -0
  267. package/src/data/schema/talent.ts +74 -0
  268. package/src/data/schema/world.ts +124 -0
  269. package/src/data/schema.ts +19 -0
  270. package/src/data/skinNodeGapFill.ts +68 -0
  271. package/src/data/spell-data.json.gz +0 -0
  272. package/src/data/spell-script-targets.json +1 -0
  273. package/src/data/tables/ahItemValues.json.gz +0 -0
  274. package/src/data/tables/alteracValley.json.gz +0 -0
  275. package/src/data/tables/areatriggerTeleports.json.gz +0 -0
  276. package/src/data/tables/botNames.json.gz +0 -0
  277. package/src/data/tables/botPopulation.json.gz +0 -0
  278. package/src/data/tables/botSpecs.json.gz +0 -0
  279. package/src/data/tables/classLevelStats.json.gz +0 -0
  280. package/src/data/tables/combatConditions.json.gz +0 -0
  281. package/src/data/tables/combatSkillMeta.json.gz +0 -0
  282. package/src/data/tables/conditions.json.gz +0 -0
  283. package/src/data/tables/createInfo.json.gz +0 -0
  284. package/src/data/tables/creatureAggroGroups.json.gz +0 -0
  285. package/src/data/tables/creatureClassLevelStats.json.gz +0 -0
  286. package/src/data/tables/creaturePatrolPacks.json.gz +0 -0
  287. package/src/data/tables/creatureWeapons.json.gz +0 -0
  288. package/src/data/tables/creatures.json.gz +0 -0
  289. package/src/data/tables/dbScripts.json.gz +0 -0
  290. package/src/data/tables/dungeonAuthoredRoutes.json.gz +0 -0
  291. package/src/data/tables/dungeonCensus.json.gz +0 -0
  292. package/src/data/tables/dungeonGameObjects.json.gz +0 -0
  293. package/src/data/tables/dungeonPacks.json.gz +0 -0
  294. package/src/data/tables/dungeonPlateCover.json.gz +0 -0
  295. package/src/data/tables/dungeonSpawns.json.gz +0 -0
  296. package/src/data/tables/dungeonSurvey.json.gz +0 -0
  297. package/src/data/tables/durabilityCosts.json.gz +0 -0
  298. package/src/data/tables/durabilityQuality.json.gz +0 -0
  299. package/src/data/tables/enchantApplicators.json.gz +0 -0
  300. package/src/data/tables/entranceYards.json.gz +0 -0
  301. package/src/data/tables/explorationBasexp.json.gz +0 -0
  302. package/src/data/tables/factionTemplates.json.gz +0 -0
  303. package/src/data/tables/factions.json.gz +0 -0
  304. package/src/data/tables/gameEvents.json.gz +0 -0
  305. package/src/data/tables/gameObjects.json.gz +0 -0
  306. package/src/data/tables/gossipMenus.json.gz +0 -0
  307. package/src/data/tables/graveyards.json.gz +0 -0
  308. package/src/data/tables/instanceMaps.json.gz +0 -0
  309. package/src/data/tables/itemEnchantmentTemplates.json.gz +0 -0
  310. package/src/data/tables/itemEnchants.json.gz +0 -0
  311. package/src/data/tables/itemRandomProperties.json.gz +0 -0
  312. package/src/data/tables/itemSets.json.gz +0 -0
  313. package/src/data/tables/items.json.gz +0 -0
  314. package/src/data/tables/levelStats.json.gz +0 -0
  315. package/src/data/tables/locks.json.gz +0 -0
  316. package/src/data/tables/map-pin-overrides.json.gz +0 -0
  317. package/src/data/tables/nonCombatTrash.json.gz +0 -0
  318. package/src/data/tables/npcTexts.json.gz +0 -0
  319. package/src/data/tables/pageTexts.json.gz +0 -0
  320. package/src/data/tables/petAbilityTP.json.gz +0 -0
  321. package/src/data/tables/petGenericSpells.json.gz +0 -0
  322. package/src/data/tables/petLevelStats.json.gz +0 -0
  323. package/src/data/tables/playerbot-weightscales.json.gz +0 -0
  324. package/src/data/tables/pools.json.gz +0 -0
  325. package/src/data/tables/quests.json.gz +0 -0
  326. package/src/data/tables/races.json.gz +0 -0
  327. package/src/data/tables/reputationRanks.json.gz +0 -0
  328. package/src/data/tables/reputationRates.json.gz +0 -0
  329. package/src/data/tables/reputationSpillover.json.gz +0 -0
  330. package/src/data/tables/ridingSpells.json.gz +0 -0
  331. package/src/data/tables/scriptTexts.json.gz +0 -0
  332. package/src/data/tables/soundClipVolume.json.gz +0 -0
  333. package/src/data/tables/spellChain.json.gz +0 -0
  334. package/src/data/tables/spellTeleports.json.gz +0 -0
  335. package/src/data/tables/spells.json.gz +0 -0
  336. package/src/data/tables/talents.json.gz +0 -0
  337. package/src/data/tables/tavernTriggers.json.gz +0 -0
  338. package/src/data/tables/taxiNodes.json.gz +0 -0
  339. package/src/data/tables/taxiRoutes.json.gz +0 -0
  340. package/src/data/tables/trainers.json.gz +0 -0
  341. package/src/data/tables/transports.json.gz +0 -0
  342. package/src/data/tables/travelAnchors.json.gz +0 -0
  343. package/src/data/tables/travelEdges.json.gz +0 -0
  344. package/src/data/tables/unitConditions.json.gz +0 -0
  345. package/src/data/tables/vendors.json.gz +0 -0
  346. package/src/data/tables/weaponEnchantProcs.json.gz +0 -0
  347. package/src/data/tables/xp.json.gz +0 -0
  348. package/src/data/tables/zoneWeather.json.gz +0 -0
  349. package/src/data/tables/zones.json.gz +0 -0
  350. package/src/data/world-data.ts +56 -0
  351. package/src/data/zone-music-sets.json +2751 -0
  352. package/src/dev/etl/lib/loot-chance-sanity.mjs +180 -0
  353. package/src/domain/audioQuality.mjs +145 -0
  354. package/src/domain/bg/ab.ts +433 -0
  355. package/src/domain/bg/arenaComps.ts +644 -0
  356. package/src/domain/bg/arenaLab.ts +695 -0
  357. package/src/domain/bg/arenaPace.ts +31 -0
  358. package/src/domain/bg/arenaRating.ts +110 -0
  359. package/src/domain/bg/av.ts +758 -0
  360. package/src/domain/bg/avEnemyPush.ts +219 -0
  361. package/src/domain/bg/avField.ts +283 -0
  362. package/src/domain/bg/avInstanceNodes.ts +197 -0
  363. package/src/domain/bg/avInstanceScore.ts +123 -0
  364. package/src/domain/bg/avQuestItems.ts +55 -0
  365. package/src/domain/bg/avQuests.ts +210 -0
  366. package/src/domain/bg/avSession.ts +196 -0
  367. package/src/domain/bg/bgConsumes.ts +269 -0
  368. package/src/domain/bg/bgPrebuff.ts +153 -0
  369. package/src/domain/bg/bgRest.ts +91 -0
  370. package/src/domain/bg/bgRoster.ts +305 -0
  371. package/src/domain/bg/bgTier.ts +61 -0
  372. package/src/domain/bg/bgWorld.ts +862 -0
  373. package/src/domain/bg/match.ts +215 -0
  374. package/src/domain/bg/strategies.ts +552 -0
  375. package/src/domain/bg/types.ts +291 -0
  376. package/src/domain/bg/wsg.ts +264 -0
  377. package/src/domain/bots/actionProviderSpec.ts +38 -0
  378. package/src/domain/bots/autoConsumables.ts +285 -0
  379. package/src/domain/bots/betweenPullRest.ts +239 -0
  380. package/src/domain/bots/botGear.ts +248 -0
  381. package/src/domain/bots/botInventory.ts +486 -0
  382. package/src/domain/bots/botPet.ts +535 -0
  383. package/src/domain/bots/botPool.ts +291 -0
  384. package/src/domain/bots/botProfessions.ts +334 -0
  385. package/src/domain/bots/companionActionBar.ts +209 -0
  386. package/src/domain/bots/companionHireCost.ts +236 -0
  387. package/src/domain/bots/companionMissions.ts +582 -0
  388. package/src/domain/bots/companionPrep.ts +254 -0
  389. package/src/domain/bots/companionQuests.ts +270 -0
  390. package/src/domain/bots/companionRep.ts +75 -0
  391. package/src/domain/bots/companionRotation.ts +708 -0
  392. package/src/domain/bots/companionXp.ts +66 -0
  393. package/src/domain/bots/consumableShare.ts +811 -0
  394. package/src/domain/bots/dpsMate.ts +1072 -0
  395. package/src/domain/bots/groupCompReport.ts +132 -0
  396. package/src/domain/bots/healthstoneSupply.ts +198 -0
  397. package/src/domain/bots/outfitter.ts +1056 -0
  398. package/src/domain/bots/paladinPrePull.ts +231 -0
  399. package/src/domain/bots/partyRole.ts +40 -0
  400. package/src/domain/bots/playerbotEquipCache.ts +412 -0
  401. package/src/domain/bots/playerbotItemEligibility.ts +60 -0
  402. package/src/domain/bots/playerbotStatWeight.ts +853 -0
  403. package/src/domain/bots/playerbotUnavailableItems.ts +147 -0
  404. package/src/domain/bots/prePullBuffs.ts +219 -0
  405. package/src/domain/bots/prePullStealth.ts +82 -0
  406. package/src/domain/bots/runSupply.ts +251 -0
  407. package/src/domain/bots/runSupplyPrefs.ts +28 -0
  408. package/src/domain/bots/sendTradeGoods.ts +394 -0
  409. package/src/domain/bots/soulShardCap.ts +35 -0
  410. package/src/domain/bots/squad.ts +842 -0
  411. package/src/domain/bots/squadRun.ts +81 -0
  412. package/src/domain/character/actionbar.ts +346 -0
  413. package/src/domain/character/appearance.ts +165 -0
  414. package/src/domain/character/buildCombatant.ts +1726 -0
  415. package/src/domain/character/character.ts +356 -0
  416. package/src/domain/character/characterName.ts +43 -0
  417. package/src/domain/character/characterRatings.ts +424 -0
  418. package/src/domain/character/characterSpells.ts +282 -0
  419. package/src/domain/character/characterStats.ts +1559 -0
  420. package/src/domain/character/characterTalents.ts +398 -0
  421. package/src/domain/character/combatSkills.ts +994 -0
  422. package/src/domain/character/displayForm.ts +72 -0
  423. package/src/domain/character/formTalentAuras.ts +171 -0
  424. package/src/domain/character/forms.ts +499 -0
  425. package/src/domain/character/races.ts +40 -0
  426. package/src/domain/character/resurrectionSickness.ts +49 -0
  427. package/src/domain/character/spellbook.ts +169 -0
  428. package/src/domain/character/stanceBar.ts +354 -0
  429. package/src/domain/character/stancePrereq.ts +70 -0
  430. package/src/domain/character/talentBuilds.ts +63 -0
  431. package/src/domain/character/talentImport.ts +130 -0
  432. package/src/domain/character/talentLink.ts +123 -0
  433. package/src/domain/character/talents.ts +201 -0
  434. package/src/domain/core/conditionSnapshot.ts +92 -0
  435. package/src/domain/core/hover.ts +14 -0
  436. package/src/domain/core/ids.ts +58 -0
  437. package/src/domain/core/internalNameTags.ts +5 -0
  438. package/src/domain/core/runtimeDataPatches.ts +357 -0
  439. package/src/domain/creature/aiTargeting.ts +588 -0
  440. package/src/domain/creature/combatCondition.ts +157 -0
  441. package/src/domain/creature/creatureAggro.ts +804 -0
  442. package/src/domain/creature/creatureAi.ts +206 -0
  443. package/src/domain/creature/creatureAiConstants.ts +661 -0
  444. package/src/domain/creature/creatureCastList.ts +1007 -0
  445. package/src/domain/creature/creatureEventAi.ts +1409 -0
  446. package/src/domain/creature/creatureGroups.ts +144 -0
  447. package/src/domain/creature/creatureLinking.ts +333 -0
  448. package/src/domain/creature/creatureScaling.ts +320 -0
  449. package/src/domain/creature/creatureTrigger.ts +53 -0
  450. package/src/domain/creature/creatureWander.ts +74 -0
  451. package/src/domain/creature/eventAiTexts.ts +145 -0
  452. package/src/domain/creature/faction.ts +287 -0
  453. package/src/domain/creature/forcedReaction.ts +48 -0
  454. package/src/domain/creature/outdoorHuntable.ts +74 -0
  455. package/src/domain/creature/patrolPacks.ts +210 -0
  456. package/src/domain/creature/reputation.ts +967 -0
  457. package/src/domain/creature/unitFlags.ts +74 -0
  458. package/src/domain/creature/worldBosses.ts +393 -0
  459. package/src/domain/dungeonMusic.mjs +48 -0
  460. package/src/domain/economy/auction.ts +282 -0
  461. package/src/domain/economy/auctionBot.ts +1060 -0
  462. package/src/domain/economy/honorPrice.ts +100 -0
  463. package/src/domain/economy/mail.ts +958 -0
  464. package/src/domain/economy/money.ts +42 -0
  465. package/src/domain/economy/syntheticClassTrainers.ts +62 -0
  466. package/src/domain/economy/trading.ts +296 -0
  467. package/src/domain/economy/vendorSellAll.ts +252 -0
  468. package/src/domain/economy/vendorStock.ts +146 -0
  469. package/src/domain/items/ammo.ts +817 -0
  470. package/src/domain/items/bank.ts +162 -0
  471. package/src/domain/items/consumableFamily.ts +205 -0
  472. package/src/domain/items/craftUpgrades.ts +83 -0
  473. package/src/domain/items/createItem.ts +93 -0
  474. package/src/domain/items/durability.ts +581 -0
  475. package/src/domain/items/equipment.ts +441 -0
  476. package/src/domain/items/equipmentHelper.ts +767 -0
  477. package/src/domain/items/inventory.ts +561 -0
  478. package/src/domain/items/itemBonding.ts +93 -0
  479. package/src/domain/items/itemContainer.ts +245 -0
  480. package/src/domain/items/itemDisplayName.ts +33 -0
  481. package/src/domain/items/itemInstance.ts +181 -0
  482. package/src/domain/items/itemRandomEnchantOutcomes.ts +315 -0
  483. package/src/domain/items/itemRandomProps.ts +77 -0
  484. package/src/domain/items/itemRestrictions.ts +329 -0
  485. package/src/domain/items/itemTeaches.ts +82 -0
  486. package/src/domain/items/itemUseCooldown.ts +52 -0
  487. package/src/domain/items/itemUseTarget.ts +90 -0
  488. package/src/domain/items/junkCategories.ts +174 -0
  489. package/src/domain/items/junkFilter.ts +368 -0
  490. package/src/domain/items/keyring.ts +131 -0
  491. package/src/domain/items/loot.ts +221 -0
  492. package/src/domain/items/mounts.ts +190 -0
  493. package/src/domain/items/onUsePayload.ts +102 -0
  494. package/src/domain/items/pendingLoot.ts +107 -0
  495. package/src/domain/items/relic.ts +105 -0
  496. package/src/domain/items/rocketBoots.ts +36 -0
  497. package/src/domain/items/sortContainer.ts +139 -0
  498. package/src/domain/items/spareContainers.ts +71 -0
  499. package/src/domain/items/spellReagentIndex.ts +131 -0
  500. package/src/domain/items/staleConsumables.ts +66 -0
  501. package/src/domain/items/weaponSpender.ts +110 -0
  502. package/src/domain/listDungeonIds.mjs +28 -0
  503. package/src/domain/macro/compose.ts +239 -0
  504. package/src/domain/macro/conditions.ts +260 -0
  505. package/src/domain/macro/creatureTypes.ts +40 -0
  506. package/src/domain/macro/describe.ts +169 -0
  507. package/src/domain/macro/icon.ts +60 -0
  508. package/src/domain/macro/index.ts +20 -0
  509. package/src/domain/macro/normalize.ts +112 -0
  510. package/src/domain/macro/parse.ts +316 -0
  511. package/src/domain/macro/plan.ts +288 -0
  512. package/src/domain/macro/rotation.ts +590 -0
  513. package/src/domain/macro/rotationEnv.ts +173 -0
  514. package/src/domain/macro/slots.ts +101 -0
  515. package/src/domain/macro/snapshot.ts +114 -0
  516. package/src/domain/macro/templates.ts +446 -0
  517. package/src/domain/macro/types.ts +70 -0
  518. package/src/domain/macro/units.ts +93 -0
  519. package/src/domain/macro/weaponTypes.ts +83 -0
  520. package/src/domain/nav/cityTeleports.ts +10 -0
  521. package/src/domain/nav/mounting.ts +113 -0
  522. package/src/domain/nav/nav.ts +43 -0
  523. package/src/domain/nav/navCollision.ts +606 -0
  524. package/src/domain/nav/navOutdoors.ts +91 -0
  525. package/src/domain/nav/navRegistry.ts +179 -0
  526. package/src/domain/nav/navRoomGraph.ts +302 -0
  527. package/src/domain/nav/navTypes.ts +43 -0
  528. package/src/domain/nav/navmesh.ts +1715 -0
  529. package/src/domain/nav/speed.ts +200 -0
  530. package/src/domain/nav/storey.ts +10 -0
  531. package/src/domain/nav/travel.ts +725 -0
  532. package/src/domain/nav/travelTypes.ts +75 -0
  533. package/src/domain/pet/pet.ts +1150 -0
  534. package/src/domain/pet/petActionBar.ts +180 -0
  535. package/src/domain/pet/petSpellbook.ts +39 -0
  536. package/src/domain/pet/petStable.ts +81 -0
  537. package/src/domain/professions/autoDisenchant.ts +236 -0
  538. package/src/domain/professions/characterEnchants.ts +176 -0
  539. package/src/domain/professions/craftCooldown.ts +52 -0
  540. package/src/domain/professions/enchantApply.ts +62 -0
  541. package/src/domain/professions/enchantTargets.ts +114 -0
  542. package/src/domain/professions/enchanting.ts +236 -0
  543. package/src/domain/professions/gatherFilter.ts +149 -0
  544. package/src/domain/professions/gearEnchant.ts +137 -0
  545. package/src/domain/professions/heldTools.ts +29 -0
  546. package/src/domain/professions/learnAllRecipes.ts +146 -0
  547. package/src/domain/professions/miningHarvest.ts +69 -0
  548. package/src/domain/professions/partyDisenchant.ts +294 -0
  549. package/src/domain/professions/partyWork.ts +83 -0
  550. package/src/domain/professions/pickpocket.ts +172 -0
  551. package/src/domain/professions/poisons.ts +240 -0
  552. package/src/domain/professions/professions.ts +677 -0
  553. package/src/domain/professions/rareNodes.ts +45 -0
  554. package/src/domain/professions/skinLoot.ts +27 -0
  555. package/src/domain/professions/vendorReagents.ts +152 -0
  556. package/src/domain/professions/weaponImbueHand.ts +171 -0
  557. package/src/domain/questFarmFilter.mjs +42 -0
  558. package/src/domain/quests/doQuest.ts +1204 -0
  559. package/src/domain/quests/gossip.ts +308 -0
  560. package/src/domain/quests/gossipTalk.ts +298 -0
  561. package/src/domain/quests/interpreter/canComplete.ts +150 -0
  562. package/src/domain/quests/interpreter/claim.ts +137 -0
  563. package/src/domain/quests/interpreter/dbscript/handlers.ts +1371 -0
  564. package/src/domain/quests/interpreter/dbscript/handlersBatch.ts +1251 -0
  565. package/src/domain/quests/interpreter/dbscript/hooks.ts +331 -0
  566. package/src/domain/quests/interpreter/dbscript/index.ts +212 -0
  567. package/src/domain/quests/interpreter/dbscript/opcodes.ts +257 -0
  568. package/src/domain/quests/interpreter/dbscript/registry.ts +1194 -0
  569. package/src/domain/quests/interpreter/dbscript/registryAreatriggerScripts.ts +539 -0
  570. package/src/domain/quests/interpreter/dbscript/registryAshenvale.ts +553 -0
  571. package/src/domain/quests/interpreter/dbscript/registryAzshara.ts +272 -0
  572. package/src/domain/quests/interpreter/dbscript/registryDarkshore.ts +637 -0
  573. package/src/domain/quests/interpreter/dbscript/registryDesolace.ts +501 -0
  574. package/src/domain/quests/interpreter/dbscript/registryDustwallowMarsh.ts +735 -0
  575. package/src/domain/quests/interpreter/dbscript/registryFelwood.ts +493 -0
  576. package/src/domain/quests/interpreter/dbscript/registryFeralas.ts +485 -0
  577. package/src/domain/quests/interpreter/dbscript/registryGoScripts.ts +203 -0
  578. package/src/domain/quests/interpreter/dbscript/registryMoonglade.ts +288 -0
  579. package/src/domain/quests/interpreter/dbscript/registryNpcProfessions.ts +230 -0
  580. package/src/domain/quests/interpreter/dbscript/registryNpcsSpecial.ts +545 -0
  581. package/src/domain/quests/interpreter/dbscript/registryRazorfenDowns.ts +293 -0
  582. package/src/domain/quests/interpreter/dbscript/registryRazorfenKraul.ts +221 -0
  583. package/src/domain/quests/interpreter/dbscript/registryRedridge.ts +112 -0
  584. package/src/domain/quests/interpreter/dbscript/registrySearingGorge.ts +125 -0
  585. package/src/domain/quests/interpreter/dbscript/registrySiblings.ts +51 -0
  586. package/src/domain/quests/interpreter/dbscript/registrySilverpineForest.ts +172 -0
  587. package/src/domain/quests/interpreter/dbscript/registryStonetalonMountains.ts +180 -0
  588. package/src/domain/quests/interpreter/dbscript/registryStormwindCity.ts +369 -0
  589. package/src/domain/quests/interpreter/dbscript/registryStranglethornVale.ts +115 -0
  590. package/src/domain/quests/interpreter/dbscript/registryStratholme.ts +146 -0
  591. package/src/domain/quests/interpreter/dbscript/registrySunkenTemple.ts +149 -0
  592. package/src/domain/quests/interpreter/dbscript/registrySwampOfSorrows.ts +163 -0
  593. package/src/domain/quests/interpreter/dbscript/registryTanaris.ts +318 -0
  594. package/src/domain/quests/interpreter/dbscript/registryTeldrassil.ts +120 -0
  595. package/src/domain/quests/interpreter/dbscript/registryTheBarrens.ts +603 -0
  596. package/src/domain/quests/interpreter/dbscript/registryThousandNeedles.ts +499 -0
  597. package/src/domain/quests/interpreter/dbscript/registryTirisfalGlades.ts +222 -0
  598. package/src/domain/quests/interpreter/dbscript/registryUngoroCrater.ts +291 -0
  599. package/src/domain/quests/interpreter/dbscript/registryWarEffort.ts +773 -0
  600. package/src/domain/quests/interpreter/dbscript/registryWesternPlaguelands.ts +206 -0
  601. package/src/domain/quests/interpreter/dbscript/registryWestfall.ts +190 -0
  602. package/src/domain/quests/interpreter/dbscript/registryWetlands.ts +186 -0
  603. package/src/domain/quests/interpreter/dbscript/registryWinterspring.ts +235 -0
  604. package/src/domain/quests/interpreter/dbscript/types.ts +817 -0
  605. package/src/domain/quests/interpreter/dbscript/vm.ts +171 -0
  606. package/src/domain/quests/interpreter/diff.ts +349 -0
  607. package/src/domain/quests/interpreter/fixtures/oracle-questlog-qi2.json +2417 -0
  608. package/src/domain/quests/interpreter/flags.ts +101 -0
  609. package/src/domain/quests/interpreter/index.ts +113 -0
  610. package/src/domain/quests/interpreter/live.ts +178 -0
  611. package/src/domain/quests/interpreter/types.ts +81 -0
  612. package/src/domain/quests/interpreter/updaters.ts +412 -0
  613. package/src/domain/quests/questCorpseUse.ts +155 -0
  614. package/src/domain/quests/questDialog.ts +43 -0
  615. package/src/domain/quests/questFight.ts +34 -0
  616. package/src/domain/quests/questObjectiveLabel.ts +39 -0
  617. package/src/domain/quests/questRewardChoice.ts +85 -0
  618. package/src/domain/quests/questScriptCredit.ts +26 -0
  619. package/src/domain/quests/questScriptItemUse.ts +74 -0
  620. package/src/domain/quests/questTameRods.ts +79 -0
  621. package/src/domain/quests/questlog.ts +1545 -0
  622. package/src/domain/quests/talkDeliver.ts +170 -0
  623. package/src/domain/raid/globalActionBar.ts +195 -0
  624. package/src/domain/raid/instanceRoster.ts +194 -0
  625. package/src/domain/raid/partySummon.ts +198 -0
  626. package/src/domain/raid/partyVault.ts +320 -0
  627. package/src/domain/raid/raidBossAbilities.ts +268 -0
  628. package/src/domain/raid/raidComp.ts +335 -0
  629. package/src/domain/raid/raidCustomRows.ts +453 -0
  630. package/src/domain/raid/raidEncounterGear.ts +298 -0
  631. package/src/domain/raid/raidEncounterTactics.ts +412 -0
  632. package/src/domain/raid/raidPlan.ts +509 -0
  633. package/src/domain/raid/raidPlanEdits.ts +98 -0
  634. package/src/domain/raid/raidPlanPacks.ts +480 -0
  635. package/src/domain/raid/raidRecovery.ts +183 -0
  636. package/src/domain/raid/raidRosterTemplate.ts +138 -0
  637. package/src/domain/rotation/auraSide.ts +68 -0
  638. package/src/domain/rotation/build.ts +3031 -0
  639. package/src/domain/rotation/classes/druid.ts +58 -0
  640. package/src/domain/rotation/classes/hooks.ts +59 -0
  641. package/src/domain/rotation/classes/hunter.ts +156 -0
  642. package/src/domain/rotation/classes/index.ts +104 -0
  643. package/src/domain/rotation/classes/mage.ts +99 -0
  644. package/src/domain/rotation/classes/paladin.ts +296 -0
  645. package/src/domain/rotation/classes/priest.ts +94 -0
  646. package/src/domain/rotation/classes/pullOpener.ts +92 -0
  647. package/src/domain/rotation/classes/rogue.ts +69 -0
  648. package/src/domain/rotation/classes/shaman.ts +29 -0
  649. package/src/domain/rotation/classes/supportSpec.ts +94 -0
  650. package/src/domain/rotation/classes/warlock.ts +81 -0
  651. package/src/domain/rotation/classes/warrior.ts +402 -0
  652. package/src/domain/rotation/classify.ts +1381 -0
  653. package/src/domain/rotation/condMetricPicker.ts +379 -0
  654. package/src/domain/rotation/consumables.ts +242 -0
  655. package/src/domain/rotation/evaluate.ts +1115 -0
  656. package/src/domain/rotation/finisherLadder.ts +145 -0
  657. package/src/domain/rotation/invent.ts +938 -0
  658. package/src/domain/rotation/killOrder.ts +30 -0
  659. package/src/domain/rotation/openerForm.ts +22 -0
  660. package/src/domain/rotation/paladinBuffs.ts +568 -0
  661. package/src/domain/rotation/prebuff.ts +283 -0
  662. package/src/domain/rotation/raidRowTuning.ts +34 -0
  663. package/src/domain/rotation/rotation.ts +11 -0
  664. package/src/domain/rotation/rotationProfiles.ts +180 -0
  665. package/src/domain/rotation/rotationSuggestions.ts +851 -0
  666. package/src/domain/rotation/ruleAfterChain.ts +49 -0
  667. package/src/domain/rotation/spec.ts +70 -0
  668. package/src/domain/rotation/spellPicker.ts +140 -0
  669. package/src/domain/rotation/stand.ts +143 -0
  670. package/src/domain/rotation/types.ts +718 -0
  671. package/src/domain/run/battlegroundRun.ts +111 -0
  672. package/src/domain/run/canEnterContext.ts +32 -0
  673. package/src/domain/run/death.ts +561 -0
  674. package/src/domain/run/deathRecovery.ts +289 -0
  675. package/src/domain/run/duel.ts +141 -0
  676. package/src/domain/run/dungeonRun.ts +344 -0
  677. package/src/domain/run/floorRest.ts +159 -0
  678. package/src/domain/run/honor.ts +557 -0
  679. package/src/domain/run/honorWeek.ts +180 -0
  680. package/src/domain/run/whenMap.ts +977 -0
  681. package/src/domain/scriptdev/arathiHighlands.ts +445 -0
  682. package/src/domain/scriptdev/ashenvale.ts +635 -0
  683. package/src/domain/scriptdev/ashenvaleHelpers.ts +1215 -0
  684. package/src/domain/scriptdev/azshara.ts +892 -0
  685. package/src/domain/scriptdev/blackfathomDeeps.ts +212 -0
  686. package/src/domain/scriptdev/blackrockDepths.ts +1434 -0
  687. package/src/domain/scriptdev/blackrockSpire.ts +730 -0
  688. package/src/domain/scriptdev/blackwingLair.ts +521 -0
  689. package/src/domain/scriptdev/burningSteppes.ts +62 -0
  690. package/src/domain/scriptdev/classFilter.ts +43 -0
  691. package/src/domain/scriptdev/darkshore.ts +817 -0
  692. package/src/domain/scriptdev/darkshoreHelpers.ts +853 -0
  693. package/src/domain/scriptdev/deadmines.ts +331 -0
  694. package/src/domain/scriptdev/desolace.ts +1239 -0
  695. package/src/domain/scriptdev/direMaul.ts +859 -0
  696. package/src/domain/scriptdev/durotar.ts +532 -0
  697. package/src/domain/scriptdev/dustwallowMarsh.ts +758 -0
  698. package/src/domain/scriptdev/dustwallowMarshHelpers.ts +994 -0
  699. package/src/domain/scriptdev/easternPlaguelands.ts +21 -0
  700. package/src/domain/scriptdev/felwood.ts +1055 -0
  701. package/src/domain/scriptdev/feralas.ts +571 -0
  702. package/src/domain/scriptdev/feralasHelpers.ts +838 -0
  703. package/src/domain/scriptdev/gnomeregan.ts +466 -0
  704. package/src/domain/scriptdev/guards.ts +616 -0
  705. package/src/domain/scriptdev/hinterlands.ts +693 -0
  706. package/src/domain/scriptdev/host.ts +1134 -0
  707. package/src/domain/scriptdev/index.ts +123 -0
  708. package/src/domain/scriptdev/instanceRaids.ts +136 -0
  709. package/src/domain/scriptdev/itemScripts.ts +37 -0
  710. package/src/domain/scriptdev/lochModan.ts +283 -0
  711. package/src/domain/scriptdev/maraudon.ts +232 -0
  712. package/src/domain/scriptdev/moltenCore.ts +831 -0
  713. package/src/domain/scriptdev/moonglade.ts +659 -0
  714. package/src/domain/scriptdev/moongladeHelpers.ts +933 -0
  715. package/src/domain/scriptdev/naxxramas.ts +577 -0
  716. package/src/domain/scriptdev/naxxramasConstruct.ts +364 -0
  717. package/src/domain/scriptdev/naxxramasFrostwyrm.ts +378 -0
  718. package/src/domain/scriptdev/naxxramasMilitary.ts +276 -0
  719. package/src/domain/scriptdev/npcProfessions.ts +1025 -0
  720. package/src/domain/scriptdev/npcsSpecial.ts +1379 -0
  721. package/src/domain/scriptdev/onyxiasLair.ts +313 -0
  722. package/src/domain/scriptdev/orgrimmar.ts +147 -0
  723. package/src/domain/scriptdev/professionSpecConsumer.ts +481 -0
  724. package/src/domain/scriptdev/razorfenDowns.ts +468 -0
  725. package/src/domain/scriptdev/razorfenKraul.ts +410 -0
  726. package/src/domain/scriptdev/redridgeMountains.ts +163 -0
  727. package/src/domain/scriptdev/registry.ts +945 -0
  728. package/src/domain/scriptdev/ruinsOfAhnqiraj.ts +356 -0
  729. package/src/domain/scriptdev/scarletMonastery.ts +713 -0
  730. package/src/domain/scriptdev/scholomance.ts +682 -0
  731. package/src/domain/scriptdev/searingGorge.ts +295 -0
  732. package/src/domain/scriptdev/shadowfangKeep.ts +181 -0
  733. package/src/domain/scriptdev/silithus.ts +71 -0
  734. package/src/domain/scriptdev/silverpineForest.ts +662 -0
  735. package/src/domain/scriptdev/stonetalonMountains.ts +493 -0
  736. package/src/domain/scriptdev/stormwindCity.ts +1192 -0
  737. package/src/domain/scriptdev/stranglethornVale.ts +402 -0
  738. package/src/domain/scriptdev/stratholme.ts +650 -0
  739. package/src/domain/scriptdev/stratholmeScripts.ts +505 -0
  740. package/src/domain/scriptdev/sunkenTemple.ts +736 -0
  741. package/src/domain/scriptdev/swampOfSorrows.ts +22 -0
  742. package/src/domain/scriptdev/tanaris.ts +391 -0
  743. package/src/domain/scriptdev/tanarisHelpers.ts +661 -0
  744. package/src/domain/scriptdev/teldrassil.ts +143 -0
  745. package/src/domain/scriptdev/templeOfAhnqiraj.ts +1013 -0
  746. package/src/domain/scriptdev/theBarrens.ts +709 -0
  747. package/src/domain/scriptdev/theBarrensHelpers.ts +1026 -0
  748. package/src/domain/scriptdev/thousandNeedles.ts +426 -0
  749. package/src/domain/scriptdev/thousandNeedlesHelpers.ts +566 -0
  750. package/src/domain/scriptdev/tirisfalGlades.ts +533 -0
  751. package/src/domain/scriptdev/types.ts +1026 -0
  752. package/src/domain/scriptdev/uldaman.ts +437 -0
  753. package/src/domain/scriptdev/ungoroCrater.ts +549 -0
  754. package/src/domain/scriptdev/ungoroCraterHelpers.ts +1006 -0
  755. package/src/domain/scriptdev/wailingCaverns.ts +700 -0
  756. package/src/domain/scriptdev/warEffort.ts +371 -0
  757. package/src/domain/scriptdev/westernPlaguelands.ts +952 -0
  758. package/src/domain/scriptdev/westfall.ts +767 -0
  759. package/src/domain/scriptdev/wetlands.ts +660 -0
  760. package/src/domain/scriptdev/winterspring.ts +482 -0
  761. package/src/domain/scriptdev/winterspringHelpers.ts +801 -0
  762. package/src/domain/scriptdev/worldBosses.ts +605 -0
  763. package/src/domain/scriptdev/zulfarrak.ts +478 -0
  764. package/src/domain/scriptdev/zulgurub.ts +1152 -0
  765. package/src/domain/sim/dummySim.ts +408 -0
  766. package/src/domain/sim/targetDummy.ts +29 -0
  767. package/src/domain/social/guild.ts +148 -0
  768. package/src/domain/spells/areaAuraMembership.ts +93 -0
  769. package/src/domain/spells/breakableStunCc.ts +166 -0
  770. package/src/domain/spells/cancelAura.ts +80 -0
  771. package/src/domain/spells/diminishing.ts +167 -0
  772. package/src/domain/spells/dispel.ts +149 -0
  773. package/src/domain/spells/dispelMechanic.ts +105 -0
  774. package/src/domain/spells/equipSpells.ts +247 -0
  775. package/src/domain/spells/learnOnTargets.ts +260 -0
  776. package/src/domain/spells/mergeSchoolImmunityFromRaw.ts +66 -0
  777. package/src/domain/spells/resurrectSpell.ts +124 -0
  778. package/src/domain/spells/spellPushback.ts +39 -0
  779. package/src/domain/spells/spellReflect.ts +43 -0
  780. package/src/domain/spells/stealth.ts +183 -0
  781. package/src/domain/spells/totem.ts +394 -0
  782. package/src/domain/spells/worldCast.ts +187 -0
  783. package/src/domain/world/areaTriggerLocks.ts +177 -0
  784. package/src/domain/world/dungeonMusic.ts +108 -0
  785. package/src/domain/world/gameEvents.ts +119 -0
  786. package/src/domain/world/gameObjects.ts +1030 -0
  787. package/src/domain/world/goEventFire.ts +234 -0
  788. package/src/domain/world/goMoTransport.ts +74 -0
  789. package/src/domain/world/goTransport.ts +81 -0
  790. package/src/domain/world/hazards.ts +459 -0
  791. package/src/domain/world/openLock.ts +398 -0
  792. package/src/domain/world/pools.ts +470 -0
  793. package/src/domain/world/restArea.ts +37 -0
  794. package/src/domain/world/weather.ts +201 -0
  795. package/src/domain/zoneAmbience.mjs +87 -0
  796. package/src/domain/zoneMusic.mjs +62 -0
  797. package/src/domain/zoneMusicQueue.mjs +7 -0
  798. package/src/engine/combat/activeSeal.ts +39 -0
  799. package/src/engine/combat/aiTargetResolve.ts +64 -0
  800. package/src/engine/combat/aoeCast.ts +289 -0
  801. package/src/engine/combat/applyConsumeAura.ts +74 -0
  802. package/src/engine/combat/applyDemonicSacrifice.ts +70 -0
  803. package/src/engine/combat/applyDispelMechanic.ts +30 -0
  804. package/src/engine/combat/applyHealEffect.ts +301 -0
  805. package/src/engine/combat/applySchoolAbsorb.ts +114 -0
  806. package/src/engine/combat/applySpell.ts +3169 -0
  807. package/src/engine/combat/applySpellLate.ts +2026 -0
  808. package/src/engine/combat/applySpellLateBag.ts +144 -0
  809. package/src/engine/combat/areaAura.ts +283 -0
  810. package/src/engine/combat/attackTable.ts +508 -0
  811. package/src/engine/combat/battleRez.ts +87 -0
  812. package/src/engine/combat/castAction.ts +36 -0
  813. package/src/engine/combat/castTargetGates.ts +75 -0
  814. package/src/engine/combat/castableKit.ts +68 -0
  815. package/src/engine/combat/ccMirrorUpgrade.ts +39 -0
  816. package/src/engine/combat/chainFan.ts +210 -0
  817. package/src/engine/combat/channel.ts +423 -0
  818. package/src/engine/combat/chaseCloseness.ts +95 -0
  819. package/src/engine/combat/cmangosCastGates.ts +129 -0
  820. package/src/engine/combat/combatFlag.ts +77 -0
  821. package/src/engine/combat/combatGeometry.ts +1329 -0
  822. package/src/engine/combat/combustion.ts +68 -0
  823. package/src/engine/combat/context.ts +730 -0
  824. package/src/engine/combat/createSession.ts +1165 -0
  825. package/src/engine/combat/creatureLeash.ts +38 -0
  826. package/src/engine/combat/crowdControl.ts +1259 -0
  827. package/src/engine/combat/dispelDuty.ts +54 -0
  828. package/src/engine/combat/dispelReflect.ts +609 -0
  829. package/src/engine/combat/displaceFloor.ts +113 -0
  830. package/src/engine/combat/duelBounds.ts +47 -0
  831. package/src/engine/combat/equippedItemGate.ts +297 -0
  832. package/src/engine/combat/evadeLifecycle.ts +63 -0
  833. package/src/engine/combat/eventAi.ts +2220 -0
  834. package/src/engine/combat/facing.ts +74 -0
  835. package/src/engine/combat/fearFlee.ts +137 -0
  836. package/src/engine/combat/fighterFactory.ts +1144 -0
  837. package/src/engine/combat/forceDespawnAction.ts +51 -0
  838. package/src/engine/combat/formulas.ts +807 -0
  839. package/src/engine/combat/friendlyFan.ts +55 -0
  840. package/src/engine/combat/groundPoolTick.ts +210 -0
  841. package/src/engine/combat/hazards.ts +114 -0
  842. package/src/engine/combat/healTargets.ts +226 -0
  843. package/src/engine/combat/heartbeatResist.ts +49 -0
  844. package/src/engine/combat/hostileItemUse.ts +75 -0
  845. package/src/engine/combat/interruptAuras.ts +66 -0
  846. package/src/engine/combat/itemRescue.ts +49 -0
  847. package/src/engine/combat/itemUse.ts +260 -0
  848. package/src/engine/combat/kitById.ts +23 -0
  849. package/src/engine/combat/knockBack.ts +201 -0
  850. package/src/engine/combat/leap.ts +89 -0
  851. package/src/engine/combat/mitigation.ts +587 -0
  852. package/src/engine/combat/modTaunt.ts +43 -0
  853. package/src/engine/combat/motionClaim.ts +268 -0
  854. package/src/engine/combat/motionGate.ts +150 -0
  855. package/src/engine/combat/motionGenerator.ts +27 -0
  856. package/src/engine/combat/navSight.ts +138 -0
  857. package/src/engine/combat/perfSink.ts +28 -0
  858. package/src/engine/combat/periodicDue.ts +55 -0
  859. package/src/engine/combat/petAuras.ts +86 -0
  860. package/src/engine/combat/pickAction.ts +3449 -0
  861. package/src/engine/combat/powerForm.ts +735 -0
  862. package/src/engine/combat/powerPools.ts +49 -0
  863. package/src/engine/combat/predicates.ts +538 -0
  864. package/src/engine/combat/procsDamage.ts +1823 -0
  865. package/src/engine/combat/reactiveGates.ts +135 -0
  866. package/src/engine/combat/roles.ts +389 -0
  867. package/src/engine/combat/rotationSubject.ts +78 -0
  868. package/src/engine/combat/ruleAfter.ts +106 -0
  869. package/src/engine/combat/seedDisplayAuras.ts +203 -0
  870. package/src/engine/combat/seedOocEffects.ts +317 -0
  871. package/src/engine/combat/seedSchoolImmunities.ts +45 -0
  872. package/src/engine/combat/session-types.ts +458 -0
  873. package/src/engine/combat/sessionApi.ts +1785 -0
  874. package/src/engine/combat/sessionCharge.ts +124 -0
  875. package/src/engine/combat/sessionChase.ts +869 -0
  876. package/src/engine/combat/sessionDeaths.ts +469 -0
  877. package/src/engine/combat/sessionFocus.ts +506 -0
  878. package/src/engine/combat/sessionFollow.ts +167 -0
  879. package/src/engine/combat/sessionGeometry.ts +188 -0
  880. package/src/engine/combat/sessionHome.ts +75 -0
  881. package/src/engine/combat/sessionInject.ts +719 -0
  882. package/src/engine/combat/sessionMechanicMove.ts +555 -0
  883. package/src/engine/combat/sessionMotion.ts +1553 -0
  884. package/src/engine/combat/sessionMotionKit.ts +247 -0
  885. package/src/engine/combat/sessionMoveIntent.ts +49 -0
  886. package/src/engine/combat/sessionMoveOrder.ts +200 -0
  887. package/src/engine/combat/sessionPathTo.ts +657 -0
  888. package/src/engine/combat/sessionPools.ts +688 -0
  889. package/src/engine/combat/sessionSteer.ts +144 -0
  890. package/src/engine/combat/sessionStepBack.ts +151 -0
  891. package/src/engine/combat/sessionStepWrap.ts +116 -0
  892. package/src/engine/combat/sessionView.ts +442 -0
  893. package/src/engine/combat/simEffects.ts +32 -0
  894. package/src/engine/combat/simFacade.ts +620 -0
  895. package/src/engine/combat/simPump.ts +264 -0
  896. package/src/engine/combat/simSnapshot.ts +165 -0
  897. package/src/engine/combat/simThreadPool.ts +35 -0
  898. package/src/engine/combat/skeramImages.ts +57 -0
  899. package/src/engine/combat/slowUpdate.ts +178 -0
  900. package/src/engine/combat/snapToFloor.ts +42 -0
  901. package/src/engine/combat/speedAura.ts +29 -0
  902. package/src/engine/combat/spellReagents.ts +71 -0
  903. package/src/engine/combat/stealthDetect.ts +93 -0
  904. package/src/engine/combat/stepBackMotion.ts +171 -0
  905. package/src/engine/combat/stepSession.ts +3102 -0
  906. package/src/engine/combat/summonCast.ts +243 -0
  907. package/src/engine/combat/thaddiusPolarity.ts +97 -0
  908. package/src/engine/combat/threat.ts +388 -0
  909. package/src/engine/combat/threatOps.ts +272 -0
  910. package/src/engine/combat/tickWorkerBody.ts +211 -0
  911. package/src/engine/combat/totemAuras.ts +122 -0
  912. package/src/engine/combat/triggerPayload.ts +42 -0
  913. package/src/engine/combat/triggeredCompanion.ts +63 -0
  914. package/src/engine/combat/types.ts +1897 -0
  915. package/src/engine/combat/useObjectTrap.ts +140 -0
  916. package/src/engine/combat/walkSurface.ts +54 -0
  917. package/src/engine/combat/weapon.ts +1248 -0
  918. package/src/engine/combat/worldFrame.ts +43 -0
  919. package/src/engine/combat.solo-golden.json +2242 -0
  920. package/src/engine/combat.ts +84 -0
  921. package/src/engine/core/detMath.ts +289 -0
  922. package/src/engine/core/events.ts +357 -0
  923. package/src/engine/core/rng.ts +36 -0
  924. package/src/engine/game/actionBars.ts +124 -0
  925. package/src/engine/game/activateObjectFromSpell.ts +320 -0
  926. package/src/engine/game/applyActiveObjectFromDbScript.ts +98 -0
  927. package/src/engine/game/applyDeathAndSpellScripts.ts +268 -0
  928. package/src/engine/game/applyDoorFromDbScript.ts +388 -0
  929. package/src/engine/game/applyEscortFromDbScript.ts +290 -0
  930. package/src/engine/game/applyGoSpellcasterCast.ts +40 -0
  931. package/src/engine/game/applyHoverFromDbScript.ts +110 -0
  932. package/src/engine/game/applyOocResurrect.ts +71 -0
  933. package/src/engine/game/applySpellDurability.ts +115 -0
  934. package/src/engine/game/applyTailFromDbScript.ts +478 -0
  935. package/src/engine/game/applyTerminateFromDbScript.ts +95 -0
  936. package/src/engine/game/auctionMail.ts +269 -0
  937. package/src/engine/game/bagOverflow.ts +130 -0
  938. package/src/engine/game/bank.ts +110 -0
  939. package/src/engine/game/barAutofill.ts +26 -0
  940. package/src/engine/game/battleground.ts +369 -0
  941. package/src/engine/game/combatEnemySpec.ts +216 -0
  942. package/src/engine/game/combatObjectTraps.ts +167 -0
  943. package/src/engine/game/combatSeed.ts +320 -0
  944. package/src/engine/game/combatSession.ts +3241 -0
  945. package/src/engine/game/combatSessionClock.ts +62 -0
  946. package/src/engine/game/companionQuestActions.ts +242 -0
  947. package/src/engine/game/companionTraining.ts +40 -0
  948. package/src/engine/game/consumables.ts +624 -0
  949. package/src/engine/game/context.ts +53 -0
  950. package/src/engine/game/createHealthstone.ts +45 -0
  951. package/src/engine/game/deathFlow.ts +127 -0
  952. package/src/engine/game/devGrant.ts +117 -0
  953. package/src/engine/game/dynamicObject.ts +365 -0
  954. package/src/engine/game/enchantItem.ts +177 -0
  955. package/src/engine/game/equipmentHelper.ts +806 -0
  956. package/src/engine/game/factionState.ts +108 -0
  957. package/src/engine/game/garmentsOoc.ts +69 -0
  958. package/src/engine/game/globalActionBar.ts +179 -0
  959. package/src/engine/game/goInteractQuestCredit.ts +51 -0
  960. package/src/engine/game/goMoTransportUse.ts +61 -0
  961. package/src/engine/game/goTransportUse.ts +60 -0
  962. package/src/engine/game/healthstoneUpkeep.ts +59 -0
  963. package/src/engine/game/killSkin.ts +124 -0
  964. package/src/engine/game/learnFromItem.ts +118 -0
  965. package/src/engine/game/loadReconcile.ts +551 -0
  966. package/src/engine/game/loot.ts +294 -0
  967. package/src/engine/game/macros.ts +125 -0
  968. package/src/engine/game/mail.ts +293 -0
  969. package/src/engine/game/meetingStoneQueue.ts +75 -0
  970. package/src/engine/game/meetingStoneUse.ts +54 -0
  971. package/src/engine/game/newGameState.ts +363 -0
  972. package/src/engine/game/oocAuraInterrupt.ts +92 -0
  973. package/src/engine/game/oocCast.ts +241 -0
  974. package/src/engine/game/oocCastEffects.ts +803 -0
  975. package/src/engine/game/oocCastMethods.ts +1077 -0
  976. package/src/engine/game/openLockFromSpell.ts +174 -0
  977. package/src/engine/game/outdoorPvp.ts +187 -0
  978. package/src/engine/game/outfitter.ts +644 -0
  979. package/src/engine/game/paladinBoard.ts +393 -0
  980. package/src/engine/game/partyAuras.ts +121 -0
  981. package/src/engine/game/persistCombatAuras.ts +91 -0
  982. package/src/engine/game/pets.ts +459 -0
  983. package/src/engine/game/prePullHealthstones.ts +154 -0
  984. package/src/engine/game/professions.ts +2227 -0
  985. package/src/engine/game/pruneStaleRuntime.ts +39 -0
  986. package/src/engine/game/questFightCredit.ts +36 -0
  987. package/src/engine/game/questItemOnCorpse.ts +166 -0
  988. package/src/engine/game/questItemOnCreature.ts +103 -0
  989. package/src/engine/game/questLog.ts +879 -0
  990. package/src/engine/game/questSpellComplete.ts +21 -0
  991. package/src/engine/game/questTurnIn.ts +598 -0
  992. package/src/engine/game/raidParty.ts +32 -0
  993. package/src/engine/game/reagentBuyIn.ts +39 -0
  994. package/src/engine/game/regenRest.ts +186 -0
  995. package/src/engine/game/rotation.ts +425 -0
  996. package/src/engine/game/runFullDungeon.ts +611 -0
  997. package/src/engine/game/runSupply.ts +80 -0
  998. package/src/engine/game/sanitizeDriftedItems.ts +135 -0
  999. package/src/engine/game/scriptDevGoUse.ts +397 -0
  1000. package/src/engine/game/scriptDevInnkeeper.ts +150 -0
  1001. package/src/engine/game/scriptDevProfessionSpec.ts +99 -0
  1002. package/src/engine/game/sendEventFromSpell.ts +87 -0
  1003. package/src/engine/game/sortContainers.ts +85 -0
  1004. package/src/engine/game/spellReputation.ts +69 -0
  1005. package/src/engine/game/squad/squadDungeonSeating.ts +197 -0
  1006. package/src/engine/game/squadDungeon.ts +4222 -0
  1007. package/src/engine/game/squadQuestShare.ts +260 -0
  1008. package/src/engine/game/summonObjectSlot.ts +69 -0
  1009. package/src/engine/game/summonObjectWild.ts +73 -0
  1010. package/src/engine/game/summoningRitualUse.ts +141 -0
  1011. package/src/engine/game/talents.ts +356 -0
  1012. package/src/engine/game/tamingRodUse.ts +66 -0
  1013. package/src/engine/game/tempSpawnCreature.ts +136 -0
  1014. package/src/engine/game/tickDungeonPatrolScripts.ts +205 -0
  1015. package/src/engine/game/tickTimedQuests.ts +28 -0
  1016. package/src/engine/game/trade.ts +586 -0
  1017. package/src/engine/game/travel.ts +1155 -0
  1018. package/src/engine/game/types.ts +1855 -0
  1019. package/src/engine/game/vendorOffers.ts +244 -0
  1020. package/src/engine/game/weaponImbueItem.ts +281 -0
  1021. package/src/engine/game/worldSession.ts +183 -0
  1022. package/src/engine/game/worldState.ts +166 -0
  1023. package/src/engine/game.ts +968 -0
  1024. package/src/engine/spells/GAP.md +67 -0
  1025. package/src/engine/spells/absorbs.ts +376 -0
  1026. package/src/engine/spells/addTargetTrigger.ts +53 -0
  1027. package/src/engine/spells/auraPerSecondCost.ts +50 -0
  1028. package/src/engine/spells/auraStacking.ts +497 -0
  1029. package/src/engine/spells/cmangos-special-cases-combustion.ts +13 -0
  1030. package/src/engine/spells/cmangos-special-cases-s18.ts +445 -0
  1031. package/src/engine/spells/cmangos-special-cases-s19.ts +324 -0
  1032. package/src/engine/spells/cmangos-special-cases-s20.ts +385 -0
  1033. package/src/engine/spells/cmangos-special-cases-s21.ts +116 -0
  1034. package/src/engine/spells/cmangos-special-cases-s22.ts +24 -0
  1035. package/src/engine/spells/cmangos-special-cases-s23.ts +52 -0
  1036. package/src/engine/spells/cmangos-special-cases.ts +1570 -0
  1037. package/src/engine/spells/conditions.ts +718 -0
  1038. package/src/engine/spells/effects.ts +203 -0
  1039. package/src/engine/spells/fixtures/oracle-effects-lock9a.json +1 -0
  1040. package/src/engine/spells/immunity.ts +942 -0
  1041. package/src/engine/spells/intentEffects.ts +351 -0
  1042. package/src/engine/spells/interpreter/GAPS.md +21 -0
  1043. package/src/engine/spells/interpreter/amount.ts +109 -0
  1044. package/src/engine/spells/interpreter/class-scripts-kit.ts +478 -0
  1045. package/src/engine/spells/interpreter/diff.ts +246 -0
  1046. package/src/engine/spells/interpreter/duration.ts +90 -0
  1047. package/src/engine/spells/interpreter/form-attrs.json +1 -0
  1048. package/src/engine/spells/interpreter/form-attrs.ts +95 -0
  1049. package/src/engine/spells/interpreter/handlers/aura-remove.ts +113 -0
  1050. package/src/engine/spells/interpreter/handlers/auras-control.ts +1547 -0
  1051. package/src/engine/spells/interpreter/handlers/auras-core.ts +1583 -0
  1052. package/src/engine/spells/interpreter/handlers/auras-misc.ts +1774 -0
  1053. package/src/engine/spells/interpreter/handlers/effect-disenchant.ts +17 -0
  1054. package/src/engine/spells/interpreter/handlers/effect-skinning.ts +20 -0
  1055. package/src/engine/spells/interpreter/handlers/effects-action-utility.ts +1455 -0
  1056. package/src/engine/spells/interpreter/handlers/effects-core.ts +432 -0
  1057. package/src/engine/spells/interpreter/handlers/effects-remainder.ts +105 -0
  1058. package/src/engine/spells/interpreter/handlers/effects-summon-item.ts +687 -0
  1059. package/src/engine/spells/interpreter/handlers/mod-increase-energy-percent.ts +36 -0
  1060. package/src/engine/spells/interpreter/handlers/mod-increase-energy.ts +36 -0
  1061. package/src/engine/spells/interpreter/handlers/periodic-trigger-zero.ts +327 -0
  1062. package/src/engine/spells/interpreter/handlers/procs.ts +131 -0
  1063. package/src/engine/spells/interpreter/handlers/registry.ts +975 -0
  1064. package/src/engine/spells/interpreter/handlers/shared.ts +667 -0
  1065. package/src/engine/spells/interpreter/handlers.ts +9 -0
  1066. package/src/engine/spells/interpreter/hunter-kit.ts +202 -0
  1067. package/src/engine/spells/interpreter/index.ts +525 -0
  1068. package/src/engine/spells/interpreter/item-triggers.ts +1121 -0
  1069. package/src/engine/spells/interpreter/lift-consume-energy.ts +37 -0
  1070. package/src/engine/spells/interpreter/mage-portals.ts +37 -0
  1071. package/src/engine/spells/interpreter/materialize-charm.ts +88 -0
  1072. package/src/engine/spells/interpreter/materialize-dispel-mechanic.ts +25 -0
  1073. package/src/engine/spells/interpreter/materialize-rating-buffs.ts +81 -0
  1074. package/src/engine/spells/interpreter/materialize-speed.ts +109 -0
  1075. package/src/engine/spells/interpreter/materialize-spell-magnet.ts +22 -0
  1076. package/src/engine/spells/interpreter/opcodes.ts +789 -0
  1077. package/src/engine/spells/interpreter/paladin-kit.ts +95 -0
  1078. package/src/engine/spells/interpreter/paladin-seals.ts +499 -0
  1079. package/src/engine/spells/interpreter/priest-warlock-kit.ts +135 -0
  1080. package/src/engine/spells/interpreter/proc.ts +443 -0
  1081. package/src/engine/spells/interpreter/registry/helpers.ts +16 -0
  1082. package/src/engine/spells/interpreter/registry/index.ts +216 -0
  1083. package/src/engine/spells/interpreter/registry/packs/class-abilities.ts +304 -0
  1084. package/src/engine/spells/interpreter/registry/packs/dire-maul.ts +44 -0
  1085. package/src/engine/spells/interpreter/registry/packs/dummy-script-tail.ts +1065 -0
  1086. package/src/engine/spells/interpreter/registry/packs/ex-wave-m.ts +70 -0
  1087. package/src/engine/spells/interpreter/registry/packs/life-tap.ts +107 -0
  1088. package/src/engine/spells/interpreter/registry/packs/paladin.ts +246 -0
  1089. package/src/engine/spells/interpreter/registry/packs/raid-script-summons.ts +26 -0
  1090. package/src/engine/spells/interpreter/registry/packs/raid-threat-wipe.ts +22 -0
  1091. package/src/engine/spells/interpreter/registry/packs/shaman.ts +214 -0
  1092. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-a.ts +269 -0
  1093. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-b.ts +370 -0
  1094. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-c.ts +172 -0
  1095. package/src/engine/spells/interpreter/registry/packs/si4-dummy-hunter.ts +60 -0
  1096. package/src/engine/spells/interpreter/registry/packs/si4-dummy-warrior.ts +31 -0
  1097. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-a.ts +114 -0
  1098. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-b.ts +249 -0
  1099. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-c.ts +233 -0
  1100. package/src/engine/spells/interpreter/registry/types.ts +48 -0
  1101. package/src/engine/spells/interpreter/talent-scripted.ts +329 -0
  1102. package/src/engine/spells/interpreter/targeting.ts +90 -0
  1103. package/src/engine/spells/interpreter/types-intent.ts +1501 -0
  1104. package/src/engine/spells/interpreter/types.ts +419 -0
  1105. package/src/engine/spells/interpreter/warrior-druid-kit.ts +314 -0
  1106. package/src/engine/spells/interpreter/weapon-imbue-kit.ts +384 -0
  1107. package/src/engine/spells/interrupt.ts +217 -0
  1108. package/src/engine/spells/meleeAttackReset.ts +60 -0
  1109. package/src/engine/spells/oocTriggerSpell.ts +49 -0
  1110. package/src/engine/spells/overrideClassScripts.ts +319 -0
  1111. package/src/engine/spells/parryHaste.ts +20 -0
  1112. package/src/engine/spells/procs.ts +300 -0
  1113. package/src/engine/spells/recovery.ts +203 -0
  1114. package/src/engine/spells/scriptTargetDest.ts +76 -0
  1115. package/src/engine/spells/scriptTargets.ts +85 -0
  1116. package/src/engine/spells/singleTargetAura.ts +82 -0
  1117. package/src/engine/spells/specialCasePayloads.ts +57 -0
  1118. package/src/engine/spells/spellAttributes.ts +249 -0
  1119. package/src/engine/spells/spellBonus.ts +143 -0
  1120. package/src/engine/spells/spellModIntents.ts +419 -0
  1121. package/src/engine/spells/spellMods.ts +283 -0
  1122. package/src/engine/spells/spellRadius.ts +15 -0
  1123. package/src/engine/spells/trapObjects.ts +26 -0
  1124. package/src/json.d.ts +7 -0
  1125. package/src/persistence/memoryRepository.ts +23 -0
  1126. package/src/persistence/saveBackups.ts +162 -0
  1127. package/src/persistence/saveFile.ts +68 -0
  1128. package/src/persistence/saveRepository.ts +11 -0
  1129. package/src/persistence/saveShape.ts +668 -0
  1130. package/src/progression/leveling.ts +89 -0
  1131. package/src/progression/rest.ts +1434 -0
  1132. package/src/progression/training.ts +226 -0
  1133. package/src/progression/xpGain.ts +369 -0
  1134. package/src/quests/quests.ts +1580 -0
  1135. package/src/world/aoePull.ts +198 -0
  1136. package/src/world/areaTableDbc.ts +39 -0
  1137. package/src/world/areaTableMapIdPairs.ts +141 -0
  1138. package/src/world/bakeSlug.ts +43 -0
  1139. package/src/world/continuousDungeon.ts +1250 -0
  1140. package/src/world/dungeonBakeProjection.ts +190 -0
  1141. package/src/world/dungeonMapDensity.ts +342 -0
  1142. package/src/world/dungeonMapProjection.ts +135 -0
  1143. package/src/world/dungeonNav.ts +904 -0
  1144. package/src/world/dungeonNpcSim.ts +147 -0
  1145. package/src/world/dungeonObjectives.ts +234 -0
  1146. package/src/world/dungeonPreset.ts +35 -0
  1147. package/src/world/dungeonRoute.ts +311 -0
  1148. package/src/world/dungeonRouteGeometry.ts +732 -0
  1149. package/src/world/dungeonRouteOrder.ts +1037 -0
  1150. package/src/world/dungeonWingRooms.ts +426 -0
  1151. package/src/world/escort.ts +296 -0
  1152. package/src/world/goPoolRoll.ts +75 -0
  1153. package/src/world/instanceObjects.ts +785 -0
  1154. package/src/world/instances.ts +1572 -0
  1155. package/src/world/meetingStones.ts +56 -0
  1156. package/src/world/navmeshFloors.ts +145 -0
  1157. package/src/world/nearGrid.ts +167 -0
  1158. package/src/world/packBudget.ts +613 -0
  1159. package/src/world/rareRoll.ts +335 -0
  1160. package/src/world/routeAuthoring.ts +132 -0
  1161. package/src/world/routeEdit.ts +209 -0
  1162. package/src/world/world.ts +812 -0
  1163. package/src/world/zoneHazards.ts +47 -0
@@ -0,0 +1,1286 @@
1
+ // Upper Blackrock Spire (map 229, UBRS wing) — InstanceDef graph, UBRS bosses and upper trash only.
2
+ // Authority: docs/dungeons/survey/16-blackrock-spire.md, which carries the residual GAPS list.
3
+
4
+ import type { EncounterDef, EncounterEvent, InstanceDef } from '../schema.ts';
5
+ import { dungeonGameObjectsForMap } from '../dungeonGameObjects.ts';
6
+ import {
7
+ entranceForInstance,
8
+ buildClusterEncounters,
9
+ clusterMemberByGuid,
10
+ loadPoolGuidCandidates,
11
+ repackFromGuids,
12
+ wingFilterByNearestBoss,
13
+ } from './pack-from-clusters.ts';
14
+
15
+ // ---- UBRS trash assignment (survey static column; LBRS families excluded) ----
16
+ // Rage Talon* and Blackhand*, minus the Incarcerators and Chromatic guards; friendlies excluded.
17
+
18
+ const STATIC = {
19
+ rageTalonDragonspawn: 21, // 9096
20
+ rageTalonFlamescale: 10, // 10083
21
+ blackhandDreadweaver: 20, // 9817
22
+ blackhandSummoner: 18, // 9818
23
+ blackhandVeteran: 28, // 9819
24
+ blackhandAssassin: 9, // 10318
25
+ blackhandElite: 14, // 10317
26
+ blackhandIronGuard: 18, // 10319
27
+ blackhandThug: 2, // 10762
28
+ rageTalonDragonGuard: 8, // 10366
29
+ rageTalonFireTongue: 8, // 10372
30
+ rageTalonCaptain: 5, // 10371
31
+ } as const;
32
+
33
+ /** Incarcerators (census ×7) - Emberseer event only, not bulk trash. */
34
+ export const UBRS_INCARCERATOR_COUNT = 7; // 10316
35
+
36
+ /** Chromatic Elite Guard (census ×2) - Drakkisath pack only, not bulk trash. */
37
+ export const UBRS_CHROMATIC_GUARD_COUNT = 2; // 10814
38
+
39
+ const ENTRY = {
40
+ // Trash
41
+ rageTalonDragonspawn: 9096,
42
+ rageTalonFlamescale: 10083,
43
+ blackhandDreadweaver: 9817,
44
+ blackhandSummoner: 9818,
45
+ blackhandVeteran: 9819,
46
+ blackhandAssassin: 10318,
47
+ blackhandElite: 10317,
48
+ blackhandIronGuard: 10319,
49
+ blackhandThug: 10762,
50
+ rageTalonDragonGuard: 10366,
51
+ rageTalonFireTongue: 10372,
52
+ rageTalonCaptain: 10371,
53
+ blackhandIncarcerator: 10316,
54
+ chromaticEliteGuard: 10814,
55
+ // Canonical UBRS bosses (mission / survey upper order)
56
+ emberseer: 9816,
57
+ jed: 10509, // rare-elite
58
+ goraluk: 10899,
59
+ solakar: 10264, // summon-only - Father Flame waves finale
60
+ gyth: 10339, // summon-only - stadium
61
+ rend: 10429, // summon-only - stadium concurrent
62
+ beast: 10430,
63
+ drakkisath: 10363,
64
+ // Rookery summons (0 static on map 229)
65
+ rookeryHatcher: 10683,
66
+ rookeryGuardian: 10258,
67
+ rookeryWhelp: 10161, // egg trap chain → 15745 Summon Rookery Whelp
68
+ // Stadium summons (0 static)
69
+ chromaticWhelp: 10442,
70
+ chromaticDragonspawn: 10447,
71
+ blackhandDragonHandler: 10742,
72
+ // Beast post-death flavor (spell 16710 miscValue)
73
+ finkle: 10776,
74
+ // Optional T0.5 — survey creature; may be absent from creatures bake.
75
+ valthalak: 16042,
76
+ } as const;
77
+
78
+ /** Flags for UBRS event DSL. */
79
+ export const UBRS_FLAGS = {
80
+ /** Seal of Ascension used at upper door (areatrigger 2046 / Dragonspine Door). */
81
+ upperDoor: 'ubrs-upper-door',
82
+ /** Aggregate TYPE_ROOM_EVENT DONE (all room runes clear). Cite: instance_blackrock_spire.cpp:384-385. */
83
+ runeRooms: 'ubrs-rune-rooms',
84
+ /** Blackrock Altar used (Emberseer ritual). */
85
+ emberseerAltar: 'ubrs-emberseer-altar',
86
+ /** TYPE_EMBERSEER DONE — opens GO_EMBERSEER_OUT 175153. Cite: cpp:232-235. */
87
+ emberseerDone: 'ubrs-emberseer-done',
88
+ /** Father Flame used (rookery start). */
89
+ fatherFlame: 'ubrs-father-flame',
90
+ /** Stadium fully cleared (Gyth + Rend). */
91
+ stadiumDone: 'ubrs-stadium-done',
92
+ /** General Drakkisath dead. */
93
+ drakkisathDone: 'ubrs-drakkisath-done',
94
+ /** Optional Lord Valthalak brazier used. */
95
+ valthalak: 'ubrs-valthalak',
96
+ } as const;
97
+
98
+ /** Per-room TYPE_ROOM_EVENT flag. Cite: blackrock_spire.h:56-62 GO_ROOM_*_RUNE. */
99
+ export function ubrsRuneRoomFlag(goEntry: number): string {
100
+ return `ubrs-rune-room:${goEntry}`;
101
+ }
102
+
103
+ /** Seal of Ascension entry gate - survey areatrigger 2046 + item 12344; GO 164725. */
104
+ export const UBRS_SEAL_GATE = {
105
+ goEntry: 164725, // Dragonspine Door
106
+ requiredItem: 12344, // Seal of Ascension
107
+ } as const;
108
+
109
+ /** TYPE_ROOM_EVENT room runes. Cite: blackrock_spire.h:56-62. */
110
+ export const UBRS_ROOM_RUNES: readonly number[] = [
111
+ 175194, 175195, 175196, 175197, 175198, 175199, 175200,
112
+ ];
113
+
114
+ // Pyroguard Emberseer altar plus the Growing ramp: the altar objectGate delays attackability until
115
+ // 20 stacks of 16048. Residual: the type-18 three-player channel, since the product is solo.
116
+ export const UBRS_EMBERSEER = {
117
+ goEntry: 175706, // Blackrock Altar
118
+ growSpellId: 16048,
119
+ growTickMs: 3_000,
120
+ maxGrowingStacks: 20,
121
+ /** Full grow before attackable — spell-data 16048 durationMs (= 20 × 3000). */
122
+ growFullMs: 60_000,
123
+ incarceratorEntry: 10316,
124
+ incarceratorCount: 7,
125
+ /** Pyroguard Emberseer himself. Cite: blackrock_spire.h:23 NPC_PYROGUARD_EMBERSEER. */
126
+ bossEntry: 9816,
127
+ /** creature guid 2290394. He stands here before the altar; the grow is not a spawn. */
128
+ spawn: { x: 144.59, y: -258.05, z: 96.5 },
129
+ spawnGuid: 2290394,
130
+ } as const;
131
+
132
+ // Incarcerators and Emberseer are immune until the altar and Growing finish. `undefined` means the
133
+ // body is not this event's, so the caller keeps template hostility.
134
+ export function ubrsEventHostile(
135
+ entry: number,
136
+ altarUsed: boolean,
137
+ grown: boolean,
138
+ ): boolean | undefined {
139
+ if (entry === UBRS_EMBERSEER.incarceratorEntry) return altarUsed;
140
+ if (entry === UBRS_EMBERSEER.bossEntry) return grown;
141
+ return undefined;
142
+ }
143
+
144
+ // Sort radius for TYPE_ROOM_EVENT mobs around each room rune. Cite: instance_blackrock_spire.cpp:351
145
+ // GetDistance < 10.0f.
146
+ export const UBRS_ROOM_EVENT_RADIUS_YD = 10;
147
+
148
+ // Lord Valthalak optional T0.5 (TYPE_VALTHALAK): GO 181050, item 22056, trigger 16048, NPC 16042.
149
+ // 16042 may be absent from the bake; the survey id is still wired.
150
+ export const UBRS_VALTHALAK = {
151
+ encId: 'lord-valthalak',
152
+ goEntry: 181050, // Lord Valthalak Brazier Spell Focus
153
+ requiredItem: 22056, // Brazier of Beckoning
154
+ triggerEntry: 16048,
155
+ bossEntry: 16042,
156
+ /** Trigger spawn — dungeonSpawns map 229 guid 2290600. */
157
+ spawn: { x: 44.71, y: -536.049, z: 110.936 },
158
+ } as const;
159
+
160
+ /** Altar GO entry alias (objectGate / pins). */
161
+ export const UBRS_EMBERSEER_ALTAR = {
162
+ goEntry: UBRS_EMBERSEER.goEntry,
163
+ } as const;
164
+
165
+ /** Father Flame rookery trigger - survey GO 175245. */
166
+ export const UBRS_FATHER_FLAME = {
167
+ goEntry: 175245, // Father Flame
168
+ } as const;
169
+
170
+ // Solakar / Father Flame timers (TYPE_FLAMEWREATH): 30 s after waves 0–3, 40 s after 4–5, then
171
+ // Solakar. A pure from-call schedule that does not wait for a clear. Cite: :701-706.
172
+ export const UBRS_SOLAKAR = {
173
+ goEntry: 175245,
174
+ /** Spawn pos — instance_blackrock_spire.cpp:99 rookeryEventSpawnPos. */
175
+ spawn: { x: 51.11098, y: -266.0549, z: 92.87846 },
176
+ waveGapEarlyMs: 30_000,
177
+ waveGapLateMs: 40_000,
178
+ /** calledIdx 0–3 use early; 4–5 use late (before Solakar wave). */
179
+ earlyWaveCount: 4,
180
+ } as const;
181
+
182
+ // Rookery egg → whelp while Hatchers live: first disturb after urand(8000,10000), 2 s at the egg,
183
+ // next after urand(7500,10000), nearest unused egg within 20 yd, one whelp per egg.
184
+ export const UBRS_ROOKERY_EGGS = {
185
+ eggGoEntry: 175124,
186
+ whelpEntry: ENTRY.rookeryWhelp,
187
+ hatcherEntry: ENTRY.rookeryHatcher,
188
+ disturbSpellId: 15_746,
189
+ searchRangeYd: 20,
190
+ /** cpp:923 min bound. */
191
+ firstDisturbMinMs: 8_000,
192
+ /** cpp:923 max bound. */
193
+ firstDisturbMaxMs: 10_000,
194
+ /** cpp:936 wait after arriving at egg before cast. */
195
+ waitAtEggMs: 2_000,
196
+ /** cpp:939 min bound. */
197
+ nextDisturbMinMs: 7_500,
198
+ /** cpp:939 max bound. */
199
+ nextDisturbMaxMs: 10_000,
200
+ // First whelp after a hatcher wave call — min disturb + wait at egg (walk omitted; no invented path
201
+ // time).
202
+ firstHatchAfterCallMs: 8_000 + 2_000,
203
+ /** Subsequent hatch gap — min next disturb (walk omitted). */
204
+ nextHatchMs: 7_500,
205
+ } as const;
206
+
207
+ // Absolute ms for the Nth egg hatch (0-based) after hatchers first appear. Cite: UBRS_ROOKERY_EGGS
208
+ // firstHatchAfterCallMs / nextHatchMs.
209
+ export function rookeryHatchAtMs(hatcherPresentSinceMs: number, hatchIndex: number): number {
210
+ if (hatchIndex <= 0) {
211
+ return hatcherPresentSinceMs + UBRS_ROOKERY_EGGS.firstHatchAfterCallMs;
212
+ }
213
+ return (
214
+ hatcherPresentSinceMs
215
+ + UBRS_ROOKERY_EGGS.firstHatchAfterCallMs
216
+ + hatchIndex * UBRS_ROOKERY_EGGS.nextHatchMs
217
+ );
218
+ }
219
+
220
+ // The Beast intro elites plus Finkle Einhorn: 3× 10317 fight as the Beast pack, and Finkle appears
221
+ // as a friendly body after the Beast dies. Cite: blackrock_spire.h:93-98; cpp:827-841, :488-491.
222
+ export const UBRS_BEAST = {
223
+ beastEntry: ENTRY.beast,
224
+ introEliteEntry: ENTRY.blackhandElite,
225
+ introEliteCount: 3,
226
+ /** aBeastLocs — blackrock_spire.h:93-98. */
227
+ introLocs: [
228
+ { x: 98.09, y: -563.45, z: 109.86 },
229
+ { x: 99.81, y: -561.47, z: 109.24 },
230
+ { x: 96.92, y: -560.98, z: 110.18 },
231
+ ] as const,
232
+ finkleEntry: ENTRY.finkle,
233
+ finkleSpellId: 16_710,
234
+ } as const;
235
+
236
+ /** Cite: instance_blackrock_spire.cpp:488-491 — Finkle only after Beast death/despawn. */
237
+ export function finkleMaySpawn(beastDead: boolean): boolean {
238
+ return beastDead;
239
+ }
240
+
241
+ // Cite: instance_blackrock_spire.cpp StartflamewreathEventIfCan :774-778 — refuse Father Flame when
242
+ // TYPE_DRAKKISATH == DONE.
243
+ export function solakarStartBlockedByDrakkisath(flags: readonly string[]): boolean {
244
+ return flags.includes(UBRS_FLAGS.drakkisathDone);
245
+ }
246
+
247
+ // One Flamewreath add slot: waveIndex 0 is always a Hatcher and 1–5 are 50/50. `roll` in [0,1) —
248
+ // under 0.5 is Hatcher, at or above is Guardian. Cite: instance_blackrock_spire.cpp:691.
249
+ export function solakarAddEntry(waveIndex: number, roll: number): number {
250
+ if (waveIndex <= 0) return ENTRY.rookeryHatcher;
251
+ return roll < 0.5 ? ENTRY.rookeryHatcher : ENTRY.rookeryGuardian;
252
+ }
253
+
254
+ // Collapse two add entries into pack rows (order: Hatcher then Guardian when mixed). Cite:
255
+ // DoSendNextFlamewreathWave two SummonCreature per wave :686-697.
256
+ export function solakarWavePack(
257
+ waveIndex: number,
258
+ rolls: readonly [number, number],
259
+ ): { creatureEntry: number; count: number }[] {
260
+ if (waveIndex >= 6) return [{ creatureEntry: ENTRY.solakar, count: 1 }];
261
+ const a = solakarAddEntry(waveIndex, rolls[0]!);
262
+ const b = solakarAddEntry(waveIndex, rolls[1]!);
263
+ if (a === b) return [{ creatureEntry: a, count: 2 }];
264
+ // Stable order for kill-supply / floor flatten: Hatcher then Guardian.
265
+ const first = a === ENTRY.rookeryHatcher ? a : b;
266
+ const second = first === a ? b : a;
267
+ return [
268
+ { creatureEntry: first, count: 1 },
269
+ { creatureEntry: second, count: 1 },
270
+ ];
271
+ }
272
+
273
+ // Roll full Flamewreath waves (6 add waves + Solakar) from seeded rng in [0,1); wave 0 is always
274
+ // 2× Hatcher. Cite: instance_blackrock_spire.cpp:683-716.
275
+ export function materializeSolakarFlamewreathEncounter(
276
+ enc: EncounterDef,
277
+ rng: () => number,
278
+ ): EncounterDef {
279
+ if (enc.id !== 'solakar-flamewreath') return enc;
280
+ const waves: { pack: { creatureEntry: number; count: number }[] }[] = [];
281
+ for (let i = 0; i < 6; i++) {
282
+ waves.push({ pack: solakarWavePack(i, [rng(), rng()]) });
283
+ }
284
+ waves.push({ pack: [{ creatureEntry: ENTRY.solakar, count: 1 }] });
285
+ return {
286
+ ...enc,
287
+ events: (enc.events ?? []).map((ev) =>
288
+ (ev.kind === 'waves' ? { kind: 'waves' as const, waves } : ev),
289
+ ),
290
+ };
291
+ }
292
+
293
+ // Solakar / Father Flame waves (TYPE_FLAMEWREATH): wave 1 is 2× 10683 and waves 2–6 hold the
294
+ // expected 1+1 mix, with the true 50/50 coming from materializeSolakarFlamewreathEncounter.
295
+ export const UBRS_SOLAKAR_WAVES = [
296
+ { pack: [{ creatureEntry: ENTRY.rookeryHatcher, count: 2 }] },
297
+ {
298
+ pack: [
299
+ { creatureEntry: ENTRY.rookeryHatcher, count: 1 },
300
+ { creatureEntry: ENTRY.rookeryGuardian, count: 1 },
301
+ ],
302
+ },
303
+ {
304
+ pack: [
305
+ { creatureEntry: ENTRY.rookeryHatcher, count: 1 },
306
+ { creatureEntry: ENTRY.rookeryGuardian, count: 1 },
307
+ ],
308
+ },
309
+ {
310
+ pack: [
311
+ { creatureEntry: ENTRY.rookeryHatcher, count: 1 },
312
+ { creatureEntry: ENTRY.rookeryGuardian, count: 1 },
313
+ ],
314
+ },
315
+ {
316
+ pack: [
317
+ { creatureEntry: ENTRY.rookeryHatcher, count: 1 },
318
+ { creatureEntry: ENTRY.rookeryGuardian, count: 1 },
319
+ ],
320
+ },
321
+ {
322
+ pack: [
323
+ { creatureEntry: ENTRY.rookeryHatcher, count: 1 },
324
+ { creatureEntry: ENTRY.rookeryGuardian, count: 1 },
325
+ ],
326
+ },
327
+ { pack: [{ creatureEntry: ENTRY.solakar, count: 1 }] },
328
+ ] as const;
329
+
330
+ // Stadium wave table (blackrock_spire.h aStadiumEventNpcs) - survey exact counts. Totals: 17×10442 +
331
+ // 9×10447 + 5×10742 = 31, then Gyth (Rend via boss_gyth ScriptDev).
332
+ export const UBRS_STADIUM_ADD_WAVES = [
333
+ {
334
+ pack: [
335
+ { creatureEntry: ENTRY.chromaticWhelp, count: 3 },
336
+ { creatureEntry: ENTRY.chromaticDragonspawn, count: 1 },
337
+ ],
338
+ },
339
+ {
340
+ pack: [
341
+ { creatureEntry: ENTRY.chromaticWhelp, count: 3 },
342
+ { creatureEntry: ENTRY.chromaticDragonspawn, count: 1 },
343
+ ],
344
+ },
345
+ {
346
+ pack: [
347
+ { creatureEntry: ENTRY.chromaticWhelp, count: 2 },
348
+ { creatureEntry: ENTRY.chromaticDragonspawn, count: 1 },
349
+ { creatureEntry: ENTRY.blackhandDragonHandler, count: 1 },
350
+ ],
351
+ },
352
+ {
353
+ pack: [
354
+ { creatureEntry: ENTRY.chromaticWhelp, count: 2 },
355
+ { creatureEntry: ENTRY.chromaticDragonspawn, count: 1 },
356
+ { creatureEntry: ENTRY.blackhandDragonHandler, count: 1 },
357
+ ],
358
+ },
359
+ {
360
+ pack: [
361
+ { creatureEntry: ENTRY.chromaticWhelp, count: 3 },
362
+ { creatureEntry: ENTRY.chromaticDragonspawn, count: 1 },
363
+ { creatureEntry: ENTRY.blackhandDragonHandler, count: 1 },
364
+ ],
365
+ },
366
+ {
367
+ pack: [
368
+ { creatureEntry: ENTRY.chromaticWhelp, count: 2 },
369
+ { creatureEntry: ENTRY.chromaticDragonspawn, count: 2 },
370
+ { creatureEntry: ENTRY.blackhandDragonHandler, count: 1 },
371
+ ],
372
+ },
373
+ {
374
+ pack: [
375
+ { creatureEntry: ENTRY.chromaticWhelp, count: 2 },
376
+ { creatureEntry: ENTRY.chromaticDragonspawn, count: 2 },
377
+ { creatureEntry: ENTRY.blackhandDragonHandler, count: 1 },
378
+ ],
379
+ },
380
+ ] as const;
381
+
382
+ // Full stadium encounter waves: 7 add waves then Gyth alone. The former concurrent Gyth+Rend wave
383
+ // is RETIRED — boss_gyth ScriptDev owns the <11% Rend inject, and both live double-fires him.
384
+ export const UBRS_STADIUM_WAVES = [
385
+ ...UBRS_STADIUM_ADD_WAVES,
386
+ { pack: [{ creatureEntry: ENTRY.gyth, count: 1 }] },
387
+ ] as const;
388
+
389
+ // Stadium wave pacing — clear-OR-60s hybrid with overlap: 60 s after each add wave, or immediately
390
+ // when the wave is dead. The timer stops after the last add, and Gyth starts on clear only.
391
+ export const UBRS_STADIUM = {
392
+ /** Inter-add-wave release — instance_blackrock_spire.cpp:672. */
393
+ waveOrClearMs: 60_000,
394
+ /** Add waves before Gyth (MAX_STADIUM_WAVES). */
395
+ addWaveCount: 7,
396
+ /** Wave summon pos — blackrock_spire.h aStadiumLocs[0]. */
397
+ waveSpawn: { x: 210.00, y: -420.30, z: 110.94 },
398
+ /** Gyth summon pos — blackrock_spire.h aStadiumLocs[1]. */
399
+ gythSpawn: { x: 210.14, y: -397.54, z: 111.1 },
400
+ /** Arena centre — blackrock_spire.h aStadiumLocs[2]. The fight is here, not the tunnel. */
401
+ centre: { x: 163.62, y: -420.33, z: 110.47 },
402
+ // TYPE_STADIUM start. Cite: AreaTrigger.dbc id=2026 (map 229, r=20); instance_blackrock_spire.cpp
403
+ // :32, :808-823. Not aStadiumLocs[2] — a 50 yd circle around the centre arms a south-edge drop.
404
+ at2026: { x: 153.763, y: -419.833, z: 110.472, radius: 20 },
405
+ // Rend/Nefarius balcony — aStadiumLocs[4], on-mesh at z 121.97 (the arena-floor z at this xy
406
+ // snaps to the balcony). 25 yd planar from AT 2026, and |dz| 11.5 so sameStoreyAsParty is false.
407
+ southDrop: { x: 161.01, y: -443.73, z: 121.97 },
408
+ // Eastern landing before the stadium rim. GO 153464 guid 2290419. trashbot.md: ramps on the Eastern side,
409
+ // then drop at the southern edge.
410
+ eastRamp: { x: 183.647, y: -369.15, z: 117.143 },
411
+ } as const;
412
+
413
+ /** Summon-only / event-temp entries - never pure static trash packs. */
414
+ export const UBRS_SUMMON_ONLY_ENTRIES = new Set<number>([
415
+ ENTRY.solakar, // 10264
416
+ ENTRY.gyth, // 10339
417
+ ENTRY.rend, // 10429
418
+ ENTRY.rookeryHatcher, // 10683
419
+ ENTRY.rookeryGuardian, // 10258
420
+ ENTRY.rookeryWhelp, // 10161
421
+ ENTRY.chromaticWhelp, // 10442
422
+ ENTRY.chromaticDragonspawn, // 10447
423
+ ENTRY.blackhandDragonHandler, // 10742
424
+ ENTRY.finkle, // 10776 — post-Beast flavor, not trash
425
+ ]);
426
+
427
+ /** Friendlies / service / LBRS / technical - never in UBRS combat graph. */
428
+ export const UBRS_EXCLUDED_ENTRIES = new Set<number>([
429
+ // Friendlies / service
430
+ 10740, // Awbee
431
+ 10257, // Bijou
432
+ 10299, // Scarshield Infiltrator
433
+ 10799, // Warosh
434
+ 15560, // Elder Stonefort (Lunar Festival)
435
+ 16044, // Mor Grayhoof Trigger
436
+ 16048, // Lord Valthalak Trigger
437
+ // LBRS bosses
438
+ 9196, // Omokk
439
+ 9236, // Vosh
440
+ 9237, // Voone
441
+ 10596, // Smolderweb
442
+ 10584, // Urok
443
+ 9736, // Zigris
444
+ 10220, // Halycon
445
+ 10268, // Gizrul
446
+ 9568, // Wyrmthalak
447
+ // LBRS trash families (sample / name lists)
448
+ 9045, // Scarshield Acolyte
449
+ 9097, // Scarshield Legionnaire
450
+ 9199, // Spirestone Enforcer
451
+ 9267, // Smolderthorn Axe Thrower
452
+ 9259, // Firebrand Grunt
453
+ 9692, // Bloodaxe Raider
454
+ 10374, // Spire Spider
455
+ 10162, // Nefarius (cosmetic stadium)
456
+ ENTRY.finkle, // Finkle Einhorn (Beast corpse flavor — not combat graph)
457
+ // Valthalak 16042 is optional boss (not pure-static trash); spine-owned.
458
+ ]);
459
+
460
+ // UBRS-completable survey quests, upper wing only. Multi-zone T0.5 chains and the Lunar Festival
461
+ // quest are excluded. Cite: docs/dungeons/survey/16-blackrock-spire.md.
462
+ export const UBRS_QUESTS = [
463
+ 4764, // Doomrigger's Clasp - GO in UBRS
464
+ 4768, // The Darkstone Tablet - GO in UBRS
465
+ 5089, // General Drakkisath's Command - chain into Demise (item from Wyrmthalak)
466
+ 5102, // General Drakkisath's Demise - kill Drakkisath
467
+ 6502, // Drakefire Amulet - Blood of the Black Dragon Champion (Drakkisath)
468
+ 6602, // Blood of the Black Dragon Champion (H)
469
+ 6821, // Eye of the Emberseer
470
+ 7761, // Blackhand's Command - ends at Drakkisath's Brand GO
471
+ ] as const;
472
+
473
+ /** Rounded static pack targets used by this graph (for tests / docs). */
474
+ export const UBRS_STATIC = { ...STATIC } as const;
475
+
476
+ // Boss spells: creature.spells from bake (game-data) - no invented ids.
477
+ // Solakar 10264, Gyth 10339, Rend 10429 present in bake; summon-only with spells ok.
478
+ const BOSS_SPELLS = {
479
+ emberseer: [16079, 16536],
480
+ jed: [15749, 11972, 14516],
481
+ goraluk: [6253, 16172, 15580],
482
+ solakar: [16727, 16556],
483
+ gyth: [20667, 20712, 18763],
484
+ rend: [20691, 15589, 23931, 8269, 13736, 15708, 15284],
485
+ beast: [16636, 16144, 16788, 16785, 15506, 14100, 20477],
486
+ drakkisath: [23462, 20691, 23023, 23931, 16789, 12097, 16805, 15548, 16419, 15284],
487
+ } as const;
488
+
489
+ /** Bake-sourced boss spell lists (for tests). */
490
+ export const UBRS_BOSS_SPELLS = { ...BOSS_SPELLS } as const;
491
+
492
+ /** Split a static spawn count into pack sizes in [2, 5] (prefer 4). Remainder 1 folded into prior pack. */
493
+ export function splitPackSizes(total: number, prefer = 4): number[] {
494
+ if (total <= 0) return [];
495
+ if (total === 1) return [1];
496
+ const packs: number[] = [];
497
+ let left = total;
498
+ while (left > 0) {
499
+ if (left <= 5) {
500
+ packs.push(left);
501
+ break;
502
+ }
503
+ let n = prefer;
504
+ const rem = left - n;
505
+ if (rem === 1) n = prefer - 1;
506
+ packs.push(n);
507
+ left -= n;
508
+ }
509
+ return packs;
510
+ }
511
+
512
+ function trashPull(
513
+ id: string,
514
+ name: string,
515
+ creatureEntry: number,
516
+ count: number,
517
+ events?: EncounterEvent[],
518
+ ): EncounterDef {
519
+ const enc: EncounterDef = {
520
+ id,
521
+ name,
522
+ kind: 'trash',
523
+ creatureEntry,
524
+ };
525
+ if (count > 1) enc.pack = [{ creatureEntry, count: count - 1 }];
526
+ if (events && events.length) enc.events = events;
527
+ return enc;
528
+ }
529
+
530
+ /** Expand one census entry into ordered trash pulls (ids `${prefix}-0` …). */
531
+ function trashFromCensus(
532
+ _prefix: string,
533
+ _displayName: string,
534
+ _creatureEntry: number,
535
+ _total: number,
536
+ ): EncounterDef[] {
537
+ // DP1: cluster packs supply trash; hand spine keeps bosses/events only.
538
+ return [];
539
+ }
540
+
541
+ function boss(
542
+ id: string,
543
+ name: string,
544
+ creatureEntry: number,
545
+ bossSpells: readonly number[],
546
+ events?: EncounterEvent[],
547
+ intro?: string,
548
+ pack?: { creatureEntry: number; count: number }[],
549
+ ): EncounterDef {
550
+ const enc: EncounterDef = {
551
+ id,
552
+ name,
553
+ kind: 'boss',
554
+ creatureEntry,
555
+ };
556
+ if (bossSpells.length) enc.bossSpells = [...bossSpells];
557
+ if (pack && pack.length) enc.pack = pack;
558
+ if (intro) enc.intro = intro;
559
+ if (events && events.length) enc.events = events;
560
+ return enc;
561
+ }
562
+
563
+ function half<T>(arr: T[]): [T[], T[]] {
564
+ const mid = Math.ceil(arr.length / 2);
565
+ return [arr.slice(0, mid), arr.slice(mid)];
566
+ }
567
+
568
+ // Linear encounter graph in survey UBRS boss order: seal entry → rune rooms → Emberseer →
569
+ // Jed/Goraluk → rookery → Solakar → stadium → Gyth/Rend → Beast → Drakkisath.
570
+ function buildHandSpine(): EncounterDef[] {
571
+ // Rune rooms / entry Blackhand
572
+ const dreadweavers = trashFromCensus(
573
+ 'blackhand-dreadweaver',
574
+ 'Blackhand Dreadweaver',
575
+ ENTRY.blackhandDreadweaver,
576
+ STATIC.blackhandDreadweaver,
577
+ );
578
+ const summoners = trashFromCensus(
579
+ 'blackhand-summoner',
580
+ 'Blackhand Summoner',
581
+ ENTRY.blackhandSummoner,
582
+ STATIC.blackhandSummoner,
583
+ );
584
+ const veterans = trashFromCensus(
585
+ 'blackhand-veteran',
586
+ 'Blackhand Veteran',
587
+ ENTRY.blackhandVeteran,
588
+ STATIC.blackhandVeteran,
589
+ );
590
+ const assassins = trashFromCensus(
591
+ 'blackhand-assassin',
592
+ 'Blackhand Assassin',
593
+ ENTRY.blackhandAssassin,
594
+ STATIC.blackhandAssassin,
595
+ );
596
+ const elites = trashFromCensus(
597
+ 'blackhand-elite',
598
+ 'Blackhand Elite',
599
+ ENTRY.blackhandElite,
600
+ STATIC.blackhandElite,
601
+ );
602
+ const ironGuards = trashFromCensus(
603
+ 'blackhand-iron-guard',
604
+ 'Blackhand Iron Guard',
605
+ ENTRY.blackhandIronGuard,
606
+ STATIC.blackhandIronGuard,
607
+ );
608
+ const thugs = trashFromCensus(
609
+ 'blackhand-thug',
610
+ 'Blackhand Thug',
611
+ ENTRY.blackhandThug,
612
+ STATIC.blackhandThug,
613
+ );
614
+
615
+ // Rookery / stadium Rage Talon
616
+ const dragonspawn = trashFromCensus(
617
+ 'rage-talon-dragonspawn',
618
+ 'Rage Talon Dragonspawn',
619
+ ENTRY.rageTalonDragonspawn,
620
+ STATIC.rageTalonDragonspawn,
621
+ );
622
+ const flamescales = trashFromCensus(
623
+ 'rage-talon-flamescale',
624
+ 'Rage Talon Flamescale',
625
+ ENTRY.rageTalonFlamescale,
626
+ STATIC.rageTalonFlamescale,
627
+ );
628
+ const dragonGuards = trashFromCensus(
629
+ 'rage-talon-dragon-guard',
630
+ 'Rage Talon Dragon Guard',
631
+ ENTRY.rageTalonDragonGuard,
632
+ STATIC.rageTalonDragonGuard,
633
+ );
634
+ const fireTongues = trashFromCensus(
635
+ 'rage-talon-fire-tongue',
636
+ 'Rage Talon Fire Tongue',
637
+ ENTRY.rageTalonFireTongue,
638
+ STATIC.rageTalonFireTongue,
639
+ );
640
+ const captains = trashFromCensus(
641
+ 'rage-talon-captain',
642
+ 'Rage Talon Captain',
643
+ ENTRY.rageTalonCaptain,
644
+ STATIC.rageTalonCaptain,
645
+ );
646
+
647
+ const [summonerPre, summonerPost] = half(summoners);
648
+ const [vetPre, vetPost] = half(veterans);
649
+ const [dreadPre, dreadPost] = half(dreadweavers);
650
+ const [elitePre, elitePost] = half(elites);
651
+ const [ironPre, ironPost] = half(ironGuards);
652
+ const [dsPre, dsPost] = half(dragonspawn);
653
+ const [flamePre, flamePost] = half(flamescales);
654
+
655
+ const out: EncounterDef[] = [];
656
+
657
+ // --- Seal of Ascension entry (areatrigger 2046 + item 12344) ---
658
+ // objectGate on first entry trash; subsequent path requires flag.
659
+ const firstEntry = dreadPre[0];
660
+ if (firstEntry) {
661
+ out.push({
662
+ ...firstEntry,
663
+ id: 'ubrs-seal-entry',
664
+ name: 'Seal of Ascension Gate',
665
+ events: [
666
+ {
667
+ kind: 'objectGate',
668
+ goEntry: UBRS_SEAL_GATE.goEntry,
669
+ requiredItem: UBRS_SEAL_GATE.requiredItem,
670
+ setsFlag: UBRS_FLAGS.upperDoor,
671
+ once: true,
672
+ },
673
+ { kind: 'requiresFlag', flag: UBRS_FLAGS.upperDoor },
674
+ ],
675
+ });
676
+ out.push(...dreadPre.slice(1));
677
+ } else {
678
+ out.push(
679
+ trashPull(
680
+ 'ubrs-seal-entry',
681
+ 'Seal of Ascension Gate',
682
+ ENTRY.blackhandDreadweaver,
683
+ 1,
684
+ [
685
+ {
686
+ kind: 'objectGate',
687
+ goEntry: UBRS_SEAL_GATE.goEntry,
688
+ requiredItem: UBRS_SEAL_GATE.requiredItem,
689
+ setsFlag: UBRS_FLAGS.upperDoor,
690
+ once: true,
691
+ },
692
+ { kind: 'requiresFlag', flag: UBRS_FLAGS.upperDoor },
693
+ ],
694
+ ),
695
+ );
696
+ }
697
+
698
+ // Rune rooms (TYPE_ROOM_EVENT): ubrs-rune-rooms is stamped on a real cluster pack in
699
+ // buildEncounters — the census bands here are empty, so it set the flag on nothing.
700
+ out.push(...summonerPre, ...vetPre, ...thugs);
701
+
702
+ // --- Pyroguard Emberseer (TYPE_EMBERSEER) ---
703
+ // He stands from the mount UNINTERACTIBLE; the altar starts Growing and 20 stacks unseal him.
704
+ {
705
+ const emb = boss(
706
+ 'pyroguard-emberseer',
707
+ 'Pyroguard Emberseer',
708
+ ENTRY.emberseer,
709
+ BOSS_SPELLS.emberseer,
710
+ [
711
+ { kind: 'requiresFlag', flag: UBRS_FLAGS.upperDoor },
712
+ { kind: 'requiresFlag', flag: UBRS_FLAGS.runeRooms },
713
+ {
714
+ kind: 'objectGate',
715
+ goEntry: UBRS_EMBERSEER.goEntry,
716
+ setsFlag: UBRS_FLAGS.emberseerAltar,
717
+ once: true,
718
+ },
719
+ { kind: 'requiresFlag', flag: UBRS_FLAGS.emberseerAltar },
720
+ { kind: 'setsFlag', flag: UBRS_FLAGS.emberseerDone },
721
+ ],
722
+ 'Use the Blackrock Altar. Pyroguard Emberseer grows for 60s, then becomes attackable. The seven Incarcerators break their chant when the altar is used.',
723
+ );
724
+ // creature guid 2290394 — he stands here from mount (cpp Reset UNINTERACTIBLE).
725
+ emb.origin = { ...UBRS_EMBERSEER.spawn };
726
+ out.push(emb);
727
+ }
728
+
729
+ // --- Rookery (same floor as Binding). Solakar skippable — trashbot.md / TYPE_FLAMEWREATH. ---
730
+ out.push(...dsPre, ...flamePre, ...dragonGuards.slice(0, Math.ceil(dragonGuards.length / 2)));
731
+ {
732
+ const sol = boss(
733
+ 'solakar-flamewreath',
734
+ 'Solakar Flamewreath',
735
+ ENTRY.solakar,
736
+ BOSS_SPELLS.solakar,
737
+ [
738
+ {
739
+ kind: 'objectGate',
740
+ goEntry: UBRS_FATHER_FLAME.goEntry,
741
+ setsFlag: UBRS_FLAGS.fatherFlame,
742
+ once: true,
743
+ },
744
+ { kind: 'requiresFlag', flag: UBRS_FLAGS.fatherFlame },
745
+ {
746
+ kind: 'waves',
747
+ waves: UBRS_SOLAKAR_WAVES.map((w) => ({
748
+ pack: w.pack.map((p) => ({ creatureEntry: p.creatureEntry, count: p.count })),
749
+ })),
750
+ },
751
+ ],
752
+ 'Father Flame awakens the rookery. Hatchers disturb eggs into whelps on a timer; Hatchers and Guardians pour on a 30s/40s schedule - then Solakar. Locked out if Drakkisath is already dead.',
753
+ );
754
+ sol.origin = { ...UBRS_SOLAKAR.spawn };
755
+ sol.optional = true;
756
+ out.push(sol);
757
+ }
758
+
759
+ // --- Hall of Blackhand (up the shaft): Jed optional, then Goraluk ---
760
+ out.push(
761
+ ...summonerPost,
762
+ ...vetPost,
763
+ ...dreadPost.slice(0, Math.ceil(dreadPost.length / 2)),
764
+ ...assassins.slice(0, Math.ceil(assassins.length / 2)),
765
+ ...elitePre,
766
+ ...ironPre,
767
+ );
768
+ out.push({
769
+ ...boss(
770
+ 'jed-runewatcher',
771
+ 'Jed Runewatcher',
772
+ ENTRY.jed,
773
+ BOSS_SPELLS.jed,
774
+ undefined,
775
+ 'Jed Runewatcher, a rare Blackhand elite, watches the rune halls.',
776
+ ),
777
+ optional: true,
778
+ });
779
+ out.push(
780
+ ...assassins.slice(Math.ceil(assassins.length / 2)),
781
+ ...dreadPost.slice(Math.ceil(dreadPost.length / 2)),
782
+ );
783
+ out.push(
784
+ boss(
785
+ 'goraluk-anvilcrack',
786
+ 'Goraluk Anvilcrack',
787
+ ENTRY.goraluk,
788
+ BOSS_SPELLS.goraluk,
789
+ undefined,
790
+ 'Goraluk Anvilcrack forges weapons for the Blackhand orcs of the upper spire.',
791
+ ),
792
+ );
793
+
794
+ // --- Stadium approach ---
795
+ out.push(
796
+ ...dsPost,
797
+ ...flamePost,
798
+ ...dragonGuards.slice(Math.ceil(dragonGuards.length / 2)),
799
+ ...fireTongues,
800
+ ...captains,
801
+ ...elitePost.slice(0, Math.ceil(elitePost.length / 2)),
802
+ ...ironPost.slice(0, Math.ceil(ironPost.length / 2)),
803
+ );
804
+
805
+ // Stadium - TYPE_STADIUM: 7 add waves clear-OR-60s + Gyth on last-add clear;
806
+ // ScriptDev owns <11% Rend mid-fight inject
807
+ {
808
+ const gyth = boss(
809
+ 'gyth-rend',
810
+ 'Gyth & Warchief Rend Blackhand',
811
+ ENTRY.gyth,
812
+ BOSS_SPELLS.gyth,
813
+ [
814
+ {
815
+ kind: 'waves',
816
+ waves: UBRS_STADIUM_WAVES.map((w) => ({
817
+ pack: w.pack.map((p) => ({ creatureEntry: p.creatureEntry, count: p.count })),
818
+ })),
819
+ },
820
+ { kind: 'setsFlag', flag: UBRS_FLAGS.stadiumDone },
821
+ ],
822
+ 'The Stadium: chromatic waves on a clear-or-60s clock, then Gyth. ScriptDev owns <50% Chromatic Chaos and <11% Summon Rend mid-fight inject (SESSION 10).',
823
+ );
824
+ // aStadiumLocs[2] — spawn is the tunnel; seedRouteFromPlan drops a boss with no origin.
825
+ gyth.origin = { ...UBRS_STADIUM.centre };
826
+ out.push(gyth);
827
+ }
828
+
829
+ // --- Beast approach ---
830
+ out.push(
831
+ ...elitePost.slice(Math.ceil(elitePost.length / 2)),
832
+ ...ironPost.slice(Math.ceil(ironPost.length / 2)),
833
+ );
834
+
835
+ // Beast: 3× Blackhand Elite intro pack (aBeastLocs); Finkle 10776 after death (controller).
836
+ out.push(
837
+ boss(
838
+ 'the-beast',
839
+ 'The Beast',
840
+ ENTRY.beast,
841
+ BOSS_SPELLS.beast,
842
+ undefined,
843
+ 'Three Blackhand Elites flee into the Furnace as you enter - then The Beast. When the Beast falls, Finkle Einhorn climbs out of the corpse.',
844
+ [{ creatureEntry: UBRS_BEAST.introEliteEntry, count: UBRS_BEAST.introEliteCount }],
845
+ ),
846
+ );
847
+
848
+ // Optional T0.5 Brazier of Beckoning, and it belongs HERE: Valthalak's focus is 45 yd from The
849
+ // Beast in The Furnace, while Drakkisath is 250 yd up — listing him last cost 477 yd.
850
+ {
851
+ const val = boss(
852
+ UBRS_VALTHALAK.encId,
853
+ 'Lord Valthalak',
854
+ UBRS_VALTHALAK.bossEntry,
855
+ [],
856
+ [
857
+ {
858
+ kind: 'objectGate',
859
+ goEntry: UBRS_VALTHALAK.goEntry,
860
+ requiredItem: UBRS_VALTHALAK.requiredItem,
861
+ setsFlag: UBRS_FLAGS.valthalak,
862
+ once: true,
863
+ },
864
+ { kind: 'requiresFlag', flag: UBRS_FLAGS.valthalak },
865
+ ],
866
+ "The Brazier of Beckoning at Lord Valthalak's focus summons the spectral warlord (optional T0.5).",
867
+ );
868
+ val.origin = { ...UBRS_VALTHALAK.spawn };
869
+ val.optional = true; // Summon (T0.5 Brazier); isComplete ignores optional.
870
+ out.push(val);
871
+ }
872
+
873
+ // --- Drakkisath finale (after Solakar) ---
874
+ out.push(
875
+ boss(
876
+ 'general-drakkisath',
877
+ 'General Drakkisath',
878
+ ENTRY.drakkisath,
879
+ BOSS_SPELLS.drakkisath,
880
+ [{ kind: 'setsFlag', flag: UBRS_FLAGS.drakkisathDone }],
881
+ 'General Drakkisath commands the chromatic elite of the upper citadel. Two Chromatic Elite Guards stand with him.',
882
+ [{ creatureEntry: ENTRY.chromaticEliteGuard, count: UBRS_CHROMATIC_GUARD_COUNT }],
883
+ ),
884
+ );
885
+
886
+ return out;
887
+ }
888
+
889
+ // TYPE_ROOM_EVENT: sort Summoner/Veteran packs within 10 yd of each of the seven room runes, pull
890
+ // them before Emberseer, and stamp a per-room setsFlag. Cite: instance_blackrock_spire.cpp:339-386.
891
+ export function stampUbrsRoomEvent(encs: EncounterDef[]): EncounterDef[] {
892
+ const gate0 = encs.findIndex((e) => e.id === 'pyroguard-emberseer');
893
+ if (gate0 < 0) return encs;
894
+ const members = clusterMemberByGuid(229);
895
+ const runes = dungeonGameObjectsForMap(229).filter((g) =>
896
+ UBRS_ROOM_RUNES.includes(g.entry),
897
+ );
898
+ if (!runes.length) return encs;
899
+
900
+ const pools = loadPoolGuidCandidates(229);
901
+ // cpp:351 is GetDistance(pRune) < 10.0f — 3-D. The 2-D hypot this used to run has a measured
902
+ // class size of ZERO here, but the source's own metric is the one to port.
903
+ const isRoomMob = (
904
+ m: { entry: number; x: number; y: number; z?: number },
905
+ rune: { x: number; y: number; z?: number },
906
+ ) =>
907
+ (m.entry === ENTRY.blackhandSummoner || m.entry === ENTRY.blackhandVeteran)
908
+ && Math.hypot(m.x - rune.x, m.y - rune.y, (m.z ?? 0) - (rune.z ?? 0))
909
+ < UBRS_ROOM_EVENT_RADIUS_YD;
910
+
911
+ // Each room's door opens when THAT room's sorted list empties, so a room's mobs have to be ONE
912
+ // pull: 2 of 7 runes had theirs split across two packs, and those doors opened with a mob alive.
913
+ const runeOfGuid = new Map<number, number>();
914
+ for (let ri = 0; ri < runes.length; ri++) {
915
+ for (const [guid, m] of members) {
916
+ if (!runeOfGuid.has(guid) && isRoomMob(m, runes[ri]!)) runeOfGuid.set(guid, ri);
917
+ }
918
+ }
919
+ if (!runeOfGuid.size) return encs;
920
+
921
+ // Strip the room mobs out of every trash pull before Emberseer; the remainder keeps the
922
+ // clusterer's pack and its events. No body is added or dropped.
923
+ const perRune: { guids: number[]; base: EncounterDef | null }[] =
924
+ runes.map(() => ({ guids: [], base: null }));
925
+ const out: EncounterDef[] = [];
926
+ for (const e of encs) {
927
+ const guids = e.spawnGuids ?? [];
928
+ // Every trash pull, not just those before Emberseer: the clusterer's order is not route
929
+ // order, so a room's mobs can sit behind him and the extracted pull is re-placed below.
930
+ if (e.kind !== 'trash' || !guids.length) {
931
+ out.push(e);
932
+ continue;
933
+ }
934
+ const take = guids.filter((g) => runeOfGuid.has(g));
935
+ if (!take.length) {
936
+ out.push(e);
937
+ continue;
938
+ }
939
+ for (const g of take) {
940
+ const slot = perRune[runeOfGuid.get(g)!]!;
941
+ slot.guids.push(g);
942
+ slot.base ??= e;
943
+ }
944
+ const rest = guids.filter((g) => !runeOfGuid.has(g));
945
+ if (rest.length) {
946
+ out.push(repackFromGuids(e, rest, members, {
947
+ events: e.events ? [...e.events] : undefined,
948
+ pools,
949
+ }));
950
+ }
951
+ }
952
+
953
+ // One flagged pull per rune, seeded on the rune's own storey.
954
+ const roomFlags: string[] = [];
955
+ const runePulls: EncounterDef[] = [];
956
+ for (let ri = 0; ri < runes.length; ri++) {
957
+ const slot = perRune[ri]!;
958
+ if (!slot.guids.length || !slot.base) continue;
959
+ const rune = runes[ri]!;
960
+ const flag = ubrsRuneRoomFlag(rune.entry);
961
+ roomFlags.push(flag);
962
+ runePulls.push(repackFromGuids(slot.base, slot.guids, members, {
963
+ id: `ubrs-rune-room-${rune.entry}`,
964
+ name: `${rune.name ?? 'Room'} guards`,
965
+ events: [{ kind: 'setsFlag', flag }],
966
+ pools,
967
+ }));
968
+ }
969
+ if (!runePulls.length) return encs;
970
+
971
+ const gIdx = out.findIndex((e) => e.id === 'pyroguard-emberseer');
972
+ if (gIdx < 0) return encs;
973
+ out.splice(gIdx, 0, ...runePulls);
974
+
975
+ // The aggregate TYPE_ROOM_EVENT DONE flag is NOT stamped on a pack: on the last room pack in route
976
+ // order it granted "all rooms clear" alone. The live floor derives it from all seven room flags.
977
+
978
+ // Emberseer requires every room flag + aggregate (all must clear). Re-find him: the splice
979
+ // above inserted the rune pulls ahead of him, so gIdx is stale by runePulls.length.
980
+ const embIdx = out.findIndex((e) => e.id === 'pyroguard-emberseer');
981
+ if (roomFlags.length && embIdx >= 0) {
982
+ const emb = out[embIdx]!;
983
+ const events = (emb.events ?? []).filter(
984
+ (ev) =>
985
+ !(
986
+ ev.kind === 'requiresFlag'
987
+ && (ev.flag === UBRS_FLAGS.runeRooms || ev.flag.startsWith('ubrs-rune-room:'))
988
+ ),
989
+ );
990
+ for (const flag of roomFlags) {
991
+ events.push({ kind: 'requiresFlag', flag });
992
+ }
993
+ // NOT the aggregate. Requiring `ubrs-rune-rooms` while nothing in the graph SETS it is an
994
+ // unsourced gate the repo's own audit counts as a soft-lock. The seven per-room flags are it.
995
+ out[embIdx] = { ...emb, events };
996
+ }
997
+
998
+ return out;
999
+ }
1000
+
1001
+ /** True when all stamped room-rune flags (and aggregate) are present. */
1002
+ export function ubrsRoomEventDone(flags: readonly string[]): boolean {
1003
+ return flags.includes(UBRS_FLAGS.runeRooms);
1004
+ }
1005
+
1006
+ // One drawable state pad for the TYPE_ROOM_EVENT mechanic: `lit` is the live rune, which stands
1007
+ // until the last mob within 10 yd dies. Seven pads the run tracked as flags and never drew.
1008
+ export type UbrsRoomPad = {
1009
+ goEntry: number;
1010
+ guid: number;
1011
+ name: string;
1012
+ x: number;
1013
+ y: number;
1014
+ z?: number;
1015
+ displayId?: number;
1016
+ /** Rune still burning / door still shut. */
1017
+ lit: boolean;
1018
+ /** `rune` for the seven room runes, `door` for Emberseer In. */
1019
+ kind: 'rune' | 'door';
1020
+ /** Room ordinal 1-7 from the GO name ("Room 3 Rune"), 0 for the door. */
1021
+ room: number;
1022
+ };
1023
+
1024
+ /** Emberseer In — the door the seven runes open. Cite: blackrock_spire.h:37. */
1025
+ export const UBRS_EMBERSEER_IN_GO = 175244;
1026
+ /** Emberseer Out — TYPE_EMBERSEER DONE. Cite: blackrock_spire.h:39; cpp:232-235. */
1027
+ export const UBRS_EMBERSEER_OUT_GO = 175153;
1028
+ /** Gyth exit — TYPE_STADIUM DONE. Cite: blackrock_spire.h:43; cpp:143-146,265. */
1029
+ export const UBRS_GYTH_EXIT_GO = 175186;
1030
+
1031
+ /** Progress doors that start shut. Combat toggles (175705/164726/175185) stay off this list. */
1032
+ export const UBRS_PROGRESS_DOORS: readonly number[] = [
1033
+ UBRS_SEAL_GATE.goEntry,
1034
+ UBRS_EMBERSEER_IN_GO,
1035
+ UBRS_EMBERSEER_OUT_GO,
1036
+ UBRS_GYTH_EXIT_GO,
1037
+ ];
1038
+
1039
+ // ScriptDev door open-state from run flags. Cite: instance_blackrock_spire.cpp:127-146 OnObjectCreate,
1040
+ // :205-265 SetData.
1041
+ export function ubrsGoOpen(goEntry: number, flags: readonly string[]): boolean {
1042
+ if (goEntry === UBRS_SEAL_GATE.goEntry) return flags.includes(UBRS_FLAGS.upperDoor);
1043
+ if (goEntry === UBRS_EMBERSEER_IN_GO) return flags.includes(UBRS_FLAGS.runeRooms);
1044
+ if (goEntry === UBRS_EMBERSEER_OUT_GO) return flags.includes(UBRS_FLAGS.emberseerDone);
1045
+ if (goEntry === UBRS_GYTH_EXIT_GO) return flags.includes(UBRS_FLAGS.stadiumDone);
1046
+ return false;
1047
+ }
1048
+
1049
+ /** Closed progress-door spawns for navmesh stamping. */
1050
+ export function ubrsClosedDoorSpawns(flags: readonly string[]): {
1051
+ x: number; y: number; z: number; o: number;
1052
+ }[] {
1053
+ const out: { x: number; y: number; z: number; o: number }[] = [];
1054
+ for (const go of dungeonGameObjectsForMap(229)) {
1055
+ if (!UBRS_PROGRESS_DOORS.includes(go.entry)) continue;
1056
+ if (ubrsGoOpen(go.entry, flags)) continue;
1057
+ out.push({ x: go.x, y: go.y, z: go.z, o: go.o });
1058
+ }
1059
+ return out;
1060
+ }
1061
+
1062
+ // The seven room runes plus Emberseer In, with live lit/out state from the run flags. Positions and display
1063
+ // ids come from the gameobject bake; nothing here is authored.
1064
+ export function ubrsRoomPads(flags: readonly string[]): UbrsRoomPad[] {
1065
+ const out: UbrsRoomPad[] = [];
1066
+ for (const go of dungeonGameObjectsForMap(229)) {
1067
+ const isRune = UBRS_ROOM_RUNES.includes(go.entry);
1068
+ const isDoor = go.entry === UBRS_EMBERSEER_IN_GO;
1069
+ if (!isRune && !isDoor) continue;
1070
+ const lit = isRune
1071
+ ? !flags.includes(ubrsRuneRoomFlag(go.entry))
1072
+ : !flags.includes(UBRS_FLAGS.runeRooms);
1073
+ const pad: UbrsRoomPad = {
1074
+ goEntry: go.entry,
1075
+ guid: go.guid,
1076
+ name: go.name,
1077
+ x: go.x,
1078
+ y: go.y,
1079
+ lit,
1080
+ kind: isRune ? 'rune' : 'door',
1081
+ room: isRune ? Number(/Room (\d)/.exec(go.name)?.[1] ?? 0) : 0,
1082
+ };
1083
+ if (go.z != null && Number.isFinite(go.z)) pad.z = go.z;
1084
+ if (go.displayId > 0) pad.displayId = go.displayId;
1085
+ out.push(pad);
1086
+ }
1087
+ // Runes by room ordinal, door last.
1088
+ out.sort((a, b) => (a.kind === b.kind ? a.room - b.room : a.kind === 'rune' ? -1 : 1));
1089
+ return out;
1090
+ }
1091
+
1092
+ /** How many of the seven rooms are clear. Cite: cpp:369-385 uiNotEmptyRoomsCount. */
1093
+ export function ubrsRoomsClearCount(flags: readonly string[]): number {
1094
+ return UBRS_ROOM_RUNES.filter((e) => flags.includes(ubrsRuneRoomFlag(e))).length;
1095
+ }
1096
+
1097
+ // Standing on a Rookery Egg hatches it: GO 175124 is a TRAP, so this is the object doing its job.
1098
+ // 1.5 yd because the 271 baked eggs sit a mean 1.77 yd apart, so one step takes one egg.
1099
+ export const UBRS_EGG_STEP_YD = 1.5;
1100
+
1101
+ /** How far around a party a run draws individual eggs. 271 pins at once is a texture. */
1102
+ export const UBRS_EGG_DRAW_YD = 45;
1103
+
1104
+ /** Extra step cost the router pays to cross an egg cell. Never a block: the eggs cover the floor. */
1105
+ export const UBRS_EGG_AVOID_MUL = 6;
1106
+ /** Radius the avoid stamp paints per egg. */
1107
+ export const UBRS_EGG_AVOID_YD = 1.5;
1108
+
1109
+ /** Every baked Rookery Egg on map 229, world coords (for the nav avoid stamp). */
1110
+ export function ubrsRookeryEggPoints(): { x: number; y: number; z?: number }[] {
1111
+ return dungeonGameObjectsForMap(229)
1112
+ .filter((g) => g.entry === UBRS_ROOKERY_EGGS.eggGoEntry)
1113
+ .map((g) => (g.z != null && Number.isFinite(g.z)
1114
+ ? { x: g.x, y: g.y, z: g.z }
1115
+ : { x: g.x, y: g.y }));
1116
+ }
1117
+
1118
+ export type UbrsEggPad = {
1119
+ guid: number;
1120
+ goEntry: number;
1121
+ x: number;
1122
+ y: number;
1123
+ z?: number;
1124
+ displayId?: number;
1125
+ /** Not yet hatched. */
1126
+ intact: boolean;
1127
+ };
1128
+
1129
+ // One storey. Cite: probe-aggro-cross-floor.mjs:20 — "One storey of Blackrock Spire is ~14 yd; 8 clears a
1130
+ // ramp but not a floor."
1131
+ export const UBRS_EGG_SAME_FLOOR_DZ = 8;
1132
+
1133
+ // Eggs near a point, hatched or not, culled by distance. z IS PART OF "NEAR": the eggs' xy box
1134
+ // covers most of the dungeon, so a 2-D test reported an egg underfoot almost anywhere.
1135
+ export function ubrsRookeryEggPads(
1136
+ hatched: (guid: number) => boolean,
1137
+ near: { x: number; y: number; z?: number },
1138
+ radiusYd = UBRS_EGG_DRAW_YD,
1139
+ sameFloorDz = UBRS_EGG_SAME_FLOOR_DZ,
1140
+ ): UbrsEggPad[] {
1141
+ const out: UbrsEggPad[] = [];
1142
+ const nz = near.z;
1143
+ const haveZ = nz != null && Number.isFinite(nz);
1144
+ for (const g of dungeonGameObjectsForMap(229)) {
1145
+ if (g.entry !== UBRS_ROOKERY_EGGS.eggGoEntry) continue;
1146
+ if (Math.hypot(g.x - near.x, g.y - near.y) > radiusYd) continue;
1147
+ // No party z (unstamped column) leaves the 2-D answer — HEIGHT_UNSTAMPED rule — but an egg
1148
+ // with no z of its own can never claim to be on your floor.
1149
+ if (haveZ) {
1150
+ if (g.z == null || !Number.isFinite(g.z)) continue;
1151
+ if (Math.abs(g.z - nz!) > sameFloorDz) continue;
1152
+ }
1153
+ const pad: UbrsEggPad = {
1154
+ guid: g.guid,
1155
+ goEntry: g.entry,
1156
+ x: g.x,
1157
+ y: g.y,
1158
+ intact: !hatched(g.guid),
1159
+ };
1160
+ if (g.z != null && Number.isFinite(g.z)) pad.z = g.z;
1161
+ if (g.displayId > 0) pad.displayId = g.displayId;
1162
+ out.push(pad);
1163
+ }
1164
+ return out;
1165
+ }
1166
+
1167
+ // Intact eggs the party is standing on. Needs the party's z — without it this is a 2-D test over an
1168
+ // xy box covering most of the dungeon, and 2 yd is all a step deserves when a floor is 14 yd.
1169
+ export const UBRS_EGG_STEP_DZ = 2;
1170
+ export function ubrsEggsUnderfoot(
1171
+ hatched: (guid: number) => boolean,
1172
+ party: { x: number; y: number; z?: number },
1173
+ ): UbrsEggPad[] {
1174
+ if (party.z == null || !Number.isFinite(party.z)) return [];
1175
+ return ubrsRookeryEggPads(hatched, party, UBRS_EGG_STEP_YD, UBRS_EGG_STEP_DZ);
1176
+ }
1177
+
1178
+ // Nearest unused Rookery Egg within `rangeYd` of `from` (3-D). Cite: cpp:946-970
1179
+ // GetGameObjectListWithEntryInGrid 20 yd, sort by distance, first without GO_FLAG_IN_USE.
1180
+ export function ubrsNearestFreeEgg(
1181
+ hatched: (guid: number) => boolean,
1182
+ from: { x: number; y: number; z?: number },
1183
+ rangeYd: number = UBRS_ROOKERY_EGGS.searchRangeYd,
1184
+ ): UbrsEggPad | null {
1185
+ let best: UbrsEggPad | null = null;
1186
+ let bestD = rangeYd;
1187
+ const fz = from.z;
1188
+ const haveZ = fz != null && Number.isFinite(fz);
1189
+ for (const g of dungeonGameObjectsForMap(229)) {
1190
+ if (g.entry !== UBRS_ROOKERY_EGGS.eggGoEntry) continue;
1191
+ if (hatched(g.guid)) continue;
1192
+ if (g.z == null || !Number.isFinite(g.z)) continue;
1193
+ if (!haveZ) continue;
1194
+ const d = Math.hypot(g.x - from.x, g.y - from.y, g.z - fz!);
1195
+ if (!(d < bestD)) continue;
1196
+ bestD = d;
1197
+ const pad: UbrsEggPad = {
1198
+ guid: g.guid, goEntry: g.entry, x: g.x, y: g.y, z: g.z, intact: true,
1199
+ };
1200
+ if (g.displayId > 0) pad.displayId = g.displayId;
1201
+ best = pad;
1202
+ }
1203
+ return best;
1204
+ }
1205
+
1206
+ function buildEncounters(): EncounterDef[] {
1207
+ // Hand spine = bosses + event-gated packs (mono trashFromCensus is empty).
1208
+ const spine = buildHandSpine();
1209
+ const encs = buildClusterEncounters({
1210
+ mapId: 229,
1211
+ spine,
1212
+ entrance: entranceForInstance('ubrs'),
1213
+ extraStrip: [
1214
+ ...UBRS_EXCLUDED_ENTRIES,
1215
+ ...UBRS_SUMMON_ONLY_ENTRIES,
1216
+ ENTRY.valthalak,
1217
+ // The seven Incarcerators are the Emberseer RITUAL, and this file has said so since it was
1218
+ // written. Unstripped, the cluster builder packed them into three ordinary trash pulls.
1219
+ ENTRY.blackhandIncarcerator,
1220
+ ],
1221
+ includePack: wingFilterByNearestBoss(229, 'ubrs'),
1222
+ });
1223
+ // Cite: instance_blackrock_spire.cpp:195-196,339-386 — 7-room sort + per-room flags.
1224
+ return stampUbrsRoomEvent(encs);
1225
+ }
1226
+
1227
+
1228
+ export const UBRS: InstanceDef = {
1229
+ id: 'ubrs',
1230
+ mapId: 229,
1231
+ wing: 'ubrs',
1232
+ name: 'Upper Blackrock Spire',
1233
+ portalZone: 'burningsteppes',
1234
+ // areatrigger_teleport 1468, Blackrock Spire - Entering (level 45). The AT's own fromZone is
1235
+ // 'searinggorge', so the portalZone match never found it and canEnter fell back to def.minLevel.
1236
+ entranceTriggerId: 1468,
1237
+ // UBRS is a TEN-man in 1.12 (post-1.10 cut), not a 5-man: instance_template 229
1238
+ // maxPlayers = 10. Cite: mangos.sql:2559; operator-confirmed 2026-08-08.
1239
+ maxPlayers: 10,
1240
+ minLevel: 45,
1241
+ levelRange: [55, 62],
1242
+ lockoutMs: 0,
1243
+ description: '',
1244
+ quests: [...UBRS_QUESTS],
1245
+ encounters: buildEncounters(),
1246
+ };
1247
+
1248
+ // Sum of pure static trash counts per creature entry (primary + pack; bosses/events excluded).
1249
+ // Incarcerators and Chromatic Elite Guards live on boss packs - not counted here.
1250
+ export function ubrsPureStaticTrashCounts(): Map<number, number> {
1251
+ const map = new Map<number, number>();
1252
+ const add = (entry: number, n: number) => map.set(entry, (map.get(entry) ?? 0) + n);
1253
+ for (const enc of UBRS.encounters) {
1254
+ if (enc.kind !== 'trash') continue;
1255
+ add(enc.creatureEntry, 1);
1256
+ for (const p of enc.pack ?? []) add(p.creatureEntry, p.count);
1257
+ }
1258
+ return map;
1259
+ }
1260
+
1261
+ /** All kill supply (trash + boss singles + pack + waves + onDeathSummon + hpThreshold). */
1262
+ export function ubrsKillSupply(): Map<number, number> {
1263
+ const map = new Map<number, number>();
1264
+ const add = (entry: number, n: number) => map.set(entry, (map.get(entry) ?? 0) + n);
1265
+ for (const enc of UBRS.encounters) {
1266
+ // Wave encounters: supply is waves only (primary is identity for summon-only finale)
1267
+ const waveEv = (enc.events ?? []).find((ev) => ev.kind === 'waves');
1268
+ if (waveEv && waveEv.kind === 'waves') {
1269
+ for (const w of waveEv.waves) {
1270
+ for (const p of w.pack) add(p.creatureEntry, p.count);
1271
+ }
1272
+ } else {
1273
+ add(enc.creatureEntry, 1);
1274
+ for (const p of enc.pack ?? []) add(p.creatureEntry, p.count);
1275
+ }
1276
+ for (const ev of enc.events ?? []) {
1277
+ if (ev.kind === 'onDeathSummon') add(ev.creatureEntry, 1);
1278
+ if (ev.kind === 'hpThreshold' && ev.spawn) {
1279
+ for (const p of ev.spawn) add(p.creatureEntry, p.count);
1280
+ }
1281
+ }
1282
+ }
1283
+ // Rookery egg whelps are controller-scheduled (not authored wave rows); not kill-supply.
1284
+ // Finkle 10776 is friendly post-death flavor — not kill-supply.
1285
+ return map;
1286
+ }