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,1013 @@
1
+ // Temple of Ahn'Qiraj — the ScriptDevAI IR port of seven of the nine encounters, read whole from
2
+ // kalimdor/temple_of_ahnqiraj. Ouro is ported; C'Thun stays absent rather than half-registered.
3
+
4
+ import type { ScriptDevAction, ScriptDevIR, ScriptDevReceiveAiEvent, ScriptDevTimer } from './types.ts';
5
+ import { AI_EVENT, INSTANCE_DATA } from './types.ts';
6
+ import { CAST_FLAG } from '../creature/creatureAi.ts';
7
+
8
+ // temple_of_ahnqiraj.h:10-21
9
+ const TYPE = { SKERAM: 0, BUG_TRIO: 1, SARTURA: 2, FANKRISS: 3, VISCIDUS: 4, HUHURAN: 5, TWINS: 6, OURO: 7, CTHUN: 8 } as const;
10
+ const NPC = {
11
+ SKERAM: 15263, SARTURA: 15516, FANKRISS: 15510, HUHURAN: 15509,
12
+ KRI: 15511, VEM: 15544, YAUJ: 15543, VEKNILASH: 15275, VEKLOR: 15276, VISCIDUS: 15299,
13
+ OURO: 15517, CTHUN: 15727,
14
+ SPAWN_FANKRISS: 15630, VEKNISS_HATCHLING: 15962,
15
+ GLOB_OF_VISCIDUS: 15667, FLESH_TENTACLE: 15802,
16
+ } as const;
17
+
18
+ /** temple_of_ahnqiraj.h:43 NPC_FLESH_TENTACLE; boss_cthun.cpp:91 MAX_FLESH_TENTACLES. */
19
+ const MAX_FLESH_TENTACLES = 2;
20
+ // boss_cthun.cpp:96-97 cthunLocations[0] — the first Flesh Tentacle spot. Both stand within a few
21
+ // yards of each other, so one anchor is the pair's site.
22
+ const CTHUN_FLESH_TENTACLE_XY = [-8571.472, 1990.2048] as const;
23
+
24
+ /** boss_viscidus.cpp:98 PHASE_EXPLODED. */
25
+ const VISCIDUS_PHASE_EXPLODED = 4;
26
+ // boss_viscidus.cpp:63 — "summons npc 15667 using spells from 25865 to 25884", so twenty globs, and
27
+ // :513 takes 5 % each: 20 x 5 = the whole bar.
28
+ const VISCIDUS_GLOB_COUNT = 20;
29
+ const VISCIDUS_GLOB_SHRINK_PCT = 5;
30
+
31
+ /** Twin Emperors shared-HP spells. Cite: boss_twinemperors.cpp:51-56. */
32
+ const SPELL_TWIN = {
33
+ TELEPORT: 799,
34
+ HEAL_BROTHER: 7393,
35
+ EMPATHY: 1177,
36
+ SUICIDE: 26627,
37
+ TELEPORT_VISUAL: 26638,
38
+ MUTATE_BUG: 802,
39
+ EXPLODE_BUG: 804,
40
+ FRENZY: 27897,
41
+ } as const;
42
+
43
+ const t = (
44
+ id: string, spellId: number, iMin: number, iMax: number, rMin: number, rMax: number,
45
+ target: ScriptDevTimer['target'], cite: string, extra: Partial<ScriptDevTimer> = {},
46
+ ): ScriptDevTimer => ({
47
+ id, spellId, initialMinMs: iMin, initialMaxMs: iMax, repeatMinMs: rMin, repeatMaxMs: rMax,
48
+ target, cite, ...extra,
49
+ });
50
+
51
+ const lifecycleFor = (field: number, file: string) => ({
52
+ onAggro: [{ kind: 'set_instance_data' as const, field, value: INSTANCE_DATA.IN_PROGRESS, cite: `${file} Aggro SetData(IN_PROGRESS)` }],
53
+ onDeath: [{ kind: 'set_instance_data' as const, field, value: INSTANCE_DATA.DONE, cite: `${file} JustDied SetData(DONE)` }],
54
+ onEvade: [{ kind: 'set_instance_data' as const, field, value: INSTANCE_DATA.FAIL, cite: `${file} JustReachedHome SetData(FAIL)` }],
55
+ });
56
+
57
+ /** Side-store for m_uiBugTrioDeathCount. Cite: temple_of_ahnqiraj.h:10 MAX_ENCOUNTER=10; cpp:240. */
58
+ const BUG_TRIO_CONSUME_KEY = 10;
59
+ const EMOTE_CONSUMED = -1531048;
60
+
61
+ function trioConsume(deathSpell: number, others: number[]): {
62
+ onReset: ScriptDevAction[];
63
+ onPreventedDeath: ScriptDevAction[];
64
+ onEvade: ScriptDevAction[];
65
+ receiveAiEvents: ScriptDevReceiveAiEvent[];
66
+ } {
67
+ const life = lifecycleFor(TYPE.BUG_TRIO, 'boss_bug_trio.cpp');
68
+ return {
69
+ onReset: [
70
+ { kind: 'set_death_prevention', enabled: true, cite: 'boss_bug_trio.cpp:97 SetDeathPrevention(true)' },
71
+ ],
72
+ onPreventedDeath: [
73
+ {
74
+ kind: 'set_instance_data',
75
+ field: BUG_TRIO_CONSUME_KEY,
76
+ value: 1,
77
+ increment: true,
78
+ cite: 'temple_of_ahnqiraj.cpp:240 ++m_uiBugTrioDeathCount',
79
+ },
80
+ { kind: 'yell', textId: EMOTE_CONSUMED, cite: 'boss_bug_trio.cpp:142 EMOTE_CONSUMED' },
81
+ { kind: 'cast_self', spellId: deathSpell, cite: 'boss_bug_trio.cpp:144,149-152 DoSpecialAbility' },
82
+ { kind: 'force_despawn', delayMs: 3000, cite: 'boss_bug_trio.cpp:146 ForcedDespawn(3000)' },
83
+ ...others.map((entry) => ({
84
+ kind: 'send_ai_event' as const,
85
+ eventType: AI_EVENT.CUSTOM_A,
86
+ receiver: 'creature_entry' as const,
87
+ creatureEntry: entry,
88
+ cite: 'temple_of_ahnqiraj.cpp:243-251 SendAIEvent CUSTOM_A to living trio',
89
+ })),
90
+ ],
91
+ onEvade: [
92
+ ...life.onEvade,
93
+ { kind: 'set_instance_data', field: BUG_TRIO_CONSUME_KEY, value: 0, cite: 'temple_of_ahnqiraj.cpp:256-278 FAIL resets m_uiBugTrioDeathCount' },
94
+ ],
95
+ receiveAiEvents: [{
96
+ eventType: AI_EVENT.CUSTOM_A,
97
+ actions: [
98
+ { kind: 'set_combat_movement', enabled: false, cite: 'boss_bug_trio.cpp:182 SetCombatMovement(false)' },
99
+ {
100
+ kind: 'set_death_prevention',
101
+ enabled: false,
102
+ gate: { field: BUG_TRIO_CONSUME_KEY, equals: 2, cite: 'boss_bug_trio.cpp:178 miscValue == 2' },
103
+ cite: 'boss_bug_trio.cpp:178 SetDeathPrevention(false) at the second consume',
104
+ },
105
+ ],
106
+ cite: 'boss_bug_trio.cpp:174-188 ReceiveAIEvent CUSTOM_A',
107
+ }],
108
+ };
109
+ }
110
+
111
+ export const BOSS_SKERAM: ScriptDevIR = {
112
+ name: 'boss_skeram',
113
+ boundCreatures: [NPC.SKERAM],
114
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_skeram.cpp',
115
+ spellIds: [26192, 26194, 785, 747],
116
+ timers: [
117
+ t('arcane_explosion', 26192, 6000, 12_000, 8000, 18_000, 'self', 'boss_skeram.cpp ARCANE_EXPLOSION 6-12s then 8-18s'),
118
+ // True Fulfilment mind-controls the NEAREST non-tank player — the reason the raid
119
+ // spreads. NEAREST_BY with skip-tank, not a plain random.
120
+ t('true_fulfilment', 785, 15_000, 15_000, 20_000, 30_000, 'hostile_random_not_top_player', 'boss_skeram.cpp TRUE_FULFILLMENT 15s then 20-30s, NEAREST_BY skipTank', { select: { playerOnly: true, skipTopThreat: true } }),
121
+ // Anti-kite punish, not a rotation spell: SKERAM_EARTH_SHOCK polls, and a victim the boss can
122
+ // reach in melee sets m_rangeCheckState = -1 so nothing is cast. Only two consecutive
123
+ // out-of-melee polls (m_rangeCheckState > 1) fire it, and the action then re-arms at 2500 ms.
124
+ // Same shape as Ragnaros's Magma Blast (moltenCore.ts:464).
125
+ t('earth_shock', 26194, 1200, 1200, 2500, 2500, 'victim', 'boss_skeram.cpp:75 AddCombatAction 1200; SKERAM_EARTH_SHOCK CanReachWithMeleeAttack victim → skip, else cast then timer 2500', { requireVictimNotInMelee: true }),
126
+ ],
127
+ phases: [
128
+ {
129
+ phase: 1,
130
+ hpBelowPct: 75,
131
+ retainPhase: true,
132
+ actions: [{ kind: 'cast_self', spellId: 747, cite: 'boss_skeram.cpp:254 DoCastSpellIfCan SPELL_SUMMON_IMAGES 747 at 75%' }],
133
+ cite: 'boss_skeram.cpp:250-260 m_hpCheck 75 then -= 25',
134
+ },
135
+ {
136
+ phase: 2,
137
+ hpBelowPct: 50,
138
+ retainPhase: true,
139
+ actions: [{ kind: 'cast_self', spellId: 747, cite: 'boss_skeram.cpp:254 DoCastSpellIfCan SPELL_SUMMON_IMAGES 747 at 50%' }],
140
+ cite: 'boss_skeram.cpp:250-260 m_hpCheck 50 then -= 25',
141
+ },
142
+ {
143
+ phase: 3,
144
+ hpBelowPct: 25,
145
+ retainPhase: true,
146
+ actions: [{ kind: 'cast_self', spellId: 747, cite: 'boss_skeram.cpp:254 DoCastSpellIfCan SPELL_SUMMON_IMAGES 747 at 25%' }],
147
+ cite: 'boss_skeram.cpp:250-260 m_hpCheck 25 then -= 25',
148
+ },
149
+ ],
150
+ lifecycle: {
151
+ ...lifecycleFor(TYPE.SKERAM, 'boss_skeram.cpp'),
152
+ justSummoned: [
153
+ // An image is a SHARE of him, not an add: its max health is a fraction of his and its current
154
+ // health is his own percent, so the copies made at 25 % are half his bar each.
155
+ {
156
+ kind: 'mirror_summoner_health',
157
+ bands: [
158
+ { belowPct: 25, fracOfMax: 0.50 },
159
+ { belowPct: 50, fracOfMax: 0.20 },
160
+ { belowPct: 101, fracOfMax: 0.10 },
161
+ ],
162
+ cite: 'boss_skeram.cpp:328-340 InitializeImages passes GetHealthPercent() as basepoints; :342-364 InitializeImage 0.50 below 25, 0.20 below 50, else 0.10, then SetHealthPercent',
163
+ },
164
+ // The C++ picks a RANDOM target for the image, not its summoner — attack_summoner pointed the
165
+ // copies at Skeram himself.
166
+ {
167
+ kind: 'attack_random',
168
+ cite: 'boss_skeram.cpp:155-160 JustSummoned SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0) then summoned->AI()->AttackStart(target)',
169
+ },
170
+ ],
171
+ },
172
+ cites: [
173
+ 'boss_skeram.cpp:25-300 whole file',
174
+ 'boss_skeram.cpp:250-260 SPELL_SUMMON_IMAGES 747 at 75/50/25 % NPC 15263',
175
+ 'boss_skeram.cpp:328-364 InitializeImages 794 / InitializeImage 3730 give each image a fraction of his max health and his own health percent, via mirror_summoner_health',
176
+ 'boss_skeram.cpp:65,89,109-153,169-200 m_isImage: the images share his ScriptName and differ by having a spawner. The teleport choreography (SPELL_TELEPORT_1/2/3 + TeleportImage) is a residual - no in-fight teleport verb here',
177
+ ],
178
+ };
179
+
180
+ export const BOSS_SARTURA: ScriptDevIR = {
181
+ name: 'boss_sartura',
182
+ boundCreatures: [NPC.SARTURA],
183
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_sartura.cpp',
184
+ spellIds: [26083, 25174, 27680, 8269],
185
+ timers: [
186
+ t('whirlwind', 26083, 10_000, 20_000, 20_000, 25_000, 'self', 'boss_sartura.cpp WHIRLWIND 10-20s then 20-25s'),
187
+ t('sundering_cleave', 25174, 2000, 5000, 2000, 5000, 'victim', 'boss_sartura.cpp SUNDERING_CLEAVE 2-5s'),
188
+ // A ten-minute hard berserk. It is the fight's clock, not chrome.
189
+ t('berserk', 27680, 600_000, 600_000, 600_000, 600_000, 'self', 'boss_sartura.cpp BERSERK 10*MINUTE'),
190
+ ],
191
+ phases: [
192
+ {
193
+ phase: 1,
194
+ hpBelowPct: 25,
195
+ actions: [
196
+ { kind: 'cast_self', spellId: 8269, cite: 'boss_sartura.cpp SARTURA_ENRAGE GetHealthPercent() <= 25.0f' },
197
+ { kind: 'flavor', text: 'enrages.', cite: 'boss_sartura.cpp timerless enrage at 25 %' },
198
+ ],
199
+ cite: 'boss_sartura.cpp AddTimerlessCombatAction(SARTURA_ENRAGE) at <=25 % HP',
200
+ },
201
+ ],
202
+ lifecycle: lifecycleFor(TYPE.SARTURA, 'boss_sartura.cpp'),
203
+ cites: ['boss_sartura.cpp:25-200 whole file'],
204
+ };
205
+
206
+ export const BOSS_FANKRISS: ScriptDevIR = {
207
+ name: 'boss_fankriss',
208
+ boundCreatures: [NPC.FANKRISS],
209
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_fankriss.cpp',
210
+ spellIds: [25646, 720, 731, 1121, 518, 25831, 25832, 26630, 26631, 26632],
211
+ timers: [
212
+ t('mortal_wound', 25646, 10_000, 15_000, 7000, 14_000, 'victim', 'boss_fankriss.cpp MORTAL_WOUND 10-15s then 7-14s'),
213
+ // Entangle teleports a NON-tank into one alcove — SELECT_FLAG_SKIP_TANK.
214
+ t('entangle', 720, 15_000, 20_000, 25_000, 55_000, 'hostile_random_not_top_player', 'boss_fankriss.cpp:160-180 urand 720/731/1121 PLAYER|SKIP_TANK', {
215
+ select: { playerOnly: true, skipTopThreat: true },
216
+ rotateSpellIds: [720, 731, 1121],
217
+ }),
218
+ t('summon_worm', 518, 30_000, 50_000, 22_000, 70_000, 'self', 'boss_fankriss.cpp:70,141-157 shuffle 518/25831/25832 waves urand(1,3)', {
219
+ rotateSpellIds: [518, 25831, 25832],
220
+ waveMinCount: 1,
221
+ waveMaxCount: 3,
222
+ intraWaveMinMs: 5000,
223
+ intraWaveMaxMs: 7000,
224
+ }),
225
+ ],
226
+ lifecycle: {
227
+ ...lifecycleFor(TYPE.FANKRISS, 'boss_fankriss.cpp'),
228
+ justSummoned: [
229
+ { kind: 'attack_random', creatureEntry: NPC.SPAWN_FANKRISS, cite: 'boss_fankriss.cpp:115-119 JustSummoned NPC_SPAWN_FANKRISS SelectAttackingTarget(RANDOM) AttackStart' },
230
+ ],
231
+ },
232
+ cites: [
233
+ 'boss_fankriss.cpp:25-213 whole file',
234
+ 'boss_fankriss.cpp:91-99,141-157 m_summonWormSpells 518/25831/25832 NPC 15630',
235
+ 'boss_fankriss.cpp:54-55,160-180,186-203 aEntangle 720/731/1121 -> 26630/26631/26632 NPC 15962',
236
+ ],
237
+ };
238
+
239
+ export const BOSS_HUHURAN: ScriptDevIR = {
240
+ name: 'boss_huhuran',
241
+ boundCreatures: [NPC.HUHURAN],
242
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_huhuran.cpp',
243
+ // Frenzy 26051 and Berserk 26068 pay through Poison Bolt 26052, resolved off the kit.
244
+ spellIds: [26051, 26068, 26053, 26180, 26050, 26052, 26233],
245
+ timers: [
246
+ t('acid_spit', 26050, 8000, 8000, 5000, 10_000, 'self', 'boss_huhuran.cpp SPIT 8s then 5-10s'),
247
+ // Frenzy triggers the Poison Bolt Volley that hits the 15 CLOSEST — the spread rule
248
+ // (PLAN §6). The volley itself rides the frenzy spell.
249
+ t('frenzy', 26051, 25_000, 35_000, 10_000, 20_000, 'self', 'boss_huhuran.cpp FRENZY 25-35s then 10-20s'),
250
+ t('noxious_poison', 26053, 10_000, 20_000, 12_000, 24_000, 'self', 'boss_huhuran.cpp NOXIOUS_POISON 10-20s then 12-24s'),
251
+ t('wyvern_sting', 26180, 35_000, 45_000, 25_000, 35_000, 'hostile_random', 'boss_huhuran.cpp WYVERN 35-45s then 25-35s'),
252
+ t('berserk', 26068, 300_000, 300_000, 300_000, 300_000, 'self', 'boss_huhuran.cpp BERSERK 5*MINUTE'),
253
+ ],
254
+ phases: [
255
+ {
256
+ // Below 30 % the berserk is forced early — the fight has a hard back half.
257
+ phase: 1,
258
+ hpBelowPct: 30,
259
+ actions: [
260
+ { kind: 'cast_self', spellId: 26068, cite: 'boss_huhuran.cpp HUHURAN_BERSERK_HP_CHECK GetHealthPercent() > 30.0f gate' },
261
+ { kind: 'flavor', text: 'goes berserk - poison volleys hit the fifteen closest.', cite: 'boss_huhuran.cpp berserk HP check at 30 %' },
262
+ ],
263
+ cite: 'boss_huhuran.cpp AddTimerlessCombatAction(HUHURAN_BERSERK_HP_CHECK) at <=30 % HP',
264
+ },
265
+ ],
266
+ lifecycle: lifecycleFor(TYPE.HUHURAN, 'boss_huhuran.cpp'),
267
+ cites: ['boss_huhuran.cpp:25-200 whole file'],
268
+ };
269
+
270
+ // The Bug Family, boss_bug_trio.cpp read whole. All three share TYPE_BUG_TRIO, and the second
271
+ // Consume drops death prevention on the survivor. Cite: boss_bug_trio.cpp:100-135.
272
+ export const BOSS_KRI: ScriptDevIR = {
273
+ name: 'boss_kri',
274
+ boundCreatures: [NPC.KRI],
275
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp',
276
+ spellIds: [26350, 25812, 3391, 26590],
277
+ timers: [
278
+ t('cleave', 26350, 4000, 8000, 5000, 12_000, 'victim', 'boss_bug_trio.cpp:204,226 CLEAVE 4-8s then 5-12s'),
279
+ // nullptr target = self-centred AoE volley, not a picked victim.
280
+ t('toxic_volley', 25812, 6000, 30_000, 15_000, 25_000, 'self', 'boss_bug_trio.cpp:205,232 TOXIC_VOLLEY 6-30s then 15-25s'),
281
+ t('thrash', 3391, 6000, 6000, 2000, 6000, 'self', 'boss_bug_trio.cpp:206,238 THRASH 6s then 2-6s'),
282
+ ],
283
+ lifecycle: (() => {
284
+ const life = lifecycleFor(TYPE.BUG_TRIO, 'boss_bug_trio.cpp');
285
+ const c = trioConsume(26590, [NPC.VEM, NPC.YAUJ]);
286
+ return {
287
+ ...life,
288
+ onReset: c.onReset,
289
+ onPreventedDeath: c.onPreventedDeath,
290
+ onEvade: c.onEvade,
291
+ onDeath: [
292
+ ...life.onDeath,
293
+ {
294
+ kind: 'cast_self' as const,
295
+ spellId: 26590,
296
+ cite: 'boss_bug_trio.cpp:128-136,149-152,214 JustDied DoSpecialAbility SPELL_SUMMON_CLOUD 26590',
297
+ },
298
+ ],
299
+ };
300
+ })(),
301
+ receiveAiEvents: trioConsume(26590, [NPC.VEM, NPC.YAUJ]).receiveAiEvents,
302
+ cites: [
303
+ 'boss_bug_trio.cpp:1-397 whole file',
304
+ 'boss_bug_trio.cpp:116-146,174-188 DummyConsume + second-consume unlocks the survivor',
305
+ 'boss_bug_trio.cpp:128-136,149-152,214 JustDied DoSpecialAbility SPELL_SUMMON_CLOUD 26590 NPC 15933',
306
+ ],
307
+ };
308
+
309
+ export const BOSS_VEM: ScriptDevIR = {
310
+ name: 'boss_vem',
311
+ boundCreatures: [NPC.VEM],
312
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp',
313
+ spellIds: [26561, 18670, 19128, 25790],
314
+ timers: [
315
+ t('charge', 26561, 15_000, 27_000, 8000, 16_000, 'hostile_random_not_in_melee', 'boss_bug_trio.cpp:257,280-282 CHARGE 15-27s then 8-16s, PLAYER|NOT_IN_MELEE_RANGE', { select: { playerOnly: true, notInMelee: true } }),
316
+ t('knock_away', 18670, 10_000, 20_000, 10_000, 20_000, 'victim', 'boss_bug_trio.cpp:258,288 KNOCK_AWAY 10-20s'),
317
+ t('knockdown', 19128, 5000, 8000, 15_000, 20_000, 'victim', 'boss_bug_trio.cpp:259,294 KNOCKDOWN 5-8s then 15-20s'),
318
+ ],
319
+ lifecycle: (() => {
320
+ const life = lifecycleFor(TYPE.BUG_TRIO, 'boss_bug_trio.cpp');
321
+ const c = trioConsume(25790, [NPC.KRI, NPC.YAUJ]);
322
+ return { ...life, onReset: c.onReset, onPreventedDeath: c.onPreventedDeath, onEvade: c.onEvade };
323
+ })(),
324
+ receiveAiEvents: trioConsume(25790, [NPC.KRI, NPC.YAUJ]).receiveAiEvents,
325
+ cites: [
326
+ 'boss_bug_trio.cpp:1-397 whole file',
327
+ 'boss_bug_trio.cpp:116-146,174-188,267 DummyConsume SPELL_VENGEANCE 25790',
328
+ 'creature_template 15544 also carries 26662, which the script never schedules - left unscheduled',
329
+ ],
330
+ };
331
+
332
+ export const BOSS_YAUJ: ScriptDevIR = {
333
+ name: 'boss_yauj',
334
+ boundCreatures: [NPC.YAUJ],
335
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_bug_trio.cpp',
336
+ spellIds: [25807, 26580, 3242, 25789, 25808],
337
+ timers: [
338
+ // GetHealthPercent() < 100.0f — the heal only fires once she has taken a hit.
339
+ t('heal', 25807, 20_000, 30_000, 10_000, 30_000, 'self', 'boss_bug_trio.cpp:314,349-351 HEAL 20-30s then 10-30s, only below 100 % HP', { hpPctMax: 99 }),
340
+ t('fear', 26580, 12_000, 24_000, 20_000, 20_000, 'self', 'boss_bug_trio.cpp:316,356-359 FEAR 12-24s then 20s', {
341
+ actions: [{ kind: 'reset_threat', cite: 'boss_bug_trio.cpp:356-358 CAST_OK SPELL_FEAR → DoResetThreat' }],
342
+ }),
343
+ t('ravage', 3242, 12_000, 12_000, 10_000, 15_000, 'victim', 'boss_bug_trio.cpp:317,366 RAVAGE 12s then 10-15s'),
344
+ // The pool is not "anything with a debuff": empty dispel/mechanic masks make the check pass only
345
+ // on a friendly in combat that is rooted, snared, frozen or crowd-controlled.
346
+ t('dispel', 25808, 10_000, 30_000, 10_000, 15_000, 'friendly_dispellable', 'boss_bug_trio.cpp:315,369-375 YAUJ_DISPEL 10-30s then 10-15s, DoFindFriendlyEligibleDispel(50.0f)', {
347
+ friendlyRadiusYd: 50,
348
+ }),
349
+ ],
350
+ lifecycle: (() => {
351
+ const life = lifecycleFor(TYPE.BUG_TRIO, 'boss_bug_trio.cpp');
352
+ const c = trioConsume(25789, [NPC.KRI, NPC.VEM]);
353
+ return { ...life, onReset: c.onReset, onPreventedDeath: c.onPreventedDeath, onEvade: c.onEvade };
354
+ })(),
355
+ receiveAiEvents: trioConsume(25789, [NPC.KRI, NPC.VEM]).receiveAiEvents,
356
+ cites: [
357
+ 'boss_bug_trio.cpp:1-397 whole file',
358
+ 'boss_bug_trio.cpp:315,369-375 DISPEL 25808 via friendly_dispellable; UnitAI.cpp:764-771 + GridNotifiers.h:915-930 empty-mask check = immobilized/snared/frozen/CC',
359
+ 'boss_bug_trio.cpp:356-358 CAST_OK SPELL_FEAR → DoResetThreat via reset_threat',
360
+ 'boss_bug_trio.cpp:116-146,174-188,325 DummyConsume SPELL_SUMMON_BROOD 25789 NPC 15621',
361
+ ],
362
+ };
363
+
364
+ // The Twin Emperors, boss_twinemperors.cpp read whole. `damageHealMirror` ports the percent link
365
+ // and the 60 yd Heal Brother LoS; teleport 799 swaps position and threat and stuns both.
366
+ export const BOSS_VEKNILASH: ScriptDevIR = {
367
+ name: 'boss_veknilash',
368
+ boundCreatures: [NPC.VEKNILASH],
369
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp',
370
+ // Double Attack 18943 pays through 18941; a trigger payload resolves off the kit.
371
+ spellIds: [26007, 26613, 27680, 18943, 802, SPELL_TWIN.HEAL_BROTHER, SPELL_TWIN.EMPATHY, SPELL_TWIN.SUICIDE, 18941],
372
+ timers: [
373
+ t('uppercut', 26007, 14_000, 29_000, 15_000, 30_000, 'hostile_random', 'boss_twinemperors.cpp:196,256-259 UPPERCUT 14-29s then 15-30s, SELECT_FLAG_IN_MELEE_RANGE', { select: { inMelee: true } }),
374
+ t('unbalancing_strike', 26613, 8000, 18_000, 8000, 20_000, 'victim', 'boss_twinemperors.cpp:197,265-266 UNBALANCING_STRIKE 8-18s then 8-20s'),
375
+ t('berserk', 27680, 900_000, 900_000, 900_000, 900_000, 'self', 'boss_twinemperors.cpp:88,247 BERSERK at 15*MINUTE, DisableCombatAction after'),
376
+ t('double_attack', 18943, 0, 0, 0, 0, 'self', 'boss_twinemperors.cpp:204 Reset DOUBLE_ATTACK TRIGGERED|AURA_NOT_PRESENT', { onReset: true }),
377
+ t('mutate_bug', 802, 7000, 14_000, 10_000, 17_000, 'self', 'boss_twinemperors.cpp:89,175-178,242 EMPEROR_BUG_ABILITY 7-14s then 10-17s SPELL_MUTATE_BUG', {
378
+ pollOnly: true,
379
+ actions: [{
380
+ kind: 'cast_on_script_targets',
381
+ spellId: 802,
382
+ cite: 'boss_twinemperors.cpp:242 DoCastSpellIfCan(nullptr, SPELL_MUTATE_BUG); spell_script_target 15316/15317',
383
+ }],
384
+ }),
385
+ ],
386
+ damageHealMirror: {
387
+ partnerEntry: NPC.VEKLOR,
388
+ empathySpellId: SPELL_TWIN.EMPATHY,
389
+ suicideSpellId: SPELL_TWIN.SUICIDE,
390
+ healBrotherSpellId: SPELL_TWIN.HEAL_BROTHER,
391
+ healBrotherRangeYd: 60,
392
+ encounterField: TYPE.TWINS,
393
+ cite: 'boss_twinemperors.cpp:96-125 DamageTaken/HealedBy; :209-210 Heal Brother 60yd',
394
+ },
395
+ lifecycle: lifecycleFor(TYPE.TWINS, 'boss_twinemperors.cpp'),
396
+ cites: [
397
+ 'boss_twinemperors.cpp:256 SPELL_UPPERCUT SELECT_FLAG_IN_MELEE_RANGE via select.inMelee; the flag is a target PICK here, while shadowfang_keep.cpp:477 and darkshore.cpp:805 use it as an EXISTENCE gate on a self-centred AoE, which is requireMeleeTargetExists',
398
+ 'boss_twinemperors.cpp:1-435 whole file',
399
+ 'boss_twinemperors.cpp:96-125,209-210 damageHealMirror (EMPATHY 1177 + HEAL_BROTHER 7393 + SUICIDE 26627)',
400
+ 'boss_twinemperors.cpp:332-356 TWIN_TELEPORT 799 SpellHit swaps pos with Veklor',
401
+ 'boss_twinemperors.cpp:66,175-178,242 MUTATE_BUG 802 script-AOE entries 15316/15317',
402
+ ],
403
+ };
404
+
405
+ export const BOSS_VEKLOR: ScriptDevIR = {
406
+ name: 'boss_veklor',
407
+ boundCreatures: [NPC.VEKLOR],
408
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp',
409
+ // Explode Bug and Enrage pay through 26059 / 26643, resolved off the kit.
410
+ spellIds: [26006, 26607, 568, 804, 799, 800, SPELL_TWIN.FRENZY, SPELL_TWIN.HEAL_BROTHER, SPELL_TWIN.EMPATHY, SPELL_TWIN.SUICIDE, 26059, 26643],
411
+ timers: [
412
+ t('shadow_bolt', 26006, 1000, 1000, 2000, 2000, 'victim', 'boss_twinemperors.cpp:289,374-375 SHADOW_BOLT 1s then every 2s'),
413
+ t('blizzard', 26607, 15_000, 20_000, 15_000, 30_000, 'hostile_random_player', 'boss_twinemperors.cpp:290,380-382 BLIZZARD 15-20s then 15-30s, PLAYER', { select: { playerOnly: true } }),
414
+ // Self-centred burst, gated in source on a top-aggro player inside the effect radius.
415
+ t('arcane_burst', 568, 1000, 1000, 5000, 5000, 'self', 'boss_twinemperors.cpp:291,387-389 ARCANE_BURST 1s then 5s, TOPAGGRO|USE_EFFECT_RADIUS'),
416
+ // TARGET_UNIT_CASTER. Cite: SpellTargetDefines.h:25; Spell.dbc 27897 EffectImplicitTargetA=1.
417
+ t('frenzy', SPELL_TWIN.FRENZY, 900_000, 900_000, 900_000, 900_000, 'self', 'boss_twinemperors.cpp:88,365 FRENZY at 15*MINUTE'),
418
+ t('twin_teleport', 799, 35_000, 35_000, 35_000, 35_000, 'self', 'boss_twinemperors.cpp:292,394 VEKLOR_TELEPORT 35s SPELL_TWIN_TELEPORT 799'),
419
+ t('explode_bug', 804, 7000, 14_000, 10_000, 17_000, 'self', 'boss_twinemperors.cpp:89,175-178,360 EMPEROR_BUG_ABILITY 7-14s then 10-17s SPELL_EXPLODE_BUG', {
420
+ pollOnly: true,
421
+ actions: [{
422
+ kind: 'cast_on_script_targets',
423
+ spellId: 804,
424
+ cite: 'boss_twinemperors.cpp:360 DoCastSpellIfCan(nullptr, SPELL_EXPLODE_BUG); spell_script_target 15316/15317',
425
+ }],
426
+ }),
427
+ ],
428
+ damageHealMirror: {
429
+ partnerEntry: NPC.VEKNILASH,
430
+ empathySpellId: SPELL_TWIN.EMPATHY,
431
+ suicideSpellId: SPELL_TWIN.SUICIDE,
432
+ healBrotherSpellId: SPELL_TWIN.HEAL_BROTHER,
433
+ healBrotherRangeYd: 60,
434
+ encounterField: TYPE.TWINS,
435
+ cite: 'boss_twinemperors.cpp:96-125 DamageTaken/HealedBy; :306-307 Heal Brother 60yd',
436
+ },
437
+ lifecycle: lifecycleFor(TYPE.TWINS, 'boss_twinemperors.cpp'),
438
+ cites: [
439
+ 'boss_twinemperors.cpp:1-435 whole file',
440
+ 'boss_twinemperors.cpp:96-125,306-307 damageHealMirror (EMPATHY 1177 + HEAL_BROTHER 7393 + SUICIDE 26627)',
441
+ 'boss_twinemperors.cpp:88,365 FRENZY 27897 at 15*MINUTE TARGET_UNIT_CASTER',
442
+ 'boss_twinemperors.cpp:292,332-356,393-394 TWIN_TELEPORT 799 SpellHit swaps pos with Veknilash',
443
+ 'boss_twinemperors.cpp:60,175-178,360 EXPLODE_BUG 804 script-AOE entries 15316/15317',
444
+ ],
445
+ };
446
+
447
+ // Viscidus, boss_viscidus.cpp read whole. The frost hit-count is ported — 100/150/200 packets apply
448
+ // 26034/26036/25937 — and the glob explode 25885 is a script-handled no-op.
449
+ export const BOSS_VISCIDUS: ScriptDevIR = {
450
+ name: 'boss_viscidus',
451
+ boundCreatures: [NPC.VISCIDUS],
452
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp',
453
+ spellIds: [25993, 25991, 25994, 26584, 25926, 26034, 26036, 25937],
454
+ timers: [
455
+ t('poison_shock', 25993, 7000, 12_000, 7000, 12_000, 'self', 'boss_viscidus.cpp:128,367-368 POISON_SHOCK 7-12s'),
456
+ t('poisonbolt_volley', 25991, 10_000, 15_000, 10_000, 15_000, 'self', 'boss_viscidus.cpp:129,373-374 POISONBOLT_VOLLEY 10-15s'),
457
+ t('toxin', 26584, 30_000, 30_000, 30_000, 30_000, 'hostile_random_player', 'boss_viscidus.cpp:127,358-362 VISCIDUS_TOXIN 30s SELECT_FLAG_PLAYER SPELL_SUMMON_TOXIC_SLIME 26584'),
458
+ ],
459
+ lifecycle: (() => {
460
+ const life = lifecycleFor(TYPE.VISCIDUS, 'boss_viscidus.cpp');
461
+ return {
462
+ ...life,
463
+ onAggro: [
464
+ ...life.onAggro,
465
+ {
466
+ kind: 'cast_self' as const,
467
+ spellId: 25994,
468
+ castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT,
469
+ cite: 'boss_viscidus.cpp:162 Aggro SPELL_MEMBRANE_VISCIDUS 25994 CAST_TRIGGERED|AURA_NOT_PRESENT',
470
+ },
471
+ {
472
+ kind: 'cast_self' as const,
473
+ spellId: 25926,
474
+ castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT,
475
+ cite: 'boss_viscidus.cpp:163 Aggro SPELL_VISCIDUS_WEAKNESS 25926 CAST_TRIGGERED|AURA_NOT_PRESENT',
476
+ },
477
+ ],
478
+ };
479
+ })(),
480
+ hitCountGates: [
481
+ {
482
+ id: 'frost',
483
+ school: 'frost',
484
+ requireAura: 25926,
485
+ phaseMin: 0,
486
+ phaseMax: 2,
487
+ thresholds: [
488
+ {
489
+ at: 100,
490
+ setPhase: 1,
491
+ actions: [
492
+ { kind: 'cast_self', spellId: 26034, castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT, cite: 'boss_viscidus.cpp:244 SPELL_VISCIDUS_SLOWED 26034' },
493
+ { kind: 'yell', textId: -1531041, cite: 'boss_viscidus.cpp:243 EMOTE_SLOW' },
494
+ ],
495
+ cite: 'boss_viscidus.cpp:87 HITCOUNT_SLOW 100; :301-305 PHASE_SLOWED',
496
+ },
497
+ {
498
+ at: 150,
499
+ setPhase: 2,
500
+ actions: [
501
+ { kind: 'remove_auras', spellId: 26034, cite: 'boss_viscidus.cpp:229 RemoveAurasDueToSpell SLOWED' },
502
+ { kind: 'cast_self', spellId: 26036, castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT, cite: 'boss_viscidus.cpp:250 SPELL_VISCIDUS_SLOWED_MORE 26036' },
503
+ { kind: 'yell', textId: -1531042, cite: 'boss_viscidus.cpp:249 EMOTE_FREEZE' },
504
+ ],
505
+ cite: 'boss_viscidus.cpp:88 HITCOUNT_SLOW_MORE 150; :307-311 PHASE_SLOWED_MORE',
506
+ },
507
+ {
508
+ at: 200,
509
+ setPhase: 3,
510
+ resetCount: true,
511
+ durationMs: 15_000,
512
+ actions: [
513
+ { kind: 'remove_auras', spellId: 26036, cite: 'boss_viscidus.cpp:230 RemoveAurasDueToSpell SLOWED_MORE' },
514
+ { kind: 'cast_self', spellId: 25937, castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT, cite: 'boss_viscidus.cpp:258 SPELL_VISCIDUS_FREEZE 25937' },
515
+ { kind: 'set_combat_movement', enabled: false, cite: 'boss_viscidus.cpp:258 freeze stun (self 25937)' },
516
+ { kind: 'yell', textId: -1531043, cite: 'boss_viscidus.cpp:257 EMOTE_FROZEN' },
517
+ ],
518
+ onExpire: {
519
+ setPhase: 0,
520
+ resetCount: true,
521
+ actions: [
522
+ { kind: 'remove_auras', spellId: 25937, cite: 'boss_viscidus.cpp:231 RemoveAurasDueToSpell FREEZE' },
523
+ { kind: 'set_combat_movement', enabled: true, cite: 'boss_viscidus.cpp:235-240 PHASE_NORMAL melee on' },
524
+ { kind: 'cast_self', spellId: 25994, castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT, cite: 'boss_viscidus.cpp:237 SPELL_MEMBRANE_VISCIDUS' },
525
+ { kind: 'cast_self', spellId: 25926, castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT, cite: 'boss_viscidus.cpp:238 SPELL_VISCIDUS_WEAKNESS' },
526
+ { kind: 'reset_threat', cite: 'boss_viscidus.cpp:239 SPELL_HATE_TO_ZERO 20538' },
527
+ ],
528
+ cite: 'boss_viscidus.cpp:415-419 freeze OnApply(!apply) CUSTOM_A → PHASE_NORMAL; 25937 durationIndex 8',
529
+ },
530
+ cite: 'boss_viscidus.cpp:89 HITCOUNT_FREEZE 200; :313-317 PHASE_FROZEN',
531
+ },
532
+ ],
533
+ cite: 'boss_viscidus.cpp:552-565 ViscidusFrostWeakness frost school → CUSTOM_B IncreaseHitCount',
534
+ },
535
+ {
536
+ id: 'melee',
537
+ melee: true,
538
+ phaseMin: 3,
539
+ phaseMax: 3,
540
+ thresholds: [
541
+ {
542
+ at: 50,
543
+ actions: [{ kind: 'yell', textId: -1531044, cite: 'boss_viscidus.cpp:322 EMOTE_CRACK' }],
544
+ cite: 'boss_viscidus.cpp:90 HITCOUNT_CRACK 50',
545
+ },
546
+ {
547
+ at: 100,
548
+ actions: [{ kind: 'yell', textId: -1531045, cite: 'boss_viscidus.cpp:324 EMOTE_SHATTER' }],
549
+ cite: 'boss_viscidus.cpp:91 HITCOUNT_SHATTER 100',
550
+ },
551
+ {
552
+ // THE SHATTER: 150 melee hits burst him into twenty globs, each worth 5 % of his bulk.
553
+ // Twenty globs is exactly a full bar, which is why this and not raw dps ends him.
554
+ at: 150,
555
+ setPhase: VISCIDUS_PHASE_EXPLODED,
556
+ resetCount: true,
557
+ actions: [
558
+ {
559
+ kind: 'summon_count',
560
+ creatureEntry: NPC.GLOB_OF_VISCIDUS,
561
+ count: VISCIDUS_GLOB_COUNT,
562
+ cite: 'boss_viscidus.cpp:63,387 SPELL_SUMMON_GLOBS 25885 - a script effect that fires the twenty summons 25865-25884, each raw effect 41 -> NPC 15667',
563
+ },
564
+ { kind: 'set_unattackable', cite: 'boss_viscidus.cpp:391-393 SPELL_INVIS_SELF 25905 + SPELL_STUN_SELF 25900' },
565
+ { kind: 'set_melee_enabled', enabled: false, cite: 'boss_viscidus.cpp:393 SPELL_STUN_SELF 25900' },
566
+ { kind: 'remove_auras', spellId: 25926, cite: 'boss_viscidus.cpp:397 RemoveAurasDueToSpell(SPELL_VISCIDUS_WEAKNESS)' },
567
+ ],
568
+ cite: 'boss_viscidus.cpp:92 HITCOUNT_EXPLODE 150; :325-326 SetPhase(PHASE_EXPLODED); :382-400 HandleExplode',
569
+ },
570
+ ],
571
+ cite: 'boss_viscidus.cpp:422-428 ViscidusFreeze melee OnProc CUSTOM_C; :92 HITCOUNT_EXPLODE 150',
572
+ },
573
+ ],
574
+ cites: [
575
+ 'boss_viscidus.cpp:1-585 whole file',
576
+ 'boss_viscidus.cpp:127,358-362 VISCIDUS_TOXIN 30s 26584 on random player',
577
+ 'boss_viscidus.cpp:162-163 Aggro 25994 + 25926; frost 100/150/200 → 26034/26036/25937',
578
+ 'boss_viscidus.cpp:382-400,505-521 SUMMON_GLOBS 25885 -> twenty globs, each death shrinking him 5 % via shrink_creature_pct',
579
+ 'boss_viscidus.cpp:214-224 SummonedMovementInform rejoin walk - residual: no movement verb, so a glob the raid ignores never walks back and never restores the 5 %',
580
+ ],
581
+ };
582
+
583
+ export const BOSS_EYE_OF_CTHUN: ScriptDevIR = {
584
+ name: 'boss_eye_of_cthun',
585
+ boundCreatures: [15589],
586
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_cthun.cpp',
587
+ spellIds: [26134, 32950, 26029, 26137, 26397, 26152, 18950, 26255],
588
+ timers: [
589
+ t('eye_beam_init', 32950, 1, 1, 3000, 5000, 'victim', 'boss_cthun.cpp:117 AddCombatAction INIT_EYEBEAM 1ms; :225-234 first three on the victim then DisableCombatAction', { maxFires: 3 }),
590
+ // After the first three the DB list takes over: 26134 on a random player every 2-3 s.
591
+ t('eye_beam', 26134, 22_000, 22_000, 2000, 3000, 'hostile_random_player', 'creature_spell_list 1558900:1 Eye of Cthun - Eye Beam, TargetId 100 = attack random player, 22 s then 2-3 s', { phase: 0, select: { playerOnly: true } }),
592
+ // 26137 is a bare SCRIPT effect whose only job is the phase switch, so the row polls: 40 s of
593
+ // Dark Glare with no targeting, then back to eye beams. Cite: boss_cthun.cpp:208-220 OnSpellCast.
594
+ t('rotate_trigger', 26137, 45_000, 45_000, 85_000, 85_000, 'self', 'creature_spell_list 1558900:0 Eye of Cthun - Rotate Trigger, 45 s then 85 s; boss_cthun.cpp:208-220 OnSpellCast SPELL_ROTATE_TRIGGER -> 40 s sub-phase', {
595
+ phase: 0,
596
+ pollOnly: true,
597
+ actions: [
598
+ { kind: 'set_phase', phase: 1, cite: 'boss_cthun.cpp:213-218 SetCombatScriptStatus(true) + SetTarget(nullptr) for the Dark Glare sub-phase' },
599
+ { kind: 'arm_timer', timerId: 'dark_glare_end', delayMs: 40_000, cite: 'boss_cthun.cpp:219 ResetTimer(EYECTHUN_END_DARKGLARE, 40000)' },
600
+ ],
601
+ }),
602
+ // The sweep itself: 26029 is a 100 yd CONE, and the rotate auras 26009/26136 pulse it every
603
+ // second while the eye spins. Cite: spell_template 26009/26136 aura 23 amplitude 1000.
604
+ t('dark_glare', 26029, 0, 0, 1000, 1000, 'self', 'boss_cthun.cpp:40-43 SPELL_DARK_GLARE 26029 triggered by SPELL_ROTATE_360_LEFT 26009 / RIGHT 26136; spell_template 26029 direct_damage shadow 43750-56250 cone radiusYd 100', { phase: 1 }),
605
+ // spellId 0 on purpose: this row shares no id with rotate_trigger, and applyScriptDevTimerActions
606
+ // matches on the id, so 26137 on both would have run BOTH action lists on every fire.
607
+ t('dark_glare_end', 0, 40_000, 40_000, 40_000, 40_000, 'self', 'boss_cthun.cpp:193-205 HandleEndDarkGlare strips the rotate auras and resumes targeting', {
608
+ phase: 1,
609
+ pollOnly: true,
610
+ startDisabled: true,
611
+ actions: [
612
+ { kind: 'set_phase', phase: 0, cite: 'boss_cthun.cpp:200-205 SetCombatScriptStatus(false) + SetTarget(GetVictim()) + AddInitialCooldowns' },
613
+ { kind: 'arm_timer', timerId: 'eye_beam', delayMs: 2000, cite: 'boss_cthun.cpp:205 AddInitialCooldowns re-arms the eye beam' },
614
+ ],
615
+ }),
616
+ ],
617
+ lifecycle: {
618
+ onAggro: [
619
+ { kind: 'set_instance_data', field: TYPE.CTHUN, value: INSTANCE_DATA.IN_PROGRESS, cite: 'boss_cthun.cpp:144-145 Aggro SetData(TYPE_CTHUN, IN_PROGRESS)' },
620
+ { kind: 'cast_self', spellId: 26152, castFlags: 1, cite: 'boss_cthun.cpp:151 SPELL_SUMMON_EYE_TENTACLES CAST_TRIGGERED|AURA_NOT_PRESENT' },
621
+ { kind: 'cast_self', spellId: 26397, castFlags: 1, cite: 'boss_cthun.cpp:152 SPELL_SUMMON_HOOK_TENTACLES_1 CAST_TRIGGERED|AURA_NOT_PRESENT' },
622
+ ],
623
+ onEvade: [
624
+ { kind: 'set_instance_data', field: TYPE.CTHUN, value: INSTANCE_DATA.FAIL, cite: 'boss_cthun.cpp:178-179 EnterEvadeMode SetData(FAIL)' },
625
+ ],
626
+ },
627
+ cites: [
628
+ 'boss_cthun.cpp:102-239 boss_eye_of_cthunAI',
629
+ 'boss_cthun.cpp:193-220 the 40 s Dark Glare sub-phase via a phase swap: 26029 pulses its own 100 yd cone every second, which is the sweep. The ORIENTATION control (the eye spinning, so the cone walks the room) is a residual - the rotate auras 26009/26136 turn the body and no facing verb here does',
630
+ ],
631
+ };
632
+
633
+ // The body phase has ONE win condition and it is not damage: two Flesh Tentacles stand in the
634
+ // stomach, and killing both strips the Carapace for 45 s. Everything else here is pressure.
635
+ export const BOSS_CTHUN: ScriptDevIR = {
636
+ name: 'boss_cthun',
637
+ boundCreatures: [15727],
638
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_cthun.cpp',
639
+ spellIds: [26213, 26769, 26232, 26235, 26156, 26255],
640
+ timers: [
641
+ t('giant_claw', 26213, 10_000, 10_000, 60_000, 60_000, 'self', 'boss_cthun.cpp:259 AddCombatAction CLAWTENTACLEDELAY 10s; comment :258 60s period after the offset'),
642
+ t('giant_eye', 26769, 40_000, 40_000, 60_000, 60_000, 'self', 'boss_cthun.cpp:260 AddCombatAction EYETENTACLEDELAY 40s; 60s period after the offset'),
643
+ // HandleEndWeaken, 45 s after the vulnerability lands: the Carapace comes back and a fresh pair
644
+ // of Flesh Tentacles goes up, so the raid has to do it again.
645
+ t('weaken_end', 26156, 0, 0, 0, 0, 'self', 'boss_cthun.cpp:406 ResetTimer(CTHUN_WEAKENED_END, 45s); :410-416 HandleEndWeaken re-casts SPELL_CARAPACE_CTHUN 26156 + SPELL_CHECK_RESET_AURA 26255 and re-spawns the tentacles', {
646
+ startDisabled: true,
647
+ castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT,
648
+ actions: [
649
+ { kind: 'cast_self', spellId: 26255, castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT, cite: 'boss_cthun.cpp:414 SPELL_CHECK_RESET_AURA 26255' },
650
+ {
651
+ kind: 'summon_count',
652
+ creatureEntry: NPC.FLESH_TENTACLE,
653
+ count: MAX_FLESH_TENTACLES,
654
+ x: CTHUN_FLESH_TENTACLE_XY[0],
655
+ y: CTHUN_FLESH_TENTACLE_XY[1],
656
+ cite: 'boss_cthun.cpp:94-99 cthunLocations[0..1]; :371-373 DoSpawnTentacles summons MAX_FLESH_TENTACLES 2',
657
+ },
658
+ ],
659
+ }),
660
+ ],
661
+ lifecycle: {
662
+ ...lifecycleFor(TYPE.CTHUN, 'boss_cthun.cpp'),
663
+ onAggro: [
664
+ { kind: 'set_instance_data', field: TYPE.CTHUN, value: INSTANCE_DATA.IN_PROGRESS, cite: 'boss_cthun.cpp Aggro SetData(IN_PROGRESS)' },
665
+ { kind: 'cast_self', spellId: 26156, castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT, cite: 'boss_cthun.cpp:390 HandleEmerge SPELL_CARAPACE_CTHUN 26156' },
666
+ {
667
+ kind: 'summon_count',
668
+ creatureEntry: NPC.FLESH_TENTACLE,
669
+ count: MAX_FLESH_TENTACLES,
670
+ x: CTHUN_FLESH_TENTACLE_XY[0],
671
+ y: CTHUN_FLESH_TENTACLE_XY[1],
672
+ cite: 'boss_cthun.cpp:94-99 cthunLocations[0..1]; :371-373 DoSpawnTentacles',
673
+ },
674
+ ],
675
+ },
676
+ // The stomach pair is the ONLY thing that makes him killable, and the hook that owns it already
677
+ // exists for Majordomo: a boss whose encounter turns on his own adds dying, not on his own death.
678
+ addDeaths: [{
679
+ creatureEntries: [NPC.FLESH_TENTACLE],
680
+ atKilled: 'all',
681
+ total: MAX_FLESH_TENTACLES,
682
+ actions: [
683
+ { kind: 'cast_self', spellId: 26235, cite: 'boss_cthun.cpp:399 HandleWeaken SPELL_CTHUN_VULNERABLE 26235 CAST_INTERRUPT_PREVIOUS' },
684
+ { kind: 'remove_auras', spellId: 26156, cite: 'boss_cthun.cpp:402 RemoveAurasDueToSpell(SPELL_CARAPACE_CTHUN)' },
685
+ { kind: 'remove_auras', spellId: 26255, cite: 'boss_cthun.cpp:401 RemoveAurasDueToSpell(SPELL_CHECK_RESET_AURA)' },
686
+ { kind: 'yell', textId: 11476, cite: 'boss_cthun.cpp:32,404 EMOTE_WEAKENED 11476' },
687
+ { kind: 'arm_timer', timerId: 'weaken_end', delayMs: 45_000, cite: 'boss_cthun.cpp:406 ResetTimer(CTHUN_WEAKENED_END, 45 * IN_MILLISECONDS)' },
688
+ ],
689
+ cite: 'boss_cthun.cpp:351-360 SummonedCreatureJustDied counts NPC_FLESH_TENTACLE to MAX_FLESH_TENTACLES then HandleWeaken',
690
+ }],
691
+ cites: [
692
+ 'boss_cthun.cpp:241-460 boss_cthunAI body phase',
693
+ 'boss_cthun.cpp:91,351-360,371-373,396-416 two Flesh Tentacles 15802 -> 26235 vulnerable, carapace off, 45 s, then both respawn',
694
+ 'boss_cthun.cpp:77-89,555-600 the stomach TELEPORT itself (26220 in, 26221/26230 out, areatriggers 4033/4034/4036) is a residual: this engine has no in-fight teleport-to-a-second-room verb, so the tentacles stand in the same room the raid is already in',
695
+ ],
696
+ };
697
+
698
+ // A rooted body with two ONE-SHOT ground pulses, not a melee add: the IR was empty, so neither
699
+ // pulse nor the immobilize existed. Neither AddCustomAction handler re-arms.
700
+ export const MOB_GIANT_CLAW_TENTACLE: ScriptDevIR = {
701
+ name: 'mob_giant_claw_tentacle',
702
+ boundCreatures: [15728],
703
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_cthun.cpp',
704
+ spellIds: [26478, 6524, 26404],
705
+ timers: [
706
+ t('ground_rupture', 26478, 2000, 2000, 0, 0, 'self', 'boss_cthun.cpp:490,504-507 AddCustomAction(GIANTCLAW_RUPTURE, 2000) HandleRupture SPELL_GIANT_GROUND_RUPTURE 26478, never re-armed', { oneShot: true }),
707
+ t('ground_tremor', 6524, 7000, 7000, 0, 0, 'self', 'boss_cthun.cpp:491,509-512 AddCustomAction(GIANTCLAW_GROUND_TREMOR, 7000) HandleGroundTremor SPELL_GROUND_TREMOR 6524, never re-armed', { oneShot: true }),
708
+ ],
709
+ lifecycle: {
710
+ onReset: [
711
+ { kind: 'set_combat_movement', enabled: false, cite: 'boss_cthun.cpp:501 Reset SetImmobilizedState(true)' },
712
+ ],
713
+ onDeath: [
714
+ { kind: 'cast_self', spellId: 26404, cite: 'boss_cthun.cpp:514-517 JustDied CastSpell(nullptr, SPELL_DESPAWN_TENT_PORT 26404, TRIGGERED_OLD_TRIGGERED)' },
715
+ ],
716
+ },
717
+ cites: [
718
+ 'boss_cthun.cpp:484-547 npc_giant_claw_tentacleAI whole struct',
719
+ 'boss_cthun.cpp:464,470-471 SPELL_GIANT_GROUND_RUPTURE 26478, SPELL_GROUND_TREMOR 6524, SPELL_DESPAWN_TENT_PORT 26404',
720
+ 'boss_cthun.cpp:488,523-545 GIANTCLAW_CHECKTARGET: after 5 s untanked it TELEPORTS to its victim with 26205. Residual - this engine has no in-fight teleport verb, and chase_focus would re-pick a target rather than move the body, which is a different mechanic',
721
+ ],
722
+ };
723
+
724
+ export const AT_STOMACH_CTHUN: ScriptDevIR = {
725
+ name: 'at_stomach_cthun',
726
+ boundCreatures: [],
727
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_cthun.cpp',
728
+ spellIds: [26220, 26230],
729
+ timers: [],
730
+ cites: [
731
+ 'boss_cthun.cpp:87-89 AREATRIGGER_STOMACH_1/2/3 4033/4034/4036; at_stomach_cthun eject/kill',
732
+ ],
733
+ };
734
+
735
+ export const BOSS_OURO: ScriptDevIR = {
736
+ name: 'boss_ouro',
737
+ boundCreatures: [15517],
738
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_ouro.cpp',
739
+ // Berserk 26615 summons the mounds through 26617, resolved off the kit.
740
+ spellIds: [18941, 26103, 26102, 26616, 26615, 26586, 26100, 26063, 26058, 26617],
741
+ timers: [
742
+ t('birth_spawn', 26586, 300, 300, 300, 300, 'self', 'boss_ouro.cpp:112 AddCombatAction OURO_SPAWN 300ms; :227 DisableCombatAction after first', { phase: 0 }),
743
+ t('sandblast', 26102, 25_000, 25_000, 25_000, 25_000, 'self', 'boss_ouro.cpp:115 AddCombatAction SAND_BLAST 25s; :268-269 CAST_OK re-arm 25000', { phase: 0 }),
744
+ t('sweep', 26103, 20_000, 20_000, 20_000, 20_000, 'self', 'boss_ouro.cpp:116 AddCombatAction SWEEP 20s; :274-275 CAST_OK re-arm 20000', { phase: 0 }),
745
+ t('double_attack', 18941, 1000, 10_000, 1000, 10_000, 'self', 'boss_ouro.cpp:117 AddCombatAction DOUBLE_ATTACK urand(1-10)s', { phase: 0 }),
746
+ t('berserk', 26615, 0, 0, 0, 0, 'self', 'boss_ouro.cpp:247-256 OURO_ENRAGE timerless at <20% HP', { hpPctMax: 20 }),
747
+ ],
748
+ timedPhases: [
749
+ {
750
+ id: 'submerge',
751
+ phase: 1,
752
+ afterMs: 90_000,
753
+ next: 'emerge',
754
+ hpMinPct: 20,
755
+ actions: [
756
+ { kind: 'cast_self', spellId: 26063, castFlags: CAST_FLAG.TRIGGERED, cite: 'boss_ouro.cpp:193 SPELL_SUBMERGE_VISUAL 26063' },
757
+ { kind: 'cast_self', spellId: 26058, castFlags: CAST_FLAG.TRIGGERED, cite: 'boss_ouro.cpp:197 SPELL_SUMMON_OURO_MOUNDS 26058 (raw effect 41 bp 4 → 5× NPC 15712)' },
758
+ { kind: 'set_unattackable', cite: 'boss_ouro.cpp:200 SetFlag UNIT_FLAG_UNINTERACTIBLE (ForcedDespawn 2000 skipped — same body re-emerges)' },
759
+ { kind: 'set_combat_movement', enabled: false, cite: 'boss_ouro.cpp:196 SetMeleeEnabled(false)' },
760
+ { kind: 'flavor', text: 'burrows.', cite: 'boss_ouro.cpp:191-209 Burrow' },
761
+ ],
762
+ cite: 'boss_ouro.cpp:113,191-209,261-264 OURO_SUBMERGE 90s Burrow 5 dirt mounds',
763
+ },
764
+ {
765
+ id: 'emerge',
766
+ phase: 0,
767
+ afterMs: 30_000,
768
+ next: 'submerge',
769
+ actions: [
770
+ { kind: 'clear_unattackable', cite: 'boss_ouro.cpp:214-218 HandleSpawnDelay SetMeleeEnabled(true)' },
771
+ { kind: 'set_combat_movement', enabled: true, cite: 'boss_ouro.cpp:214 SetMeleeEnabled(true)' },
772
+ { kind: 'cast_self', spellId: 26100, cite: 'boss_ouro.cpp:218 SPELL_GROUND_RUPTURE on emerge' },
773
+ { kind: 'flavor', text: 'erupts from the sand.', cite: 'boss_ouro.cpp:212-218 HandleSpawnDelay' },
774
+ ],
775
+ cite: 'spell-data 26642 tickMs 30000 first mound SPELL_SUMMON_OURO_TRIGG → re-summon; product keeps the same body',
776
+ },
777
+ ],
778
+ lifecycle: lifecycleFor(TYPE.OURO, 'boss_ouro.cpp'),
779
+ cites: [
780
+ 'boss_ouro.cpp:107-280 boss_ouroAI ground kit',
781
+ 'boss_ouro.cpp:191-209,197 SPELL_SUMMON_OURO_MOUNDS 26058 five NPC 15712; emerge 30s (26642 tickMs)',
782
+ ],
783
+ };
784
+
785
+ export const NPC_OURO_SPAWNER: ScriptDevIR = {
786
+ name: 'npc_ouro_spawner',
787
+ boundCreatures: [15957],
788
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_ouro.cpp',
789
+ spellIds: [],
790
+ timers: [],
791
+ cites: ['boss_ouro.cpp npc_ouro_spawner — summons Ouro; no combat timer'],
792
+ };
793
+
794
+ // The mound is the submerge phase's whole pressure: a 1 s Quake pulse under it and a fresh random
795
+ // player picked every 5-10 s, so it cannot be tanked and the raid has to break line with it.
796
+ export const NPC_OURO_MOUND: ScriptDevIR = {
797
+ name: 'npc_ouro_mound',
798
+ boundCreatures: [15712],
799
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_ouro.cpp',
800
+ // 26093 Quake is 26092's periodic payload and has to be on the kit for the trigger to resolve.
801
+ spellIds: [24780, 26060, 26092, 26093],
802
+ timers: [
803
+ t('dirtmound_passive', 26092, 0, 0, 0, 0, 'self', 'boss_ouro.cpp:56,360-362 Reset SPELL_DIRTMOUND_PASSIVE 26092 CAST_AURA_NOT_PRESENT | CAST_TRIGGERED; it casts SPELL_QUAKE 26093 every 1 s', {
804
+ onReset: true,
805
+ castFlags: CAST_FLAG.TRIGGERED | CAST_FLAG.AURA_NOT_PRESENT,
806
+ }),
807
+ // PickNewTarget: SetInCombatWithZone, DoResetThreat, a random PLAYER, AddThreat 1000000 and
808
+ // AttackStart — the chase_focus verb exactly, on a 1 s first pick then urand(5-10)s.
809
+ t('pick_new_target', 26092, 1000, 1000, 5000, 10_000, 'self', 'boss_ouro.cpp:357,378-387,390-393 AddCustomAction(1) delayed 1000 then ResetTimer(1, urand(5000,10000)) PickNewTarget', {
810
+ pollOnly: true,
811
+ actions: [{
812
+ kind: 'chase_focus',
813
+ threat: 1_000_000,
814
+ cite: 'boss_ouro.cpp:379-386 SetInCombatWithZone + DoResetThreat + SelectAttackingTarget(RANDOM, 0, nullptr, SELECT_FLAG_PLAYER) + AddThreat(target, 1000000.f) + AttackStart',
815
+ }],
816
+ }),
817
+ ],
818
+ cites: [
819
+ 'boss_ouro.cpp:352-394 npc_ouro_moundAI',
820
+ 'boss_ouro.cpp:51-56 SPELL_QUAKE 26093, SPELL_DREAM_FOG 24780, SPELL_DIRTMOUND_PASSIVE 26092, SPELL_SUMMON_SCARABS 26060',
821
+ 'boss_ouro.cpp:52 SPELL_DREAM_FOG 24780 is commented "on mounds" and is cast NOWHERE in the file, so it stays absent rather than invented',
822
+ 'boss_ouro.cpp:440-447 the 30 s scarab summon is an AuraScript payload swap on the passive - no aura-script payload-swap verb here, so 26060 rides the kit unscheduled',
823
+ ],
824
+ };
825
+
826
+ export const NPC_OURO_TRIGGER: ScriptDevIR = {
827
+ name: 'npc_ouro_trigger',
828
+ boundCreatures: [15717],
829
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_ouro.cpp',
830
+ spellIds: [],
831
+ timers: [],
832
+ cites: ['boss_ouro.cpp:85-105 npc_ouro_triggerAI stores Ouro HP% for emerge; REACT_PASSIVE'],
833
+ };
834
+
835
+ // No ScriptName of its own: the behaviour is Viscidus's summon hooks plus the ViscidusShrinks
836
+ // SpellScript. It gets an IR because the hook that owns the 5 % is the glob's own death.
837
+ export const NPC_GLOB_OF_VISCIDUS: ScriptDevIR = {
838
+ name: 'npc_glob_of_viscidus',
839
+ boundCreatures: [NPC.GLOB_OF_VISCIDUS],
840
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_viscidus.cpp',
841
+ spellIds: [25896],
842
+ timers: [],
843
+ lifecycle: {
844
+ onDeath: [{
845
+ kind: 'shrink_creature_pct',
846
+ creatureEntry: NPC.VISCIDUS,
847
+ pct: VISCIDUS_GLOB_SHRINK_PCT,
848
+ cite: 'boss_viscidus.cpp:505-521 ViscidusShrinks: hpLose = 0.05f * GetMaxHealth(), SetHealth(GetHealth() - hpLose) with a GetHealth() > 1 + hpLose floor',
849
+ }],
850
+ },
851
+ cites: [
852
+ 'boss_viscidus.cpp:63,82 SPELL_SUMMON_GLOBS 25885 -> NPC_GLOB_OF_VISCIDUS 15667',
853
+ 'boss_viscidus.cpp:183-198 JustSummoned REACT_PASSIVE + MovePoint back to the respawn coord',
854
+ 'boss_viscidus.cpp:200-210 SummonedCreatureJustDied -> the shrink; :214-224 the rejoin walk is a movement residual',
855
+ 'creature_template 15667 Glob of Viscidus carries no ScriptName; the shrink is a SpellScript on 25893/27934',
856
+ ],
857
+ };
858
+
859
+ export const NPC_OURO_SCARAB: ScriptDevIR = {
860
+ name: 'npc_ouro_scarab',
861
+ boundCreatures: [15718],
862
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/boss_ouro.cpp',
863
+ spellIds: [],
864
+ timers: [],
865
+ cites: ['boss_ouro.cpp npc_ouro_scarab — mound hatch add; no independent combat timer'],
866
+ };
867
+
868
+ /** mob_anubisath_sentinel.cpp:78 m_abilities — the nine dealt one per sibling, never stacked. */
869
+ const SENTINEL_ABILITIES = [812, 2147, 2148, 2834, 9347, 13022, 19595, 21737, 25777] as const;
870
+
871
+ // Five sentinels, nine abilities, one shuffle: the group that aggros deals pool[0..4] out and each
872
+ // wears exactly one. On death the dead one's ability moves to every survivor, so a wipe-race stacks.
873
+ export const MOB_ANUBISATH_SENTINEL: ScriptDevIR = {
874
+ name: 'mob_anubisath_sentinel',
875
+ boundCreatures: [15264],
876
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp',
877
+ spellIds: [8599, 2400, 26565, ...SENTINEL_ABILITIES],
878
+ timers: [
879
+ // DisableCombatAction after CAST_OK, so it is one enrage per pull and not a per-tick re-arm.
880
+ t('enrage', 8599, 0, 0, 0, 0, 'self', 'mob_anubisath_sentinel.cpp:65 AddTimerlessCombatAction BERSERK_HP_CHECK; :211-221 <30 % CAST_OK then DisableCombatAction', { hpPctMax: 30, oneShot: true }),
881
+ ],
882
+ lifecycle: {
883
+ onAggro: [{
884
+ kind: 'deal_group_abilities',
885
+ spellIds: [...SENTINEL_ABILITIES],
886
+ radiusYd: 80,
887
+ cite: 'mob_anubisath_sentinel.cpp:117 GetCreatureListWithEntryInGrid 80.0f; :127-131 std::shuffle; :140-159 SetAbility; :183-205 InitSentinelsNear',
888
+ }],
889
+ onDeath: [{
890
+ kind: 'transfer_group_ability',
891
+ healSpellId: 26565,
892
+ radiusYd: 80,
893
+ cite: 'mob_anubisath_sentinel.cpp:136-138,163-181 JustDied DoTransferAbility SPELL_TRANSFER_POWER 2400; :225-243 SharePowers casts the ability + SPELL_HEAL_BRETHEN 26565 on the buddy',
894
+ }],
895
+ },
896
+ cites: [
897
+ 'mob_anubisath_sentinel.cpp:36-247 whole npc_anubisath_sentinelAI',
898
+ 'mob_anubisath_sentinel.cpp:53 MAX_BUDDY 4 (five bodies incl. self); :78 the nine-ability pool',
899
+ 'mob_anubisath_sentinel.cpp:95-110 EnterEvadeMode respawns fallen buddies — no host verb, left out',
900
+ ],
901
+ };
902
+
903
+ // The Defender re-randomises on every AGGRO, not on spawn: one reflect, one of Meteor/Plague, one of
904
+ // Thunderclap/Shadow Storm, and a summon slot that re-rolls on EVERY fire (so that one rotates).
905
+ export const MOB_ANUBISATH_DEFENDER: ScriptDevIR = {
906
+ name: 'mob_anubisath_defender',
907
+ boundCreatures: [15277],
908
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp',
909
+ spellIds: [8269, 25698, 26555, 26556, 26558, 26554, 13022, 19595, 17430, 17431],
910
+ timers: [
911
+ t('defender_reflect', 13022, 0, 0, 0, 0, 'self', 'mob_anubisath_sentinel.cpp:293-294 Aggro urand(0,1) FIRE_ARCANE_REFLECT 13022 / SHADOW_FROST_REFLECT 19595, CAST_TRIGGERED', {
912
+ onReset: true,
913
+ pickPerSpawnSpellIds: [13022, 19595],
914
+ }),
915
+ // Aggro picks ONE of the pair and arms only that action, so the two rows are one slot with a pool.
916
+ // Meteor takes a random PLAYER, Plague takes SELECT_FLAG_SKIP_TANK.
917
+ t('defender_meteor_plague', 26558, 6000, 10_000, 8000, 12_000, 'hostile_random', 'mob_anubisath_sentinel.cpp:296-299,332-349 urand(0,1) METEOR 26558 (SELECT_FLAG_PLAYER) / PLAGUE 26556 (SKIP_TANK), 6-10s then 8-12s', {
918
+ select: { playerOnly: true },
919
+ pickPerSpawnSpellIds: [26558, 26556],
920
+ }),
921
+ t('defender_clap_storm', 26554, 5000, 8000, 6000, 10_000, 'self', 'mob_anubisath_sentinel.cpp:301-304,350-361 urand(0,1) THUNDERCLAP 26554 / SHADOW_STORM 26555 (nullptr target), 5-8s then 6-10s', {
922
+ pickPerSpawnSpellIds: [26554, 26555],
923
+ }),
924
+ // This one really is per-fire: the urand sits inside ExecuteAction, so it re-rolls each cast.
925
+ t('defender_summon', 17430, 3000, 5000, 12_000, 16_000, 'self', 'mob_anubisath_sentinel.cpp:283,362-376 ANUBDEFENDER_SUMMON 3-5s then 12-16s, urand(0,1) SWARMGUARD 17430 / WARRIOR 17431 per fire', {
926
+ rotateSpellIds: [17430, 17431],
927
+ waveMinCount: 1,
928
+ waveMaxCount: 1,
929
+ }),
930
+ t('defender_hp_check', 8269, 1000, 1000, 0, 0, 'self', 'mob_anubisath_sentinel.cpp:277,312-330 HP_CHECK <10 % urand(0,1) ENRAGE 8269 / EXPLODE 25698, then DisableCombatAction', {
931
+ hpPctMax: 9,
932
+ oneShot: true,
933
+ pickPerSpawnSpellIds: [8269, 25698],
934
+ actions: [{ kind: 'flavor', text: 'goes into a frenzy!', cite: 'mob_anubisath_sentinel.cpp:320 DoScriptText(EMOTE_GENERIC_FRENZY 2384)' }],
935
+ }),
936
+ ],
937
+ cites: [
938
+ 'mob_anubisath_sentinel.cpp:249-380 whole npc_anubisath_defenderAI',
939
+ 'mob_anubisath_sentinel.cpp:288-306 Aggro re-randomises the four abilities every pull',
940
+ 'mob_anubisath_sentinel.cpp:290 RemoveAllAuras on aggro — no host verb, left out',
941
+ ],
942
+ };
943
+
944
+ export const AT_TEMPLE_AHNQIRAJ: ScriptDevIR = {
945
+ name: 'at_temple_ahnqiraj',
946
+ boundCreatures: [],
947
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.cpp',
948
+ spellIds: [],
949
+ timers: [],
950
+ cites: ['temple_of_ahnqiraj.cpp:476 AreaTrigger_at_temple_ahnqiraj — C\'Thun room / twins intro'],
951
+ };
952
+
953
+ export const EVENT_CTHUN_RESET: ScriptDevIR = {
954
+ name: 'event_cthun_reset',
955
+ boundCreatures: [],
956
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.cpp',
957
+ spellIds: [26257],
958
+ timers: [],
959
+ cites: ['temple_of_ahnqiraj.cpp:481 event_cthun_reset — SPELL_RESET_ENCOUNTER 26257'],
960
+ };
961
+
962
+ export const INSTANCE_TEMPLE_OF_AHNQIRAJ: ScriptDevIR = {
963
+ name: 'instance_temple_of_ahnqiraj',
964
+ boundCreatures: [],
965
+ sourceFile: 'kalimdor/temple_of_ahnqiraj/temple_of_ahnqiraj.cpp',
966
+ spellIds: [],
967
+ timers: [],
968
+ // Every slot that has a creature, not just the four bosses whose kits are ported: the instance
969
+ // table is state, and a raid that clears Viscidus must record it even without a freeze verb.
970
+ encounters: [
971
+ { creatureEntry: NPC.SKERAM, field: TYPE.SKERAM, cite: 'temple_of_ahnqiraj.h:12 TYPE_SKERAM' },
972
+ { creatureEntry: 15511, field: TYPE.BUG_TRIO, cite: 'temple_of_ahnqiraj.h:13 TYPE_BUG_TRIO (Lord Kri 15511 is the primary)' },
973
+ { creatureEntry: NPC.SARTURA, field: TYPE.SARTURA, cite: 'temple_of_ahnqiraj.h:14 TYPE_SARTURA' },
974
+ { creatureEntry: NPC.FANKRISS, field: TYPE.FANKRISS, cite: 'temple_of_ahnqiraj.h:15 TYPE_FANKRISS' },
975
+ { creatureEntry: 15299, field: TYPE.VISCIDUS, cite: 'temple_of_ahnqiraj.h:16 TYPE_VISCIDUS' },
976
+ { creatureEntry: NPC.HUHURAN, field: TYPE.HUHURAN, cite: 'temple_of_ahnqiraj.h:17 TYPE_HUHURAN' },
977
+ { creatureEntry: NPC.VEKNILASH, field: TYPE.TWINS, cite: "temple_of_ahnqiraj.h:18 TYPE_TWINS (Vek'nilash 15275 is the primary)" },
978
+ { creatureEntry: NPC.OURO, field: TYPE.OURO, cite: 'temple_of_ahnqiraj.h:19 TYPE_OURO' },
979
+ { creatureEntry: NPC.CTHUN, field: TYPE.CTHUN, cite: "temple_of_ahnqiraj.h:20 TYPE_CTHUN" },
980
+ ],
981
+ cites: [
982
+ 'temple_of_ahnqiraj.cpp whole file',
983
+ 'temple_of_ahnqiraj.h:10-21 MAX_ENCOUNTER 10 - slot 9 is TWINS_INTRO, a pseudo-event',
984
+ ],
985
+ };
986
+
987
+ /** DungeonEncounter.Id → TYPE_* (encounterIndex). Bake type-31 value1s: 715 Twin Emperors, 716 Ouro. */
988
+ const DUNGEON_ENCOUNTER_TYPE: Record<number, number> = {
989
+ 715: TYPE.TWINS,
990
+ 716: TYPE.OURO,
991
+ };
992
+
993
+ /** DungeonEncounter 715 is graph id twin-emperors (Ouro has no graph row). */
994
+ const DUNGEON_ENCOUNTER_DEFEATED: Record<number, string> = {
995
+ 715: 'twin-emperors',
996
+ };
997
+
998
+ /** True when AQ40 SetData is DONE or the graph encounter is defeated. Cite: Conditions.cpp:402-411. */
999
+ export function isCompletedDungeonEncounter(
1000
+ run: {
1001
+ dungeonId?: string;
1002
+ scriptInstanceData?: Record<number, number>;
1003
+ defeated?: string[];
1004
+ } | null | undefined,
1005
+ encounterId: number,
1006
+ ): boolean {
1007
+ if (!run || run.dungeonId !== 'temple-of-ahnqiraj') return false;
1008
+ const field = DUNGEON_ENCOUNTER_TYPE[encounterId];
1009
+ if (field == null) return false;
1010
+ if ((run.scriptInstanceData?.[field] ?? 0) === INSTANCE_DATA.DONE) return true;
1011
+ const graphId = DUNGEON_ENCOUNTER_DEFEATED[encounterId];
1012
+ return graphId != null && (run.defeated ?? []).includes(graphId);
1013
+ }