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,978 @@
1
+ // Peeled from liveDungeonController (S13) — gauntlet/escort — waves, eggs, Mograine, escorts, ally release, Finkle.
2
+ // The live controller context, as much of it as this module reads; tuiFloor.mjs builds one.
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
+ type LiveDungeonCtx = any;
5
+ import type { EncounterDef } from '../data/schema.ts';
6
+ import {
7
+ applyEncounterCleared,
8
+ isCleared,
9
+ floorGauntletWaves,
10
+ hasFlag,
11
+ requiredFlags,
12
+ setFlag,
13
+ } from '../world/instances.ts';
14
+ const sound = { clip: (_name: string): void => {} };
15
+ import { mulberry32 } from '../engine/core/rng.ts';
16
+ import {
17
+ BRD_GORSHAK_JAIL,
18
+ BRD_RIBBLY,
19
+ BRD_RING_OF_LAW,
20
+ materializeRingOfLawEncounter,
21
+ ringOfLawAttemptSeed,
22
+ } from '../data/dungeons/blackrock-depths.ts';
23
+ import {
24
+ UBRS_BEAST,
25
+ UBRS_EMBERSEER,
26
+ UBRS_ROOKERY_EGGS,
27
+ UBRS_SOLAKAR,
28
+ UBRS_STADIUM,
29
+ finkleMaySpawn,
30
+ solakarStartBlockedByDrakkisath,
31
+ ubrsNearestFreeEgg,
32
+ } from '../data/dungeons/ubrs.ts';
33
+ import { LBRS_UROK } from '../data/dungeons/lbrs.ts';
34
+ import { STRATH_BLACK_GUARD } from '../data/dungeons/stratholme-undead.ts';
35
+ import { DM_EAST_PUSILLIN_CHASE, dmEastPusillinCanFight } from '../data/dungeons/dire-maul-east.ts';
36
+ import {
37
+ SCHOLO_GANDLING,
38
+ SCHOLO_KIRTONOS,
39
+ } from '../data/dungeons/scholomance.ts';
40
+ import {
41
+ ZF_BLY,
42
+ ZF_PYRAMID,
43
+ } from '../data/dungeons/zul-farrak.ts';
44
+ import { RAJAXX_ARMY } from '../data/dungeons/ruins-of-ahnqiraj.ts';
45
+ import {
46
+ SM_MOGRAINE_WHITEMANE,
47
+ canScarletResurrect,
48
+ wipeResetPair,
49
+ } from '../data/dungeons/sm-cathedral.ts';
50
+ import {
51
+ MARAUDON_CELEBRAS_RITUAL,
52
+ maraCelebrasCompleteRitual,
53
+ maraCelebrasRitualActive,
54
+ } from '../data/dungeons/maraudon.ts';
55
+ import {
56
+ WILLIX_AMBUSH,
57
+ willixAmbushSpawns,
58
+ } from '../data/dungeons/razorfen-kraul.ts';
59
+ const esc = (s: string): string => String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
60
+ import { canAttackCreature } from '../domain/creature/faction.ts';
61
+ import { findPathForMap, WALK_MAX_VISITED } from '../domain/nav/nav.ts';
62
+ import {
63
+ partyDistTo,
64
+ sameStoreyAsParty,
65
+ placeFloorBody,
66
+ removeFloorEntities,
67
+ spawnGauntletWave,
68
+ summonedBodyGuid,
69
+ } from '../world/continuousDungeon.ts';
70
+ import { getQuest } from '../domain/quests/questlog.ts';
71
+ import {
72
+ escortDefForQuest,
73
+ escortDefs,
74
+ failEscort,
75
+ startEscort,
76
+ tickEscort,
77
+ type EscortDef,
78
+ type EscortWaypoint,
79
+ } from '../world/escort.ts';
80
+ type LiveRouteEditNode = unknown;
81
+
82
+ type RouteEditNode = LiveRouteEditNode;
83
+ type ReachPt = { x: number; y: number; z?: number };
84
+
85
+ export const GAUNTLET_START_YD = 50;
86
+
87
+ export type GauntletEscortApi = Record<string, unknown>;
88
+
89
+ export function installGauntletEscort(ctx: LiveDungeonCtx): GauntletEscortApi {
90
+ // ---- Floor gauntlet: authored `waves` run on the live floor -------------------
91
+ // Flag-gated chains (Ring of Law, Mutanus, Gandling…) arm when their flags are
92
+ // satisfied and START when the party stands at the arm point (ring: arena centre /
93
+ // at_ring_of_law, blackrock_depths.cpp:211 + h:162; else enc.origin). Ungated chains
94
+ // with hostile / bodyless primaries (Grubbis, Mograine, Belnistrasz, Gyth, Fenrus)
95
+ // arm the same way. Ungated + standing non-hostile primary (Doom'rel) stays on the
96
+ // gossip-challenge path: startChallengeGauntletAt gated on targetEncounterId.
97
+ /**
98
+ * Per-transition after calling wave `calledIdx` (0-based).
99
+ * `clearAdvances`: when true, a fully-dead wave skips remaining fromCallMs
100
+ * (Stadium clear-OR-60s). Default false = pure ctx.schedule(Solakar / Gor'shak).
101
+ */
102
+ type GauntletTransition = {
103
+ fromCallMs?: number;
104
+ fromClearMs?: number;
105
+ clearAdvances?: boolean;
106
+ };
107
+ const gauntletTransition = (encId: string, calledIdx: number, waveCount: number): GauntletTransition | null => {
108
+ if (calledIdx + 1 >= waveCount) return null;
109
+ // instance_blackrock_depths.cpp DoCallNextDwarf: m_uiDwarfFightTimer = 30000 (:591).
110
+ if (encId === 'doomrel') return { fromCallMs: 30_000 };
111
+ if (encId === 'ring-of-law') {
112
+ // wave1→wave2 only — blackrock_depths.cpp:459-460 m_uiEventTimer = 16000.
113
+ if (calledIdx === 0) return { fromCallMs: BRD_RING_OF_LAW.mobWaveGapMs };
114
+ // last mob wave→boss from death — blackrock_depths.cpp:318-319 m_uiEventTimer = 5000.
115
+ if (calledIdx === 1) return { fromClearMs: BRD_RING_OF_LAW.bossAfterClearMs };
116
+ }
117
+ // dbscripts_on_quest_start 3982: wave1 @ 3s, wave2 @ 45s → gap 42s after wave1 call.
118
+ if (encId === 'gorshak-jail' && calledIdx === 0) {
119
+ return { fromCallMs: BRD_GORSHAK_JAIL.waveGapMs };
120
+ }
121
+ // instance_blackrock_spire.cpp:701-706 — 30s after waves 0–3, 40s after 4–5.
122
+ if (encId === 'solakar-flamewreath') {
123
+ if (calledIdx < UBRS_SOLAKAR.earlyWaveCount) {
124
+ return { fromCallMs: UBRS_SOLAKAR.waveGapEarlyMs };
125
+ }
126
+ // calledIdx 4–5 → late gap; after Solakar (calledIdx 6) transition is null via waveCount.
127
+ return { fromCallMs: UBRS_SOLAKAR.waveGapLateMs };
128
+ }
129
+ // instance_blackrock_spire.cpp:668-672 + :436-438 — 60s OR clear, add waves only.
130
+ if (encId === 'gyth-rend') {
131
+ if (calledIdx + 1 < UBRS_STADIUM.addWaveCount) {
132
+ return { fromCallMs: UBRS_STADIUM.waveOrClearMs, clearAdvances: true };
133
+ }
134
+ // Last add → Gyth: clear only (timer stops when m_uiStadiumWaves >= MAX).
135
+ return null;
136
+ }
137
+ // dbscripts_on_event 4845 — pure from-call gaps after waves 0–4 (5/13/28/42/58 → 66s).
138
+ if (encId === LBRS_UROK.encId) {
139
+ const gap = LBRS_UROK.waveGapsMs[calledIdx];
140
+ if (gap != null) return { fromCallMs: gap };
141
+ return null;
142
+ }
143
+ // boss_darkmaster_gandling.cpp:57/106 + dbScripts.event delay 2000 —
144
+ // portal rooms (waves 0–5) pure from-call 20s min; last portal → Gandling on clear.
145
+ if (encId === SCHOLO_GANDLING.encId) {
146
+ if (calledIdx < 5) return { fromCallMs: SCHOLO_GANDLING.portalRepeatMinMs };
147
+ return null; // last portal → Gandling when room clears
148
+ }
149
+ // stratholme.cpp:1212 mindless every 400ms (packs of 5 → packGapMs);
150
+ // :718 60s after all mindless dead before Black Guards walk out.
151
+ if (encId === STRATH_BLACK_GUARD.encId) {
152
+ if (calledIdx + 1 < STRATH_BLACK_GUARD.mindlessWaveCount) {
153
+ return { fromCallMs: STRATH_BLACK_GUARD.packGapMs };
154
+ }
155
+ if (calledIdx + 1 === STRATH_BLACK_GUARD.mindlessWaveCount) {
156
+ return { fromClearMs: STRATH_BLACK_GUARD.blackGuardAfterClearMs };
157
+ }
158
+ return null;
159
+ }
160
+ // dbscripts_on_event 2609 — pure from-call gaps after waves 0–1 (10/100/250s).
161
+ // Clear does NOT advance early (instance timer is absolute from unlock).
162
+ if (encId === ZF_PYRAMID.encId) {
163
+ const gap = ZF_PYRAMID.waveGapsMs[calledIdx];
164
+ if (gap != null) return { fromCallMs: gap };
165
+ return null;
166
+ }
167
+ // ruins_of_ahnqiraj.cpp:310/:370 m_armyDelayTimer = 3*MINUTE; clear does not advance.
168
+ if (encId === RAJAXX_ARMY.encId) return { fromCallMs: RAJAXX_ARMY.waveGapMs };
169
+ // Mograine/Whitemane: wave0→1 on clear (fake death); wave1→2 is HP-gated
170
+ // Scarlet Resurrection inject (tickGauntlet tryMograineWhitemaneRes), not schedule.
171
+ // Cite: boss_mograine_and_whitemane.cpp Deep Sleep L475–496 + HandleResurrection.
172
+ if (encId === SM_MOGRAINE_WHITEMANE.encId) {
173
+ return null;
174
+ }
175
+ return null;
176
+ };
177
+ // GAUNTLET_START_YD exported at module scope
178
+ type FloorGauntlet = {
179
+ encId: string;
180
+ /** Materialized encounter (ring rolls); id-keyed lookups still use encId. */
181
+ enc: EncounterDef;
182
+ waves: { entry: number; count: number }[][];
183
+ /** Optional per-wave spawn (ring POS_EAST / POS_NORTH); else enc.origin. */
184
+ waveSpawns?: ({ x: number; y: number; z?: number } | undefined)[];
185
+ /** Next wave index to call. */
186
+ idx: number;
187
+ /** Guids of every called wave member. */
188
+ spawned: number[];
189
+ // Solakar egg layer — hatcher-present clock (cpp:923/936/939). Armed when the first Hatcher wave is
190
+ // called; null = no hatchers yet.
191
+ rookeryHatcherSinceMs?: number | null;
192
+ /** How many egg-hatch ticks have fired this gauntlet. */
193
+ rookeryHatchesDone?: number;
194
+ /** Undo for claimed standing bodies: guid → npcFlags before the claim. */
195
+ claimedPrev: Map<number, number>;
196
+ /** Auto-call deadline while the current wave still stands (tomb 30s, ring wave1→2 16s). */
197
+ nextCallAtMs: number | null;
198
+ /** Post-clear delay for the transition out of the wave just called (ring boss 5s). */
199
+ clearDelayMs: number | null;
200
+ /** runElapsedMs when clear delay elapses; set on first all-dead tick. */
201
+ clearReadyAtMs: number | null;
202
+ /** When true, all-dead skips remaining nextCallAtMs (Stadium clear-OR-timer). */
203
+ clearAdvances: boolean;
204
+ };
205
+
206
+ const callGauntletWave = (): void => {
207
+ if (!ctx.gauntlet) return;
208
+ const enc = ctx.gauntlet.enc;
209
+ const wave = ctx.gauntlet.waves[ctx.gauntlet.idx];
210
+ if (!wave) return;
211
+ const isFinal = ctx.gauntlet.idx === ctx.gauntlet.waves.length - 1;
212
+ // Solakar: always rookeryEventSpawnPos (cpp:99) even if room-snap origin drifts.
213
+ const spawnAt = ctx.gauntlet.waveSpawns?.[ctx.gauntlet.idx]
214
+ ?? (enc.id === 'solakar-flamewreath' ? UBRS_SOLAKAR.spawn : undefined);
215
+ const res = spawnGauntletWave(
216
+ ctx.continuous, enc, wave, ctx.gauntlet.idx, isFinal, spawnAt,
217
+ enc.id === RAJAXX_ARMY.encId ? RAJAXX_ARMY.claimMaxYd : undefined,
218
+ );
219
+ const calledIdx = ctx.gauntlet.idx;
220
+ ctx.gauntlet.idx += 1;
221
+ // Arm rookery egg clock on first wave that includes a Hatcher (cpp:923).
222
+ if (enc.id === 'solakar-flamewreath' && ctx.gauntlet.rookeryHatcherSinceMs == null) {
223
+ const hasHatcher = wave.some((m) => m.entry === UBRS_ROOKERY_EGGS.hatcherEntry);
224
+ if (hasHatcher) {
225
+ ctx.gauntlet.rookeryHatcherSinceMs = ctx.runElapsedMs;
226
+ ctx.gauntlet.rookeryHatchesDone = 0;
227
+ }
228
+ }
229
+ const trans = gauntletTransition(enc.id, calledIdx, ctx.gauntlet.waves.length);
230
+ ctx.gauntlet.nextCallAtMs =
231
+ trans?.fromCallMs != null ? ctx.runElapsedMs + trans.fromCallMs : null;
232
+ ctx.gauntlet.clearDelayMs = trans?.fromClearMs ?? null;
233
+ ctx.gauntlet.clearReadyAtMs = null;
234
+ ctx.gauntlet.clearAdvances = !!trans?.clearAdvances;
235
+ ctx.stampTemplates(res.created);
236
+ for (const e of res.claimed) {
237
+ ctx.gauntlet.claimedPrev.set(e.guid, e.npcFlags);
238
+ e.npcFlags = 0;
239
+ }
240
+ const joined: typeof ctx.continuous.entities = [];
241
+ for (const e of [...res.created, ...res.claimed]) {
242
+ e.hostile = true; // event actor — attacks regardless of template reaction
243
+ ctx.gauntlet.spawned.push(e.guid);
244
+ if (e.state === 'alive') joined.push(e);
245
+ }
246
+ if (joined.length) {
247
+ const names = [...new Set(joined.map((e) => ctx.ds.creature(e.entry)?.name ?? `entry ${e.entry}`))];
248
+ ctx.pushFeed(`<span class="tw-auto-ev"><b>${esc(names.join(', '))}</b> ${joined.length > 1 ? 'join the fight' : 'joins the fight'}</span>`);
249
+ ctx.aggroFloorEntities(joined, { ignoreAcquire: true });
250
+ }
251
+ ctx.saveFloorState();
252
+ };
253
+
254
+ /**
255
+ * Rookery Hatchers disturb eggs → Rookery Whelp 10161.
256
+ * Cite: instance_blackrock_spire.cpp:946-970 nearest unused GO_ROOKERY_EGG within 20 yd
257
+ * of that Hatcher; one egg is one whelp, spawned at the egg. No egg → no whelp.
258
+ * Shared consume with step-on (`go-used:<guid>`). Out of combat: cpp:977 returns early.
259
+ */
260
+ const tickRookeryEggs = (): void => {
261
+ if (!ctx.gauntlet || ctx.gauntlet.encId !== 'solakar-flamewreath') return;
262
+ const since = ctx.gauntlet.rookeryHatcherSinceMs;
263
+ if (since == null) return;
264
+ const run = ctx.game.state.instance;
265
+ if (!run) return;
266
+ const due = ctx.gauntlet.rookeryHatcherDueMs ?? (ctx.gauntlet.rookeryHatcherDueMs = new Map());
267
+ const hatched = (guid: number) => hasFlag(ctx.game.state.instance!, `go-used:${guid}`);
268
+ const inCombat = ctx.inActiveFight();
269
+ const created: typeof ctx.continuous.entities = [];
270
+ let done = ctx.gauntlet.rookeryHatchesDone ?? 0;
271
+ for (const g of ctx.gauntlet.spawned) {
272
+ const e = ctx.continuous.entities.find((x) => x.guid === g);
273
+ if (!e || e.entry !== UBRS_ROOKERY_EGGS.hatcherEntry || e.state !== 'alive') continue;
274
+ if (!inCombat && !ctx.continuous.engagedGuids.includes(e.guid)) continue;
275
+ if (!due.has(g)) due.set(g, since + UBRS_ROOKERY_EGGS.firstHatchAfterCallMs);
276
+ if (ctx.runElapsedMs < due.get(g)!) continue;
277
+ const egg = ubrsNearestFreeEgg(hatched, e);
278
+ if (!egg) continue;
279
+ ctx.game.state.instance = setFlag(ctx.game.state.instance!, `go-used:${egg.guid}`);
280
+ due.set(g, ctx.runElapsedMs + UBRS_ROOKERY_EGGS.nextHatchMs);
281
+ const guid = summonedBodyGuid(`solakar-egg#${egg.guid}`);
282
+ if (ctx.continuous.entities.some((x) => x.guid === guid)) continue;
283
+ const ent = {
284
+ guid,
285
+ entry: UBRS_ROOKERY_EGGS.whelpEntry,
286
+ x: egg.x,
287
+ y: egg.y,
288
+ z: egg.z ?? e.z,
289
+ state: 'alive' as const,
290
+ detectionRange: 18,
291
+ level: 18,
292
+ movementType: 0,
293
+ npcFlags: 0,
294
+ hostile: true,
295
+ };
296
+ ctx.continuous.entities.push(ent);
297
+ created.push(ent);
298
+ ctx.gauntlet.spawned.push(guid);
299
+ done += 1;
300
+ }
301
+ ctx.gauntlet.rookeryHatchesDone = done;
302
+ if (created.length) {
303
+ ctx.stampTemplates(created);
304
+ ctx.pushFeed(
305
+ `<span class="tw-auto-ev"><b>Rookery Whelps</b> hatch from disturbed eggs `
306
+ + `(${UBRS_ROOKERY_EGGS.disturbSpellId})!</span>`,
307
+ );
308
+ ctx.aggroFloorEntities(created, { ignoreAcquire: true });
309
+ ctx.saveFloorState();
310
+ }
311
+ };
312
+
313
+ const startGauntlet = (enc: EncounterDef): boolean => {
314
+ const run = ctx.game.state.instance;
315
+ if (ctx.gauntlet || !run || ctx.stopped || isCleared(run, enc.id)) return false;
316
+ // instance_blackrock_spire.cpp:774-778 — Drakkisath DONE permanently locks rookery.
317
+ if (enc.id === 'solakar-flamewreath' && solakarStartBlockedByDrakkisath(run.flags ?? [])) {
318
+ return false;
319
+ }
320
+ // Sticky per-attempt rolls (LOCK 4 — same seed as beginEncounter via ringOfLawAttemptSeed).
321
+ const rng = mulberry32(ringOfLawAttemptSeed(enc.id, ctx.continuous.clearedGuids.length));
322
+ const mat = materializeRingOfLawEncounter(enc, () => rng.next());
323
+ const waves = floorGauntletWaves(mat);
324
+ if (!waves?.length) return false;
325
+ // Ring: mobs POS_EAST, boss POS_NORTH — blackrock_depths.cpp:191-192, :459/:502.
326
+ const waveSpawns = enc.id === 'ring-of-law'
327
+ ? [BRD_RING_OF_LAW.mobSpawn, BRD_RING_OF_LAW.mobSpawn, BRD_RING_OF_LAW.bossSpawn]
328
+ : enc.id === 'gyth-rend'
329
+ ? [
330
+ ...Array.from({ length: UBRS_STADIUM.addWaveCount }, () => UBRS_STADIUM.waveSpawn),
331
+ UBRS_STADIUM.gythSpawn,
332
+ ]
333
+ : undefined;
334
+ // Gor'shak: delay first wave 3s (dbscripts_on_quest_start 3982 delay 3000).
335
+ // Emberseer: delay boss spawn growFullMs (spell 16048 duration / 20×3s stacks).
336
+ // Black Guard: first mindless after 500ms (stratholme.cpp:312).
337
+ // Urok: first wave at 5s (dbscripts_on_event 4845 delay 5000).
338
+ const delayFirstMs = enc.id === 'gorshak-jail'
339
+ ? BRD_GORSHAK_JAIL.wave1AtMs
340
+ : enc.id === 'pyroguard-emberseer'
341
+ ? UBRS_EMBERSEER.growFullMs
342
+ : enc.id === STRATH_BLACK_GUARD.encId
343
+ ? STRATH_BLACK_GUARD.firstMindlessMs
344
+ : enc.id === LBRS_UROK.encId
345
+ ? LBRS_UROK.firstWaveAtMs
346
+ // dbscripts_on_go_use brazier 175564 delay 5000 → Kirtonos.
347
+ : enc.id === SCHOLO_KIRTONOS.encId
348
+ ? SCHOLO_KIRTONOS.firstWaveAtMs
349
+ // first portal guardians @ cast 16s + DB 2s (cpp:57 + dbScripts delay).
350
+ : enc.id === SCHOLO_GANDLING.encId
351
+ ? SCHOLO_GANDLING.firstPortalGuardiansAtMs
352
+ // dbscripts_on_event 2609 delay 10000 → pyramid wave 1.
353
+ : enc.id === ZF_PYRAMID.encId
354
+ ? ZF_PYRAMID.firstWaveAtMs
355
+ : 0;
356
+ ctx.gauntlet = {
357
+ encId: enc.id,
358
+ enc: mat,
359
+ waves,
360
+ waveSpawns,
361
+ idx: 0,
362
+ spawned: [],
363
+ claimedPrev: new Map(),
364
+ nextCallAtMs: delayFirstMs > 0 ? ctx.runElapsedMs + delayFirstMs : null,
365
+ clearDelayMs: null,
366
+ clearReadyAtMs: null,
367
+ clearAdvances: false,
368
+ rookeryHatcherSinceMs: null,
369
+ rookeryHatchesDone: 0,
370
+ rookeryHatcherDueMs: new Map(),
371
+ };
372
+ ctx.pushFeed(`<span class="tw-auto-ev"><b>${esc(enc.name)}</b> - the event begins</span>`);
373
+ if (delayFirstMs <= 0) callGauntletWave();
374
+ return true;
375
+ };
376
+
377
+ ctx.startGauntlet = startGauntlet;
378
+ /** Quest 3982 accept (or active log) starts the jail defense gauntlet. */
379
+ const tryStartGorshakJail = (): boolean => {
380
+ const run = ctx.game.state.instance;
381
+ if (!run || ctx.stopped || ctx.gauntlet) return false;
382
+ if (isCleared(run, 'gorshak-jail')) return false;
383
+ const st = getQuest(ctx.game.state.questlog, BRD_GORSHAK_JAIL.questId);
384
+ if (!st || st.status === 'turnedIn' || st.explored === true) return false;
385
+ const enc = ctx.def.encounters.find((e) => e.id === 'gorshak-jail');
386
+ if (!enc || !floorGauntletWaves(enc)) return false;
387
+ return startGauntlet(enc);
388
+ };
389
+
390
+ const gauntletSpawnedDead = (): boolean => {
391
+ if (!ctx.gauntlet) return false;
392
+ // [].every is true — empty spawned after a failed first call then dumped every
393
+ // remaining stadium wave in one tick (T3 one-shots wave 0, clearAdvances fires 1..7).
394
+ if (!ctx.gauntlet.spawned.length) return false;
395
+ return ctx.gauntlet.spawned.every((g) => {
396
+ const e = ctx.continuous.entities.find((x) => x.guid === g);
397
+ return !e || e.state === 'dead';
398
+ });
399
+ };
400
+
401
+ ctx.tickGauntlet = (): void => {
402
+ const run = ctx.game.state.instance;
403
+ if (!run || ctx.stopped) return;
404
+ if (!ctx.gauntlet) {
405
+ if (ctx.runElapsedMs - ctx.lastGauntletScanMs < 1_500) return;
406
+ ctx.lastGauntletScanMs = ctx.runElapsedMs;
407
+ for (const enc of ctx.def.encounters) {
408
+ if (isCleared(run, enc.id)) continue;
409
+ const need = requiredFlags(enc);
410
+ // Flag-gated chains still wait for flags; ungated chains may arm too.
411
+ if (need.some((f) => !hasFlag(run, f))) continue;
412
+ if (!floorGauntletWaves(enc)) continue;
413
+ // Emberseer stands from mount (guid 2290394). Growing is liveFloorState, not a
414
+ // gauntlet spawn — starting waves here synthesized a second 9816.
415
+ if (enc.id === 'pyroguard-emberseer') continue;
416
+ // Gor'shak: quest-accept only (dbscripts_on_quest_start 3982) — never walk-by.
417
+ if (enc.id === 'gorshak-jail') {
418
+ tryStartGorshakJail();
419
+ continue;
420
+ }
421
+ // Ungated + standing non-hostile primary = gossip challenge (Doom'rel).
422
+ // That path is startChallengeGauntletAt gated on targetEncounterId so walking
423
+ // past never starts the tomb. Cite: boss_doomrel gossip → TYPE_TOMB_OF_SEVEN.
424
+ if (!need.length) {
425
+ const pe = enc.creatureEntry ?? 0;
426
+ if (pe > 0 && ctx.continuous.entities.some((e) =>
427
+ e.entry === pe && e.state === 'alive' && !e.hostile)) continue;
428
+ }
429
+ // Ring arms at arena centre (areatrigger), not POS_NORTH — blackrock_depths.h:162.
430
+ // Stadium arms at AT 2026 (r=20), not aStadiumLocs[2] — a 50 yd centre circle
431
+ // starts the gauntlet on a southern-edge drop (trashbot.md / cpp:808-823).
432
+ const arm = enc.id === 'ring-of-law' ? BRD_RING_OF_LAW.arenaCenter
433
+ : enc.id === 'gyth-rend' ? UBRS_STADIUM.at2026
434
+ : enc.origin;
435
+ if (!arm || !Number.isFinite(arm.x)) continue;
436
+ const armZ = enc.id === 'ring-of-law' ? BRD_RING_OF_LAW.mobSpawn.z : arm.z;
437
+ const armYd = enc.id === 'gyth-rend' ? UBRS_STADIUM.at2026.radius : GAUNTLET_START_YD;
438
+ if (enc.id === 'ring-of-law' && !sameStoreyAsParty(ctx.continuous, armZ)) continue;
439
+ if (enc.id === 'gyth-rend' && !sameStoreyAsParty(ctx.continuous, armZ)) continue;
440
+ if (partyDistTo(ctx.continuous, arm.x, arm.y, armZ) > armYd) continue;
441
+ // Bare primary from spawnUnlockedBodies blocks final-wave credit guid.
442
+ // Also strip flag-gated leftovers (Kirtonos used to abort here and stay unfightable).
443
+ const g = summonedBodyGuid(enc.id);
444
+ if (ctx.continuous.entities.some((e) => e.guid === g)) {
445
+ // Through the world writer: a hand-replaced `entities` leaves `nearIndexed`
446
+ // counting a body that is gone, which strands it in the near grid and skips the
447
+ // next appends. Cite: continuousDungeon.ts removeFloorEntities; E1.2.
448
+ removeFloorEntities(ctx.continuous, (e) => e.guid !== g);
449
+ ctx.continuous.clearedGuids = ctx.continuous.clearedGuids.filter((x) => x !== g);
450
+ }
451
+ if (startGauntlet(enc)) return;
452
+ }
453
+ return;
454
+ }
455
+ if (ctx.gauntlet.idx >= ctx.gauntlet.waves.length) {
456
+ if (gauntletSpawnedDead()) ctx.gauntlet = null; // credit lands via the route loop
457
+ return;
458
+ }
459
+ // Whitemane ≤50% → Scarlet Resurrection Mograine inject (mid-fight concurrent).
460
+ if (tryMograineWhitemaneRes()) return;
461
+ // Solakar hatchers → continuous egg whelps (cpp:923/936/939).
462
+ tickRookeryEggs();
463
+ if (gauntletSpawnedDead()) {
464
+ // Pure ctx.schedule(tomb 30s, solakar 30/40s, gorshak 42s, emberseer grow): wait the
465
+ // full fromCall even if the current wave died early. Stadium clearAdvances skips
466
+ // that wait so clear-OR-60s matches instance_blackrock_spire.cpp:436-438.
467
+ if (
468
+ !ctx.gauntlet.clearAdvances
469
+ && ctx.gauntlet.nextCallAtMs != null
470
+ && ctx.runElapsedMs < ctx.gauntlet.nextCallAtMs
471
+ ) return;
472
+ // Ring boss: wait clearDelayMs from last death (cpp:318-319); else immediate.
473
+ if (ctx.gauntlet.clearDelayMs != null && ctx.gauntlet.clearDelayMs > 0) {
474
+ if (ctx.gauntlet.clearReadyAtMs == null) {
475
+ ctx.gauntlet.clearReadyAtMs = ctx.runElapsedMs + ctx.gauntlet.clearDelayMs;
476
+ }
477
+ if (ctx.runElapsedMs >= ctx.gauntlet.clearReadyAtMs) callGauntletWave();
478
+ return;
479
+ }
480
+ callGauntletWave();
481
+ return;
482
+ }
483
+ if (ctx.gauntlet.nextCallAtMs != null && ctx.runElapsedMs >= ctx.gauntlet.nextCallAtMs) {
484
+ callGauntletWave();
485
+ }
486
+ };
487
+
488
+ /**
489
+ * Arriving at an explicitly TARGETED boss whose body stands non-hostile:
490
+ * - waves authored (Doom'rel) → the gossip challenge, run the gauntlet;
491
+ * - plain neutral named (Ribbly, Plugger, Bly after pyramid) → attack-to-start, flip + engage.
492
+ * Gated on targetEncounterId so walking PAST the bar never starts a fight.
493
+ * Flag-gated non-wave bosses (Bly) unlock when requiresFlag is satisfied.
494
+ * Cite: dbscripts_on_gossip 94101 → faction 14 @ +6s (ZF_BLY); boss_doomrel gossip.
495
+ */
496
+ const startChallengeGauntletAt = (): boolean => {
497
+ const run = ctx.game.state.instance;
498
+ if (!run || !ctx.targetEncounterId) return false;
499
+ const enc = ctx.def.encounters.find((e) => e.id === ctx.targetEncounterId);
500
+ if (!enc || enc.kind !== 'boss' || isCleared(run, enc.id)) return false;
501
+ // Pusillin: gossip chase only — never challenge-flip before 5th stop.
502
+ // Cite: dbscripts_on_gossip 570905 sets faction 90; earlier stages keep gossip.
503
+ if (
504
+ ctx.def.id === 'dire-maul-east'
505
+ && enc.id === DM_EAST_PUSILLIN_CHASE.encId
506
+ && !dmEastPusillinCanFight(run.flags ?? [])
507
+ ) return false;
508
+ const need = requiredFlags(enc);
509
+ if (need.some((f) => !hasFlag(run, f))) return false;
510
+ // Flag-gated wave chains arm on walk-in (tickGauntlet), not challenge gossip.
511
+ if (need.length && floorGauntletWaves(enc)) return false;
512
+ const primaryGuids = ctx.guidsForFloorEncounter(enc);
513
+ const primary = ctx.continuous.entities.find((e) =>
514
+ primaryGuids.includes(e.guid) && e.state === 'alive' && !e.hostile);
515
+ if (!primary || partyDistTo(ctx.continuous, primary.x, primary.y, primary.z) > 12) return false;
516
+ if (floorGauntletWaves(enc)) return !ctx.gauntlet && startGauntlet(enc);
517
+ // Friendly-to-all templates can never be flipped (Unit::CanAttack — reaction < FRIENDLY), except
518
+ // where a gossip script sets the faction: Bly 7604 (94101) and Ribbly 9543 (197001).
519
+ if (
520
+ enc.id !== ZF_BLY.encId
521
+ && enc.id !== BRD_RIBBLY.encId
522
+ && !canAttackCreature(ctx.ds, ctx.game.state.char.race, primary.entry)
523
+ ) return false;
524
+ primary.hostile = true;
525
+ primary.npcFlags = 0;
526
+ // Bly crew ride-along (Raven/Oro/Murta) — dbscripts 94101 sets faction 14 on all four.
527
+ if (enc.id === ZF_BLY.encId) {
528
+ for (const e of ctx.continuous.entities) {
529
+ if (e.state !== 'alive') continue;
530
+ if (!(ZF_BLY.crewEntries as readonly number[]).includes(e.entry)) continue;
531
+ e.hostile = true;
532
+ e.npcFlags = 0;
533
+ }
534
+ }
535
+ // Ribbly's three cronies turn with him — 197001 names them by guid (data_flags 16).
536
+ if (enc.id === BRD_RIBBLY.encId) {
537
+ for (const e of ctx.continuous.entities) {
538
+ if (e.state !== 'alive') continue;
539
+ if (!(BRD_RIBBLY.cronyGuids as readonly number[]).includes(e.guid)) continue;
540
+ e.hostile = true;
541
+ e.npcFlags = 0;
542
+ }
543
+ }
544
+ return ctx.aggroFloorEntities([primary]);
545
+ };
546
+
547
+ /**
548
+ * Wipe: the event FAILS. Synthesized actors despawn (their guids scrubbed from
549
+ * clear credit so a retry respawns them); claimed ghosts stand back down.
550
+ * Cite: instance_blackrock_depths.cpp SetData FAIL → respawn all seven, round 0.
551
+ * SM cathedral: instance_scarlet_monastery.cpp FAIL → SetRespawnDelay(30) pair
552
+ * re-arm — wipeResetPair; never permanently dead (probe negative).
553
+ */
554
+ const resetGauntletOnWipe = (): void => {
555
+ if (!ctx.gauntlet) return;
556
+ if (ctx.gauntlet.encId === SM_MOGRAINE_WHITEMANE.encId) {
557
+ const mogAlive = ctx.gauntlet.spawned.some((g) => {
558
+ const e = ctx.continuous.entities.find((x) => x.guid === g);
559
+ return e?.entry === SM_MOGRAINE_WHITEMANE.mograineEntry && e.state !== 'dead';
560
+ });
561
+ const whiAlive = ctx.gauntlet.spawned.some((g) => {
562
+ const e = ctx.continuous.entities.find((x) => x.guid === g);
563
+ return e?.entry === SM_MOGRAINE_WHITEMANE.whitemaneEntry && e.state !== 'dead';
564
+ });
565
+ const wr = wipeResetPair({ mograineAlive: mogAlive, whitemaneAlive: whiAlive });
566
+ const delayS = wr.respawnDelayMs / 1000;
567
+ ctx.pushFeed(
568
+ `<span class="tw-auto-ev"><b>Mograine & Whitemane</b> - wipe (${wr.encounterState}`
569
+ + `${delayS > 0 ? `, respawn ${delayS}s` : ''}). The pair is not permanently dead.</span>`,
570
+ );
571
+ }
572
+ const created = new Set(ctx.gauntlet.spawned.filter((g) => !ctx.gauntlet!.claimedPrev.has(g)));
573
+ // Same reason as the bare-primary drop above: the grid has to be rebuilt with the array.
574
+ removeFloorEntities(ctx.continuous, (e) => !created.has(e.guid));
575
+ ctx.continuous.clearedGuids = ctx.continuous.clearedGuids.filter((g) => !created.has(g));
576
+ for (const [guid, npcFlags] of ctx.gauntlet.claimedPrev) {
577
+ const e = ctx.continuous.entities.find((x) => x.guid === guid);
578
+ if (e && e.state !== 'dead') {
579
+ e.npcFlags = npcFlags;
580
+ ctx.stampTemplates([e]); // reaction back from the template (tomb ghosts → friendly)
581
+ }
582
+ }
583
+ ctx.gauntlet = null;
584
+ };
585
+
586
+ /**
587
+ * Whitemane ≤50% → Deep Sleep + Scarlet Resurrection injects Mograine while she
588
+ * still lives (wave 2). Negative: never if Mograine wave-0 is still alive.
589
+ * Cite: boss_mograine_and_whitemane.cpp:475-496 / :423-443; canScarletResurrect.
590
+ */
591
+ const tryMograineWhitemaneRes = (): boolean => {
592
+ if (!ctx.gauntlet || ctx.gauntlet.encId !== SM_MOGRAINE_WHITEMANE.encId) return false;
593
+ // After wave0+wave1 called (idx===2), before final Mograine res inject (idx becomes 3).
594
+ if (ctx.gauntlet.idx !== 2) return false;
595
+
596
+ const mograineAlive = ctx.gauntlet.spawned.some((g) => {
597
+ const e = ctx.continuous.entities.find((x) => x.guid === g);
598
+ return !!e
599
+ && e.entry === SM_MOGRAINE_WHITEMANE.mograineEntry
600
+ && e.state !== 'dead';
601
+ });
602
+
603
+ // Resolve Whitemane HP% from the live session (fallback 100 if not engaged yet).
604
+ let whitemaneHpPct = 100;
605
+ let foundWhitemane = false;
606
+ for (const g of ctx.gauntlet.spawned) {
607
+ const e = ctx.continuous.entities.find((x) => x.guid === g);
608
+ if (!e || e.entry !== SM_MOGRAINE_WHITEMANE.whitemaneEntry || e.state === 'dead') continue;
609
+ foundWhitemane = true;
610
+ const side = ctx.floorSideOfGuid(g);
611
+ if (side && ctx.currentSession) {
612
+ // One store read (E1.1). This scanned the view array for the seat, having already
613
+ // stopped parsing the digits out of `enemy_3` to index by them.
614
+ const v = ctx.currentSession.viewOfSide?.(side);
615
+ if (v && v.maxHp > 0) {
616
+ whitemaneHpPct = (100 * v.hp) / v.maxHp;
617
+ }
618
+ }
619
+ break;
620
+ }
621
+ if (!foundWhitemane) return false;
622
+
623
+ if (!canScarletResurrect({
624
+ mograineAlive,
625
+ whitemaneHpPct,
626
+ alreadyResurrected: false, // idx===2 means final res wave not called yet
627
+ })) return false;
628
+
629
+ ctx.pushFeed(
630
+ `<span class="tw-auto-ev"><b>High Inquisitor Whitemane</b> casts Deep Sleep `
631
+ + `(${SM_MOGRAINE_WHITEMANE.spellDeepSleep}) and Scarlet Resurrection `
632
+ + `(${SM_MOGRAINE_WHITEMANE.spellScarletResurrection})!</span>`,
633
+ );
634
+ callGauntletWave(); // final wave — Mograine inject; Whitemane stays in spawned
635
+ ctx.pushFeed(
636
+ `<span class="tw-auto-ev"><b>Scarlet Commander Mograine</b> rises - both fight together!</span>`,
637
+ );
638
+ return true;
639
+ };
640
+
641
+ /**
642
+ * Boss death releases an allied boss: Emperor down → Princess Moira turns neutral
643
+ * and evades; her encounter credits as "saved" so the run still completes. Killing
644
+ * her FIRST (the loot run) still credits normally and skips the release.
645
+ * Cite: boss_emperor_dagran_thaurissan.cpp:70-89 — SetFactionTemporary(FACTION_NEUTRAL
646
+ * 734) + EnterEvadeMode on the Princess when the Emperor dies.
647
+ */
648
+ const RELEASE_ON_DEATH: Record<string, { allyEncId: string; feed: string }> = {
649
+ 'emperor-dagran-thaurissan': {
650
+ allyEncId: 'princess-moira',
651
+ feed: 'Princess Moira Bronzebeard turns neutral as the Emperor falls!',
652
+ },
653
+ };
654
+ const standDownAlly = (allyEnc: EncounterDef): void => {
655
+ for (const g of allyEnc.spawnGuids ?? []) {
656
+ const e = ctx.continuous.entities.find((x) => x.guid === g);
657
+ if (!e || e.state === 'dead') continue;
658
+ const side = ctx.floorSideOfGuid(g);
659
+ if (side && ctx.currentSession && typeof ctx.currentSession.disengageEnemySides === 'function') {
660
+ ctx.currentSession.disengageEnemySides([side]);
661
+ // Both directions, inside the un-bind.
662
+ ctx.unbindFloorSide(side);
663
+ }
664
+ ctx.continuous.engagedGuids = ctx.continuous.engagedGuids.filter((x) => x !== g);
665
+ e.state = 'alive';
666
+ e.hostile = false;
667
+ e.npcFlags = 2; // questgiver again — she ends The Royal Rescue / Fate of the Kingdom
668
+ }
669
+ };
670
+ /**
671
+ * Densify sparse escort polylines with map nav (Kernobee has 2 sourced endpoints;
672
+ * Willix/Belnistrasz already have dense script_waypoint rows). Intermediate points
673
+ * keep unique high point ids so credit/ambush hooks still match authored ids.
674
+ * Cite: findPathForMap; never invent endpoints.
675
+ */
676
+ const densifyEscortDef = (
677
+ base: EscortDef,
678
+ start: { x: number; y: number; z?: number },
679
+ ): EscortDef => {
680
+ const anchors: EscortWaypoint[] = [
681
+ { point: 0, x: start.x, y: start.y, z: start.z },
682
+ ...base.waypoints,
683
+ ];
684
+ const dense: EscortWaypoint[] = [];
685
+ let synth = 10_000;
686
+ for (let i = 1; i < anchors.length; i++) {
687
+ const a = anchors[i - 1]!;
688
+ const b = anchors[i]!;
689
+ const segYd = Math.hypot(b.x - a.x, b.y - a.y);
690
+ // Only path-expand long gaps (sparse follower routes). Dense WPs stay as authored.
691
+ if (segYd > 20) {
692
+ const via = findPathForMap(
693
+ ctx.def.mapId,
694
+ { x: a.x, y: a.y, z: a.z },
695
+ { x: b.x, y: b.y, z: b.z },
696
+ undefined,
697
+ { maxVisited: WALK_MAX_VISITED },
698
+ );
699
+ if (via && via.length > 2) {
700
+ for (let j = 1; j < via.length - 1; j++) {
701
+ const p = via[j]!;
702
+ dense.push({ point: synth++, x: p.x, y: p.y, z: p.z ?? b.z });
703
+ }
704
+ }
705
+ }
706
+ dense.push(b);
707
+ }
708
+ if (dense.length <= base.waypoints.length) return base;
709
+ return { ...base, waypoints: dense };
710
+ };
711
+
712
+ /**
713
+ * Lane F5: when an escort quest is accepted (or already in log at mount), start the
714
+ * authored waypoint run for that NPC. Pure path in escort.ts; here we mirror pose +
715
+ * densify sparse routes + credit via finishEscort (recordEventHappens).
716
+ */
717
+ const tryStartFloorEscort = (questId: number, preferGuid?: number): boolean => {
718
+ if (ctx.floorEscort && (ctx.floorEscort.status === 'active' || ctx.floorEscort.status === 'paused')) {
719
+ return false;
720
+ }
721
+ const eDef = escortDefForQuest(questId, ctx.def.mapId);
722
+ if (!eDef || eDef.instanceId !== ctx.def.id) return false;
723
+ // Prefer the NPC the player just talked to (multiple Kernobee spawns).
724
+ let npc = preferGuid != null
725
+ ? ctx.continuous.entities.find((e) => e.guid === preferGuid && e.entry === eDef.npcEntry)
726
+ : undefined;
727
+ if (!npc || npc.state === 'dead') {
728
+ npc = ctx.continuous.entities.find(
729
+ (e) => e.entry === eDef.npcEntry && e.state !== 'dead',
730
+ );
731
+ }
732
+ if (!npc) return false;
733
+ const start = { x: npc.x, y: npc.y, z: npc.z };
734
+ const liveDef = densifyEscortDef(eDef, start);
735
+ ctx.floorEscortDef = liveDef;
736
+ ctx.floorEscort = startEscort({
737
+ def: liveDef,
738
+ npcGuid: npc.guid,
739
+ start,
740
+ });
741
+ // Drop questgiver flag while escorting (ScriptDev clears UNIT_NPC_FLAG_QUESTGIVER
742
+ // on accept; restored at credit WP). Cite: razorfen_kraul.cpp:148 + WP46 SetFlag.
743
+ npc.npcFlags = 0;
744
+ ctx.pushFeed(
745
+ `<span class="tw-auto-ev">Escort started: <b>${esc(ctx.ds.quest(questId)?.title ?? String(questId))}</b></span>`,
746
+ );
747
+ return true;
748
+ };
749
+
750
+ /** Resume any active escort quest already in the log (re-mount / continue). */
751
+ const resumeFloorEscortsFromLog = (): void => {
752
+ for (const d of escortDefs()) {
753
+ if (d.instanceId !== ctx.def.id || d.mapId !== ctx.def.mapId) continue;
754
+ const st = getQuest(ctx.game.state.questlog, d.questId);
755
+ if (!st || st.status === 'turnedIn') continue;
756
+ // Already credited — no need to re-walk.
757
+ if (st.explored === true) continue;
758
+ if (tryStartFloorEscort(d.questId)) break;
759
+ }
760
+ };
761
+
762
+ // Maraudon 7046 — finish Celebras RP after sourced path+wait budget. Cite: dbscripts_on_quest_start
763
+ // 7046 + movement 1371601–03 → gossip restored.
764
+ const tickCelebrasRitual = (): void => {
765
+ if (ctx.celebrasRitualStartedAtMs == null || ctx.def.id !== 'maraudon') return;
766
+ const run = ctx.game.state.instance;
767
+ if (!run || !maraCelebrasRitualActive(run.flags ?? [])) {
768
+ ctx.celebrasRitualStartedAtMs = null;
769
+ return;
770
+ }
771
+ if (ctx.runElapsedMs - ctx.celebrasRitualStartedAtMs < MARAUDON_CELEBRAS_RITUAL.completeAfterMs) {
772
+ return;
773
+ }
774
+ const next = maraCelebrasCompleteRitual(run.flags ?? []);
775
+ if (!next) {
776
+ ctx.celebrasRitualStartedAtMs = null;
777
+ return;
778
+ }
779
+ ctx.game.state.instance = { ...run, flags: next };
780
+ ctx.celebrasRitualStartedAtMs = null;
781
+ ctx.pushFeed(
782
+ `<span class="tw-auto-ev"><b>Celebras the Redeemed</b> says: "`
783
+ + `${esc(MARAUDON_CELEBRAS_RITUAL.says.whole.text)}" - scepter ritual complete `
784
+ + `(turn in quest ${MARAUDON_CELEBRAS_RITUAL.questId}).</span>`,
785
+ );
786
+ sound.clip('questcomplete');
787
+ ctx.saveFloorState();
788
+ ctx.persist();
789
+ };
790
+
791
+ const tickFloorEscort = (dtMs: number): void => {
792
+ if (!ctx.floorEscort || ctx.stopped) return;
793
+ if (ctx.floorEscort.status === 'done' || ctx.floorEscort.status === 'failed') return;
794
+ const eDef = ctx.floorEscortDef ?? escortDefForQuest(ctx.floorEscort.questId, ctx.def.mapId);
795
+ if (!eDef) return;
796
+
797
+ // Abandon fails the escort. Cite: ScriptDev escort AI ends when quest is gone.
798
+ const st = getQuest(ctx.game.state.questlog, ctx.floorEscort.questId);
799
+ if (!st) {
800
+ ctx.floorEscort = failEscort(ctx.floorEscort, 'abandoned');
801
+ const ent = ctx.continuous.entities.find((e) => e.guid === ctx.floorEscort!.npcGuid);
802
+ if (ent) ent.npcFlags = 2;
803
+ ctx.pushFeed(`<span class="tw-auto-ev">Escort failed (quest abandoned)</span>`);
804
+ sound.clip('questfailed');
805
+ return;
806
+ }
807
+
808
+ ctx.partyWorldFromSession();
809
+ const { run: next, events } = tickEscort(ctx.floorEscort, eDef, dtMs, {
810
+ partyPos: { x: ctx.continuous.party.x, y: ctx.continuous.party.y },
811
+ });
812
+ ctx.floorEscort = next;
813
+ const ent = ctx.continuous.entities.find((e) => e.guid === next.npcGuid);
814
+ if (ent) {
815
+ placeFloorBody(ctx.continuous, ent, next.x, next.y, next.z);
816
+ }
817
+ for (const ev of events) {
818
+ if (ev.kind === 'ambush') {
819
+ ctx.pushFeed(
820
+ `<span class="tw-auto-ev">Escort ambush at waypoint ${ev.point}!</span>`,
821
+ );
822
+ // Willix WP15/45 → 2× Raging Agam'ar at aBoarSpawn. Cite: razorfen_kraul.cpp:104-120.
823
+ if (
824
+ ctx.def.id === 'razorfen-kraul'
825
+ && (ev.point === 15 || ev.point === 45)
826
+ ) {
827
+ const spawns = willixAmbushSpawns(ev.point as 15 | 45);
828
+ let n = 0;
829
+ for (let i = 0; i < spawns.length; i++) {
830
+ const s = spawns[i]!;
831
+ const guid = summonedBodyGuid(`willix-ambush-${ev.point}.${i}`);
832
+ if (ctx.continuous.entities.some((e) => e.guid === guid)) continue;
833
+ ctx.continuous.entities.push({
834
+ guid,
835
+ entry: s.entry,
836
+ x: s.x,
837
+ y: s.y,
838
+ z: s.z,
839
+ state: 'alive',
840
+ detectionRange: 20,
841
+ level: 25,
842
+ movementType: 0,
843
+ npcFlags: 0,
844
+ hostile: true,
845
+ });
846
+ n += 1;
847
+ }
848
+ if (n > 0) {
849
+ ctx.pushFeed(
850
+ `<span class="tw-auto-ev"><b>${n}× Raging Agam'ar</b> ambush Willix `
851
+ + `(entry ${WILLIX_AMBUSH.entry})!</span>`,
852
+ );
853
+ }
854
+ }
855
+ } else if (ev.kind === 'credit') {
856
+ const res = ctx.game.finishEscort(ev.questId);
857
+ if (res.ok) {
858
+ ctx.pushFeed(
859
+ `<span class="tw-auto-ev">Escort complete: <b>${esc(ctx.ds.quest(ev.questId)?.title ?? String(ev.questId))}</b></span>`,
860
+ );
861
+ sound.clip('questcomplete');
862
+ }
863
+ // Restore questgiver for turn-in. Cite: razorfen_kraul.cpp:124 SetFlag QUESTGIVER.
864
+ // Kernobee turns in to Scooty outside; flag restore is harmless.
865
+ if (ent) ent.npcFlags = 2;
866
+ } else if (ev.kind === 'paused') {
867
+ // Quiet — player is out of range; no spam.
868
+ } else if (ev.kind === 'done') {
869
+ ctx.saveFloorState();
870
+ ctx.persist();
871
+ } else if (ev.kind === 'failed') {
872
+ ctx.pushFeed(`<span class="tw-auto-ev">Escort failed</span>`);
873
+ sound.clip('questfailed');
874
+ if (ent) ent.npcFlags = 2;
875
+ }
876
+ }
877
+ };
878
+
879
+ const tickAllyRelease = (): void => {
880
+ const run = ctx.game.state.instance;
881
+ if (!run) return;
882
+ for (const [bossId, rel] of Object.entries(RELEASE_ON_DEATH)) {
883
+ if (ctx.releasedAllies.has(bossId)) continue;
884
+ const bossEnc = ctx.def.encounters.find((e) => e.id === bossId);
885
+ const allyEnc = ctx.def.encounters.find((e) => e.id === rel.allyEncId);
886
+ if (!bossEnc || !allyEnc) {
887
+ ctx.releasedAllies.add(bossId); // not this dungeon
888
+ continue;
889
+ }
890
+ if (isCleared(run, rel.allyEncId)) {
891
+ // Saved on a prior mount (or slain first): stand her down silently post-rebuild.
892
+ standDownAlly(allyEnc);
893
+ ctx.releasedAllies.add(bossId);
894
+ continue;
895
+ }
896
+ const bossGuids = ctx.guidsForFloorEncounter(bossEnc);
897
+ if (!bossGuids.length) continue;
898
+ const session = ctx.currentSession;
899
+ const bossDead = bossGuids.every((g) => {
900
+ const e = ctx.continuous.entities.find((x) => x.guid === g);
901
+ if (!e) return false;
902
+ if (e.state === 'dead') return true;
903
+ if (e.state === 'engaged') {
904
+ const side = ctx.floorSideOfGuid(g);
905
+ const v = side != null ? session?.viewOfSide?.(side) : undefined;
906
+ return !!v && !(v.hp > 0);
907
+ }
908
+ return false;
909
+ });
910
+ if (!bossDead) continue;
911
+ ctx.releasedAllies.add(bossId);
912
+ standDownAlly(allyEnc);
913
+ ctx.game.state.instance = applyEncounterCleared(ctx.game.state.instance!, allyEnc);
914
+ ctx.pushFeed(`<span class="tw-auto-ev">${esc(rel.feed)}</span>`);
915
+ ctx.saveFloorState();
916
+ ctx.persist();
917
+ }
918
+ };
919
+
920
+ // The Beast dead → Finkle Einhorn 10776 (spell 16710). Cite: instance_blackrock_spire.cpp
921
+ // OnCreatureDespawn :488-491. Negative: never spawn unless beast is dead (finkleMaySpawn).
922
+ const tickFinkleSpawn = (): void => {
923
+ if (ctx.finkleSpawned || ctx.def.id !== 'ubrs') return;
924
+ const run = ctx.game.state.instance;
925
+ if (!run) return;
926
+ const beastDead = isCleared(run, 'the-beast');
927
+ if (!finkleMaySpawn(beastDead)) return;
928
+ if (ctx.continuous.entities.some((e) => e.entry === UBRS_BEAST.finkleEntry && e.state !== 'dead')) {
929
+ ctx.finkleSpawned = true;
930
+ return;
931
+ }
932
+ const beastEnc = ctx.def.encounters.find((e) => e.id === 'the-beast');
933
+ const o = beastEnc?.origin ?? UBRS_BEAST.introLocs[0]!;
934
+ const guid = summonedBodyGuid('ubrs-finkle');
935
+ if (ctx.continuous.entities.some((e) => e.guid === guid)) {
936
+ ctx.finkleSpawned = true;
937
+ return;
938
+ }
939
+ ctx.continuous.entities.push({
940
+ guid,
941
+ entry: UBRS_BEAST.finkleEntry,
942
+ x: o.x,
943
+ y: o.y,
944
+ ...(o.z != null && Number.isFinite(o.z) ? { z: o.z } : {}),
945
+ state: 'alive',
946
+ detectionRange: 18,
947
+ level: 60,
948
+ movementType: 0,
949
+ npcFlags: 1, // gossip — flavor NPC
950
+ hostile: false,
951
+ });
952
+ ctx.finkleSpawned = true;
953
+ ctx.pushFeed(
954
+ `<span class="tw-auto-ev"><b>Finkle Einhorn</b> climbs out of the Beast `
955
+ + `(spell ${UBRS_BEAST.finkleSpellId})!</span>`,
956
+ );
957
+ ctx.saveFloorState();
958
+ };
959
+
960
+ ctx.gauntletTransition = gauntletTransition;
961
+ ctx.callGauntletWave = callGauntletWave;
962
+ ctx.tickRookeryEggs = tickRookeryEggs;
963
+ ctx.startGauntlet = startGauntlet;
964
+ ctx.tryStartGorshakJail = tryStartGorshakJail;
965
+ ctx.gauntletSpawnedDead = gauntletSpawnedDead;
966
+ ctx.startChallengeGauntletAt = startChallengeGauntletAt;
967
+ ctx.resetGauntletOnWipe = resetGauntletOnWipe;
968
+ ctx.tryMograineWhitemaneRes = tryMograineWhitemaneRes;
969
+ ctx.standDownAlly = standDownAlly;
970
+ ctx.densifyEscortDef = densifyEscortDef;
971
+ ctx.tryStartFloorEscort = tryStartFloorEscort;
972
+ ctx.resumeFloorEscortsFromLog = resumeFloorEscortsFromLog;
973
+ ctx.tickCelebrasRitual = tickCelebrasRitual;
974
+ ctx.tickFloorEscort = tickFloorEscort;
975
+ ctx.tickAllyRelease = tickAllyRelease;
976
+ ctx.tickFinkleSpawn = tickFinkleSpawn;
977
+ return { gauntletTransition, callGauntletWave, tickRookeryEggs, startGauntlet, tryStartGorshakJail, gauntletSpawnedDead, startChallengeGauntletAt, resetGauntletOnWipe, tryMograineWhitemaneRes, standDownAlly, densifyEscortDef, tryStartFloorEscort, resumeFloorEscortsFromLog, tickCelebrasRitual, tickFloorEscort, tickAllyRelease, tickFinkleSpawn };
978
+ }