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,1121 @@
1
+ // Pure spell-effect resolution plus item trigger routing: on-use, on-equip and chance-on-hit take the
2
+ // same resolver. It never invents an effect and never rolls without an injected rng.
3
+
4
+ import type { ItemDef, Mechanic, SpellDef, SpellEffect, BuffMod } from '../../../data/schema.ts';
5
+ import type { Rng } from '../../core/rng.ts';
6
+ import type { ProcEventContext } from '../procs.ts';
7
+ import { MECHANIC_ID } from '../../../domain/creature/creatureAiConstants.ts';
8
+ import {
9
+ EFFECT_HANDLERS,
10
+ createHandlerState,
11
+ finalizeResult,
12
+ } from './handlers.ts';
13
+
14
+ /** SharedDefines Mechanics id → name (inverse of MECHANIC_ID). */
15
+ const MECHANIC_NAME_FROM_ID: Readonly<Record<number, Mechanic>> = Object.freeze(
16
+ Object.fromEntries(
17
+ Object.entries(MECHANIC_ID)
18
+ .filter(([, id]) => id != null && id > 0)
19
+ .map(([name, id]) => [id as number, name as Mechanic]),
20
+ ),
21
+ );
22
+ import {
23
+ buildProcTriggerSpellMeta,
24
+ resolveProcTriggerSpellId,
25
+ tryProcTriggerSpell,
26
+ type ProcTriggerSpellMeta,
27
+ } from './proc.ts';
28
+ import { effectAmountRange } from './amount.ts';
29
+ import {
30
+ applyWeaponImbueKit,
31
+ applyWeaponImbueKitFromItemEnchant,
32
+ weaponImbueHasCombatKit,
33
+ } from './weapon-imbue-kit.ts';
34
+ import { SPELL_ATTR_EX2, hasAttrEx2 } from '../spellAttributes.ts';
35
+ // The extracted enchantment table. The resolver fills thin weapon-imbue rows from it so poisons,
36
+ // stones and oils work without re-running the docker-only enricher. Cite: extract-item-enchants.mjs.
37
+ import itemEnchantsTable from '../../../data/tables/itemEnchants.json' with { type: 'json' };
38
+
39
+ // Baked roles no effect payload can imply, so role inference never returns them: the two auto-attack
40
+ // toggles, the tame channel, and the pet heal — which must be rescued or combat heals the owner.
41
+ const NON_DERIVABLE_ROLES: ReadonlySet<string> = new Set(['shoot', 'attack', 'pet_tame', 'pet_heal']);
42
+ import {
43
+ SPELL_AURA_PROC_TRIGGER_SPELL,
44
+ SPELL_EFFECT_APPLY_AURA,
45
+ } from './opcodes.ts';
46
+ import type { InterpretContext, InterpretResult } from './types.ts';
47
+ import {
48
+ materializeOverrideClassScriptIntents,
49
+ materializeSpellModIntents,
50
+ talentScriptedEffects,
51
+ talentScriptedAppendEffects,
52
+ } from './talent-scripted.ts';
53
+ import { materializePaladinSeal, sealMaterializedEffects } from './paladin-seals.ts';
54
+ import {
55
+ applyExecuteRageToEffects,
56
+ materializeWarriorDruidKitEffects,
57
+ } from './warrior-druid-kit.ts';
58
+ import { materializeHunterKitEffects } from './hunter-kit.ts';
59
+ import { materializePriestWarlockKitEffects } from './priest-warlock-kit.ts';
60
+ import { materializePaladinKitEffects } from './paladin-kit.ts';
61
+ import { applyFormAttrPatch } from './form-attrs.ts';
62
+ import { materializeAuraRemoveEffects } from './handlers/aura-remove.ts';
63
+ import { liftConsumeEnergyIntents } from './lift-consume-energy.ts';
64
+ import {
65
+ materializeMissingSpeedFromRaw,
66
+ stampMissingSpeedFromRaw,
67
+ } from './materialize-speed.ts';
68
+ import {
69
+ materializeMissingRatingBuffsFromRaw,
70
+ stampMissingRatingBuffsFromRaw,
71
+ } from './materialize-rating-buffs.ts';
72
+ import {
73
+ materializeMissingCharmFromRaw,
74
+ stampMissingCharmFromRaw,
75
+ } from './materialize-charm.ts';
76
+ import { withHostile } from './targeting.ts';
77
+ import { materializeDispelMechanicIntents } from './materialize-dispel-mechanic.ts';
78
+ import { materializeSpellMagnetIntents } from './materialize-spell-magnet.ts';
79
+
80
+ // Local interpret entry (same body as index.interpretSpell) — avoids circular import with index.ts
81
+ // re-exports of this module.
82
+ function interpretSpellLocal(spell: SpellDef, ctx: InterpretContext = {}): InterpretResult {
83
+ const resolvedCtx: InterpretContext = {
84
+ ...ctx,
85
+ spellLevel:
86
+ ctx.spellLevel
87
+ ?? (ctx.casterLevel != null ? (spell.spellLevel ?? spell.reqLevel ?? 0) : undefined),
88
+ };
89
+ const state = createHandlerState(spell, resolvedCtx);
90
+ const rawList = spell.rawEffects;
91
+ if (!rawList || rawList.length === 0) {
92
+ return finalizeResult(state);
93
+ }
94
+ for (let slot = 0; slot < rawList.length; slot++) {
95
+ const raw = rawList[slot]!;
96
+ const effect = raw.effect | 0;
97
+ if (!effect) continue;
98
+ const handler = EFFECT_HANDLERS[effect];
99
+ if (!handler) {
100
+ state.unhandled.push({
101
+ slot,
102
+ effect,
103
+ auraName: raw.auraName | 0,
104
+ reason: `unhandled effect ${effect} (SI3+)`,
105
+ });
106
+ continue;
107
+ }
108
+ const before = state.effects.length;
109
+ handler(state, raw, slot);
110
+ // Stamp the DBC slot on everything this handler appended — the coefficient index.
111
+ // Same stamp as index.interpretSpell; this is the copy the combat path actually calls.
112
+ for (let i = before; i < state.effects.length; i++) {
113
+ const e = state.effects[i]!;
114
+ if (e.effectSlot == null) e.effectSlot = slot;
115
+ }
116
+ }
117
+ return finalizeResult(state);
118
+ }
119
+
120
+ /** Spell id → SpellDef lookup (DataStore.spell / combatant spell list). */
121
+ export type SpellLookup = (id: number) => SpellDef | undefined | null;
122
+
123
+ /** ItemDef.procs row shape (FI2 bake). */
124
+ export type ItemProcRow = NonNullable<ItemDef['procs']>[number];
125
+
126
+ export interface ResolveSpellEffectsOpts extends InterpretContext {
127
+ // Force interpreter even when the SI gate is off. SI5 default already prefers interpreter when rawEffects
128
+ // exist.
129
+ forceInterpreter?: boolean;
130
+ }
131
+
132
+ /** True when bake synthesized no usable SpellEffect list. */
133
+ export function isBakeEffectsEmpty(spell: SpellDef): boolean {
134
+ return !spell.effects || spell.effects.length === 0;
135
+ }
136
+
137
+ // Catalog materializer for a hollow baked effect list that still has raw effects. Allowlisted opcodes
138
+ // only: a full-catalog materialize would flip rotation's "empty bake means skip the keep-up" gate.
139
+ const FILL_EMPTY_EFFECT_OPCODES = new Set([
140
+ 2, // SCHOOL_DAMAGE
141
+ 3, // SPELL_EFFECT_DUMMY — Holy Shock parent ranks (materializePaladinKit)
142
+ 5, // SPELL_EFFECT_TELEPORT_UNITS
143
+ 8, // POWER_DRAIN
144
+ 9, // HEALTH_LEECH (Death Coil)
145
+ 10, // HEAL
146
+ 17, // WEAPON_DAMAGE_NOSCHOOL (Heroic Strike / Overpower)
147
+ 22, // SPELL_EFFECT_PARRY — Parry 3127 SetCanParry; KI-818
148
+ 23, // SPELL_EFFECT_BLOCK — Block 107 SetCanBlock
149
+ 28, // SUMMON (pet family)
150
+ 31, // WEAPON_PERCENT_DAMAGE
151
+ 33, // SPELL_EFFECT_OPEN_LOCK — Pick Lock 1804 / Opening (catalog + OOC; KI-613)
152
+ 38, // SPELL_EFFECT_DISPEL — Cleanse / Cure / Remove Curse
153
+ 41, // SPELL_EFFECT_SUMMON_WILD
154
+ 50, // SPELL_EFFECT_TRANS_DOOR — mage capital Portals only materialize teleport (handleTransDoor)
155
+ 56, // SUMMON_PET
156
+ 58, // WEAPON_DAMAGE
157
+ 59, // SPELL_EFFECT_OPEN_LOCK_ITEM — shared EffectOpenLock with 33
158
+ 64, // TRIGGER_SPELL
159
+ 67, // HEAL_MAX_HEALTH (Lay on Hands)
160
+ 69, // SPELL_EFFECT_DISTRACT
161
+ 71, // SPELL_EFFECT_PICKPOCKET
162
+ 95, // SPELL_EFFECT_SKINNING — 8613/8617/8618/10768; KI must-impl #18
163
+ 99, // SPELL_EFFECT_DISENCHANT — Disenchant 13262 / 10694 (PT); KI must-impl #18
164
+ 73, // SUMMON_POSSESSED (Eye of Kilrogg)
165
+ 77, // SCRIPT_EFFECT (healthstone / friend-heal)
166
+ 112, // SUMMON_DEMON (Inferno)
167
+ 121, // NORMALIZED_WEAPON_DMG
168
+ ]);
169
+ /** Aura opcodes safe to materialize on the catalog surface. */
170
+ const FILL_EMPTY_AURA_OPCODES = new Set([
171
+ 1, // SPELL_AURA_BIND_SIGHT (Mind Vision)
172
+ 4, // SPELL_AURA_DUMMY — seals / VE / soulstone / scripted holders (resolveCombatSpell kits)
173
+ 5, // MOD_CONFUSE / polymorph (higher ranks)
174
+ 2, // SPELL_AURA_MOD_POSSESS — Mind Control; KI-801 family
175
+ 6, // SPELL_AURA_MOD_CHARM — Enslave Demon / Dominate Mind; KI-801
176
+ 177, // SPELL_AURA_AOE_CHARM — TakeCharmOf advertised=false; HandleAoECharm :2348
177
+ 7, // SPELL_AURA_MOD_FEAR — creature/player fear (Terrify 7399); KI-448
178
+ 9, // MOD_ATTACKSPEED
179
+ 10, // MOD_THREAT (Blessing of Salvation / Greater)
180
+ 13, // MOD_DAMAGE_DONE (Tiger's Fury)
181
+ 14, // MOD_DAMAGE_TAKEN (Blessing of Sanctuary)
182
+ 15, // DAMAGE_SHIELD (Thorns / Retribution)
183
+ 17, // SPELL_AURA_MOD_STEALTH_DETECT (Catseye Elixir) — KI-593 catalog surface
184
+ 18, // SPELL_AURA_MOD_INVISIBILITY (Lesser/Greater Invis pots) — KI-592
185
+ 19, // SPELL_AURA_MOD_INVISIBILITY_DETECTION (Detect Lesser/Greater Invisibility)
186
+ 22, // MOD_RESISTANCE
187
+ 23, // PERIODIC_TRIGGER_SPELL
188
+ 28, // SPELL_AURA_REFLECT_SPELLS (Sheen of Zanza when bake drops parent aura) — KI-625
189
+ 29, // MOD_STAT
190
+ 31, // MOD_INCREASE_SPEED (Dash / Ghost Wolf)
191
+ 32, // MOD_INCREASE_MOUNTED_SPEED
192
+ 33, // MOD_DECREASE_SPEED
193
+ 36, // MOD_SHAPESHIFT
194
+ 42, // PROC_TRIGGER_SPELL
195
+ 44, // SPELL_AURA_TRACK_CREATURES (Detect Undead / Beast) — KI-592
196
+ 45, // TRACK_RESOURCES (Find Treasure)
197
+ 47, // MOD_PARRY_PERCENT
198
+ 49, // MOD_DODGE_PERCENT
199
+ 51, // MOD_BLOCK_PERCENT (Shield Block / Holy Shield)
200
+ 52, // MOD_CRIT_PERCENT
201
+ 56, // TRANSFORM (Polymorph variants)
202
+ 65, // MOD_CASTING_SPEED
203
+ 67, // MOD_DISARM
204
+ 68, // SPELL_AURA_MOD_STALKED — track flag (Hunter's Mark effect 1); KI-849
205
+ 69, // SPELL_AURA_SCHOOL_ABSORB — PW:S / Fire Ward / Frost Ward; KI-426
206
+ 77, // MECHANIC_IMMUNITY (Fear Ward)
207
+ 78, // MOUNTED (Warhorse / Felsteed)
208
+ 79, // MOD_DAMAGE_PERCENT_DONE (Power Infusion)
209
+ 80, // SPELL_AURA_MOD_PERCENT_STAT (BoK)
210
+ 82, // SPELL_AURA_WATER_BREATHING (Water Breathing / Unending Breath)
211
+ 91, // SPELL_AURA_MOD_DETECT_RANGE (Mind Soothe)
212
+ 93, // MOD_UNATTACKABLE (Phase Shift)
213
+ 97, // SPELL_AURA_MANA_SHIELD — Mana Shield ranks; KI-423
214
+ 98, // SPELL_AURA_MOD_SKILL_TALENT — racial weapon/eng skill (Gun/Axe/Sword/Mace Spec, Eng Spec)
215
+ 99, // MOD_ATTACK_POWER
216
+ 100, // SPELL_AURA_AURAS_VISIBLE (Detect Magic)
217
+ 104, // SPELL_AURA_WATER_WALK (Water Walking)
218
+ 105, // FEATHER_FALL
219
+ 107, // ADD_FLAT_MODIFIER → next_cast_mod (Inner Focus / Combustion)
220
+ 108, // ADD_PCT_MODIFIER → next_cast_mod
221
+ 110, // SPELL_AURA_MOD_POWER_REGEN_PERCENT — Evocation / Innervate; KI-424
222
+ 88, // SPELL_AURA_MOD_HEALTH_REGEN_PERCENT — Troll Regeneration OOC +10%; KI-876
223
+ 116, // SPELL_AURA_MOD_REGEN_DURING_COMBAT — Troll Regeneration combat 10%; KI-876
224
+ 117, // SPELL_AURA_MOD_MECHANIC_RESISTANCE — Orc Hardiness stun resist
225
+ 127, // SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS — Hunter's Mark +RAP; KI-849
226
+ 134, // SPELL_AURA_MOD_MANA_REGEN_INTERRUPT — channel full spirit (Evocation/Innervate)
227
+ 136, // MOD_HEALING_DONE_PERCENT (Power Infusion)
228
+ 137, // SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE (GBK)
229
+ 138, // MOD_MELEE_HASTE (Curse of Tongues)
230
+ 144, // SAFE_FALL
231
+ 149, // SPELL_AURA_RESIST_PUSHBACK — Concentration Aura 19746 (35%); Barkskin uses same aura
232
+ 153, // SPELL_AURA_SPLIT_DAMAGE_FLAT — Blessing of Sacrifice; KI-821
233
+ 155, // MOD_WATER_BREATHING (Undead racial)
234
+ 156, // SPELL_AURA_MOD_REPUTATION_GAIN — Human Diplomacy
235
+ 165, // SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS — melee twin of 127
236
+ 168, // SPELL_AURA_MOD_DAMAGE_DONE_VERSUS — Beast Slaying / Echoes; KI-875
237
+ 30, // SPELL_AURA_MOD_SKILL — equip/temp skill auras (same surface as 98)
238
+ ]);
239
+
240
+ /** Blessing of Sanctuary ranks — empty effects[] + aura 14/43; catalog must match combat (KI-180). */
241
+ const FILL_EMPTY_SPELL_IDS = new Set([20911, 20912, 20913, 20914, 25899]);
242
+
243
+ export function fillEmptyEffectsFromRaw(
244
+ spell: SpellDef,
245
+ ctx: ResolveSpellEffectsOpts = {},
246
+ ): SpellDef {
247
+ if (!isBakeEffectsEmpty(spell)) return spell;
248
+ const raw = spell.rawEffects;
249
+ if (!raw?.length) return spell;
250
+ const eligible = FILL_EMPTY_SPELL_IDS.has(spell.id | 0) || raw.some((r) => {
251
+ const eff = r.effect | 0;
252
+ const aura = r.auraName | 0;
253
+ return FILL_EMPTY_EFFECT_OPCODES.has(eff) || FILL_EMPTY_AURA_OPCODES.has(aura);
254
+ });
255
+ if (!eligible) return spell;
256
+ const resolved = resolveCombatSpell(spell, ctx);
257
+ if (!resolved.effects.length) return spell;
258
+ // Warriors never use combo points — DBC ATTR_EX_FINISH on Overpower is not NeedsComboPoints.
259
+ // Cite: SpellMgr.h NeedsComboPoints energy/rogue finishers; KI-569.
260
+ if (resolved.requiresComboPoints && resolved.powerType === 'rage') {
261
+ const out = { ...resolved };
262
+ delete (out as { requiresComboPoints?: boolean }).requiresComboPoints;
263
+ delete (out as { finishingScalesDamage?: boolean }).finishingScalesDamage;
264
+ return out;
265
+ }
266
+ return resolved;
267
+ }
268
+
269
+ // The interpreter gate, kept local to avoid a circular import. Read once: the env lookup goes through
270
+ // a V8 interceptor and ran per spell resolution per cast — 2.3% of a 40-unit tick profile.
271
+ const ENV_INTERPRETER_OFF = typeof process !== 'undefined'
272
+ && process.env?.PHONECRAFT_SI_INTERPRETER === '0';
273
+ function interpreterGateOn(ctx?: InterpretContext): boolean {
274
+ if (ctx?.useInterpreter === false) return false;
275
+ if (ctx?.useInterpreter === true) return true;
276
+ return !ENV_INTERPRETER_OFF;
277
+ }
278
+
279
+ // Resolve spell effects for the combat and item paths: raw effects with the gate on are interpreted,
280
+ // otherwise the baked list stands. No Math.random or wall clock — callers pass an injected rng.
281
+ export function resolveSpellEffects(
282
+ spell: SpellDef,
283
+ ctx: ResolveSpellEffectsOpts = {},
284
+ ): InterpretResult {
285
+ const rawLen = spell.rawEffects?.length ?? 0;
286
+ const preferInterp =
287
+ ctx.forceInterpreter === true ||
288
+ (rawLen > 0 && interpreterGateOn(ctx));
289
+
290
+ if (preferInterp && rawLen > 0) {
291
+ const { forceInterpreter: _f, ...rest } = ctx;
292
+ return interpretSpellLocal(spell, { ...rest, useInterpreter: true });
293
+ }
294
+
295
+ return {
296
+ effects: spell.effects ? spell.effects.slice() : [],
297
+ unhandled: [],
298
+ ...(spell.strikeBonus != null ? { strikeBonus: spell.strikeBonus } : {}),
299
+ };
300
+ }
301
+
302
+ // Spell ids whose hollow effect list hid the duration-scale surface. Mass-filling every hollow spell
303
+ // belongs to its own lane, since it re-classifies situational CC as a rotation keep-up.
304
+ export const DURATION_SURFACE_HOLLOW_SPELL_IDS: ReadonlySet<number> = new Set([
305
+ // Turn Undead — creature 19725 (20s di=18), player ranks 2878 (10s di=1), 10326 (20s di=18)
306
+ 19725, 2878, 10326, 5627,
307
+ // Rapid Fire 3045 — 15s di=8
308
+ 3045,
309
+ // Volley ranks — 6s di=32 (often already filled; materialize is no-op then)
310
+ 1510, 14294, 14295, 14296,
311
+ // Creature Psychic Scream 13704 — same 6s di=32 pattern as KI-152 notes
312
+ 13704,
313
+ ]);
314
+
315
+ // Fill a bake-hollow effect list in place from the raw effects, for the duration-surface ids only:
316
+ // combat re-resolves, but data-store consumers and repros read the effect list for its duration.
317
+ export function materializeHollowSpellsInPlace(
318
+ spells: Iterable<SpellDef>,
319
+ ctx: ResolveSpellEffectsOpts = {},
320
+ opts: { onlyIds?: ReadonlySet<number> } = {},
321
+ ): number {
322
+ const only = opts.onlyIds ?? DURATION_SURFACE_HOLLOW_SPELL_IDS;
323
+ let n = 0;
324
+ for (const spell of spells) {
325
+ if (!only.has(spell.id | 0)) continue;
326
+ if (spell.passive) continue;
327
+ if (!isBakeEffectsEmpty(spell)) continue;
328
+ if (!(spell.rawEffects?.length)) continue;
329
+ const resolved = resolveCombatSpell(spell, ctx);
330
+ if (!resolved.effects.length) continue;
331
+ spell.effects = resolved.effects.map((e) => ({ ...e }));
332
+ if (resolved.role && !spell.role) spell.role = resolved.role;
333
+ if (resolved.strikeBonus != null && spell.strikeBonus == null) {
334
+ spell.strikeBonus = resolved.strikeBonus;
335
+ }
336
+ if (resolved.rageGenerated != null && spell.rageGenerated == null) {
337
+ spell.rageGenerated = resolved.rageGenerated;
338
+ }
339
+ if (resolved.aoe != null && spell.aoe == null) spell.aoe = resolved.aoe;
340
+ n += 1;
341
+ }
342
+ return n;
343
+ }
344
+
345
+ // The combat materializer: a SpellDef with effects and strike bonus from the interpreter when raw
346
+ // effects exist. A shallow copy, so the bake row is not mutated; without raw it returns the input.
347
+ export function resolveCombatSpell(
348
+ spell: SpellDef,
349
+ ctx: ResolveSpellEffectsOpts = {},
350
+ ): SpellDef {
351
+ if (!interpreterGateOn(ctx)) {
352
+ // Still stamp form attrs (notShapeshift / costPct) — independent of effect opcodes.
353
+ return applyFormAttrPatch(spell);
354
+ }
355
+
356
+ const rawLen = spell.rawEffects?.length ?? 0;
357
+ // Scripted talent residuals, the port of the talent-actives enricher. Filled only when the baked
358
+ // effects are empty, so a hand-built fixture or an already-resolved def is never clobbered.
359
+ const scripted = talentScriptedEffects(spell.id);
360
+
361
+ if (rawLen === 0) {
362
+ if (scripted && isBakeEffectsEmpty(spell)) {
363
+ return applyFormAttrPatch({ ...spell, effects: scripted.map((e) => ({ ...e })) });
364
+ }
365
+ return applyFormAttrPatch(spell);
366
+ }
367
+
368
+ const result = resolveSpellEffects(spell, { ...ctx, forceInterpreter: true });
369
+ let effects = result.effects.slice();
370
+ // Prefer the concrete scripted effects when the generic path left the list empty. Deep Wounds
371
+ // materializes intermediate dummy triggers that the C++ rewrites, so keep the holder.
372
+ if (
373
+ scripted
374
+ && (
375
+ effects.length === 0
376
+ || scripted.some((e) =>
377
+ e.kind === 'deep_wounds'
378
+ || e.kind === 'pyroclasm'
379
+ || e.kind === 'sweeping_strikes'
380
+ // C++ rewrites these dummy/proc holders (generic aura-42 would double-fire without the gate).
381
+ // Cite: UnitAuraProcHandler.cpp Cheat Death 28845; Adaptive Warding 28764; set/talent s20.
382
+ || e.kind === 'cheat_death'
383
+ || e.kind === 'adaptive_warding'
384
+ || e.kind === 'class_power_set'
385
+ || e.kind === 'vestments_greater_heal'
386
+ || e.kind === 'dreamwalker_healing_touch'
387
+ || e.kind === 'idol_healing_touch_refund'
388
+ || e.kind === 'totem_lesser_healing_wave'
389
+ || e.kind === 'master_of_elements'
390
+ || e.kind === 'magic_absorption'
391
+ || e.kind === 'oracle_healing_bonus'
392
+ || e.kind === 'obsidian_armor'
393
+ || e.kind === 'eye_for_an_eye'
394
+ || e.kind === 'ignite'
395
+ // Aura 109 Improved Sprint stays scripted so generic add_target_trigger does not replace it.
396
+ // Cite: Spell.cpp:7433–7468; SpellEffects.cpp:4140–4147 case 30918.
397
+ || e.kind === 'improved_sprint'
398
+ // Vampiric Embrace and Demonic Sacrifice leave a bare holder on the generic path, so the
399
+ // scripted payload is kept or the pickers classify them as utility rather than castable.
400
+ || e.kind === 'vampiric_embrace'
401
+ || e.kind === 'demonic_sacrifice',
402
+ )
403
+ )
404
+ ) {
405
+ effects = scripted.map((e) => ({ ...e }));
406
+ }
407
+ {
408
+ // Combustion and kin: the DBC slots are real, so the C++ payload rides alongside them.
409
+ const extra = talentScriptedAppendEffects(spell.id);
410
+ if (extra?.length) {
411
+ const have = new Set(effects.map((e) => e.kind));
412
+ effects = [...effects, ...extra.filter((e) => !have.has(e.kind))];
413
+ }
414
+ }
415
+ // Runtime speed merge: when the bake dropped a speed aura the raw effects still carry, append it to
416
+ // both the resolved list and the shared bake row, so inspection sees the snare without a re-bake.
417
+ effects = materializeMissingSpeedFromRaw(spell, effects);
418
+ stampMissingSpeedFromRaw(spell);
419
+ // Second-slot rating buffs (Mongoose crit aura 52) when bake only mapped the first aura.
420
+ // Cite: materialize-rating-buffs.ts; KI-591.
421
+ effects = materializeMissingRatingBuffsFromRaw(spell, effects);
422
+ stampMissingRatingBuffsFromRaw(spell);
423
+ // Charm/possess (Enslave Demon / Mind Control) when bake only mapped the haste rider.
424
+ // Cite: materialize-charm.ts; SpellAuras HandleModCharm; KI-801.
425
+ effects = materializeMissingCharmFromRaw(spell, effects);
426
+ stampMissingCharmFromRaw(spell);
427
+ // Will of the Forsaken and Escape Artist: the seed layers stamp a cleanse for the control-breaker
428
+ // path, which the mechanic-immunity interpretation would drop, so it is merged back.
429
+ {
430
+ const bakeCleanses = (spell.effects ?? []).filter((e) => e.kind === 'cleanse');
431
+ if (bakeCleanses.length > 0 && !effects.some((e) => e.kind === 'cleanse')) {
432
+ effects = [...bakeCleanses.map((e) => ({ ...e })), ...effects];
433
+ }
434
+ }
435
+ // Spell-mod residuals such as a free cost or a crit bonus become a next-cast modifier, rank-generic
436
+ // from the intents. The scripted table wins above when it has a row.
437
+ effects = materializeSpellModIntents(result.intents, effects, spell);
438
+ effects = materializeOverrideClassScriptIntents(result.intents, effects, spell);
439
+ // The Orc Command racial is a permanent 5% pet damage buff, and the generic modifier materialize
440
+ // turns it into a 15-second self buff — the wrong target and the wrong duration.
441
+ if (spell.id === 20575 || spell.id === 20576) {
442
+ let amount = 5;
443
+ for (const r of spell.rawEffects ?? []) {
444
+ const aura = r.auraName | 0;
445
+ if (aura !== 107 && aura !== 108) continue;
446
+ const { min } = effectAmountRange(r, ctx);
447
+ if (min !== 0) { amount = min; break; }
448
+ }
449
+ effects = [{
450
+ kind: 'buff',
451
+ mod: 'damage_done_pct',
452
+ amount,
453
+ durationMs: 0,
454
+ applyTo: 'pet',
455
+ }];
456
+ }
457
+ // A resistance-percent intent on a physical mask becomes a live armor buff or debuff, and hostility
458
+ // comes from targetA: without the flag, Death Wish's own -20% armor read as a foe debuff.
459
+ for (const intent of result.intents ?? []) {
460
+ if (intent.kind !== 'mod_resistance_pct') continue;
461
+ if ((intent.schoolMask & 1) === 0) continue; // armor is the physical bit only
462
+ const rawSlot = (spell.rawEffects ?? []).find(
463
+ (r) => r.effect === 6 && r.auraName === 101,
464
+ );
465
+ const tgtA = (rawSlot?.targetA ?? 0) | 0;
466
+ effects.push(withHostile(
467
+ {
468
+ kind: 'buff' as const,
469
+ mod: 'armor_pct' as const,
470
+ amount: intent.amount,
471
+ durationMs: intent.durationMs,
472
+ },
473
+ tgtA,
474
+ intent.amount,
475
+ ));
476
+ }
477
+
478
+ // SESSION 3 — Warrior/Druid kit: block%, cleanse, Retaliation, Barkskin, FR, Execute.
479
+ // Cite: warrior-druid-kit.ts; SPELL-FIDELITY-RUNSHEET SESSION 3.
480
+ effects = materializeWarriorDruidKitEffects(spell, result, effects);
481
+ effects = materializeDispelMechanicIntents(result.intents, effects);
482
+ effects = materializeSpellMagnetIntents(result.intents, effects, spell);
483
+ if (ctx.rage != null) {
484
+ effects = applyExecuteRageToEffects(spell, effects, ctx.rage);
485
+ }
486
+
487
+ // SESSION 4 — Hunter kit: traps (armed proc), Feign Death, Aspect of the Beast.
488
+ // Cite: hunter-kit.ts; SPELL-FIDELITY-RUNSHEET SESSION 4.
489
+ effects = materializeHunterKitEffects(spell, result, effects);
490
+
491
+ // SESSION 5 — Priest/Warlock kit: Life Tap (health→mana), Lightwell ranks.
492
+ // Cite: priest-warlock-kit.ts; Warlock.cpp LifeTap; SPELL-FIDELITY-RUNSHEET SESSION 5.
493
+ effects = materializePriestWarlockKitEffects(spell, result, effects);
494
+
495
+ // SESSION 11 — Paladin kit: Blessing of Sacrifice / Light / Concentration Aura.
496
+ // Cite: paladin-kit.ts; SPELL-FIDELITY-RUNSHEET SESSION 11.
497
+ effects = materializePaladinKitEffects(spell, result, effects);
498
+
499
+ // Paladin seals replace their dummy and proc shells with a real seal effect so the active seal arms.
500
+ // Cite: paladin-seals.ts; enrich-paladin-seals.mjs.
501
+ const sealFx = materializePaladinSeal(spell);
502
+ if (sealFx) effects = sealMaterializedEffects(sealFx, spell, effects);
503
+
504
+ // Preserve a totem's ability kit through re-resolution: the handler emits only the slot, creature,
505
+ // health and duration, while the kit comes from the creature spell list.
506
+ for (let i = 0; i < effects.length; i++) {
507
+ const e = effects[i]!;
508
+ if (e.kind !== 'summon_totem') continue;
509
+ const bake = (spell.effects ?? []).find(
510
+ (be) => be.kind === 'summon_totem'
511
+ && be.creature === e.creature
512
+ && be.slot === e.slot,
513
+ );
514
+ if (!bake || bake.kind !== 'summon_totem') continue;
515
+ const hasKit = !!(bake.abilities && bake.abilities.length);
516
+ const hasTrigs = !!(bake.triggerAbilities && bake.triggerAbilities.length);
517
+ if (!hasKit && !hasTrigs && !bake.name) continue;
518
+ effects[i] = {
519
+ ...e,
520
+ ...(bake.name ? { name: bake.name } : {}),
521
+ ...(hasKit
522
+ ? { abilities: bake.abilities!.map((a) => ({ ...a, effects: a.effects.map((x) => ({ ...x })) })) }
523
+ : {}),
524
+ // The trigger abilities must survive re-resolution too, or every periodic totem loses its
525
+ // payload the moment combat re-resolves the spell and goes back to summoning a decoration.
526
+ ...(hasTrigs
527
+ ? { triggerAbilities: bake.triggerAbilities!.map((a) => ({ ...a, effects: a.effects.map((x) => ({ ...x })) })) }
528
+ : {}),
529
+ };
530
+ }
531
+
532
+ // Weapon imbue: prefer the offline kit, then merge the richer baked fields, then fill from the
533
+ // extracted enchantment table — so re-resolving never strips the combat payload.
534
+ for (let i = 0; i < effects.length; i++) {
535
+ const e = effects[i]!;
536
+ if (e.kind !== 'weapon_imbue') continue;
537
+ applyWeaponImbueKit(e);
538
+ if (!weaponImbueHasCombatKit(e)) {
539
+ const bake = (spell.effects ?? []).find(
540
+ (be) => be.kind === 'weapon_imbue' && be.enchantId === e.enchantId,
541
+ );
542
+ if (bake && bake.kind === 'weapon_imbue' && weaponImbueHasCombatKit(bake)) {
543
+ effects[i] = {
544
+ ...e,
545
+ ...(bake.attackPower != null ? { attackPower: bake.attackPower } : {}),
546
+ ...(bake.equipSpellId != null ? { equipSpellId: bake.equipSpellId } : {}),
547
+ ...(bake.combatSpellId != null ? { combatSpellId: bake.combatSpellId } : {}),
548
+ ...(bake.combatChancePct != null ? { combatChancePct: bake.combatChancePct } : {}),
549
+ ...(bake.combatPpm != null ? { combatPpm: bake.combatPpm } : {}),
550
+ ...(bake.damageFlat != null ? { damageFlat: bake.damageFlat } : {}),
551
+ ...(bake.rockbiterAmount != null ? { rockbiterAmount: bake.rockbiterAmount } : {}),
552
+ ...(bake.combat
553
+ ? {
554
+ combat: {
555
+ ...bake.combat,
556
+ ...(bake.combat.direct ? { direct: { ...bake.combat.direct } } : {}),
557
+ ...(bake.combat.dot ? { dot: { ...bake.combat.dot } } : {}),
558
+ },
559
+ }
560
+ : {}),
561
+ ...(bake.family && !e.family ? { family: bake.family } : {}),
562
+ };
563
+ }
564
+ }
565
+ // itemEnchant fallback — poisons (chance-only), stones (damageFlat), oils (equipSpellId).
566
+ // spellLookup fills combat.direct so Instant Poison actually deals nature damage on swing.
567
+ const cur = effects[i]!;
568
+ if (cur.kind !== 'weapon_imbue') continue;
569
+ const ench =
570
+ (ctx as { itemEnchantLookup?: (id: number) => unknown }).itemEnchantLookup?.(cur.enchantId)
571
+ ?? (itemEnchantsTable as Record<string, { effects: unknown[] }>)[String(cur.enchantId)];
572
+ if (ench) {
573
+ applyWeaponImbueKitFromItemEnchant(
574
+ cur,
575
+ ench as Parameters<typeof applyWeaponImbueKitFromItemEnchant>[1],
576
+ ctx.spellLookup,
577
+ );
578
+ }
579
+ }
580
+
581
+ const bakeRole = spell.role;
582
+ // Safety net: an opcode with NO HANDLER AT ALL means the resolution is incomplete, not empty, and
583
+ // returning it erases a row the ETL got right. Gated on unhandled, so a real empty answer stands.
584
+ if (effects.length === 0 && (spell.effects?.length ?? 0) > 0 && result.unhandled.length > 0) {
585
+ return applyFormAttrPatch(spell);
586
+ }
587
+ // Pet-management rows survive regardless, because the ETL SYNTHESIZES them onto learn-spell rows
588
+ // whose opcode is handled and correctly emits nothing — so the guard above cannot see the drop.
589
+ {
590
+ const PET_KINDS = new Set(['summon_pet', 'dismiss_pet', 'revive_pet']);
591
+ // A guardian summon covers the same creature, so do not re-add a bake stamp of a plain pet summon
592
+ // on top of it. Cite: SpellEffects.cpp:2820-2992 EffectSummonGuardian.
593
+ const missing = (spell.effects ?? []).filter((b) => {
594
+ if (!PET_KINDS.has(b.kind)) return false;
595
+ if (effects.some((e) => e.kind === b.kind)) return false;
596
+ if (
597
+ b.kind === 'summon_pet'
598
+ && effects.some(
599
+ (e) => e.kind === 'summon_guardian' && e.creature === b.creature,
600
+ )
601
+ ) {
602
+ return false;
603
+ }
604
+ return true;
605
+ });
606
+ if (missing.length) effects = [...effects, ...missing.map((e) => ({ ...e }))];
607
+ }
608
+ // Aura-removal bodies, last so no earlier rewrite drops the holder. Cite: handlers/aura-remove.ts.
609
+ effects = materializeAuraRemoveEffects(spell, effects);
610
+ // interpretSpellLocal skips finalizeInterpret — lift consume/energy on this path too.
611
+ effects = liftConsumeEnergyIntents(result.intents, effects);
612
+ const out: SpellDef = {
613
+ ...spell,
614
+ effects,
615
+ };
616
+ if (result.strikeBonus != null) {
617
+ out.strikeBonus = result.strikeBonus;
618
+ }
619
+ // A rage energize becomes generated rage in display units. The ETL stamps it from the spell's power
620
+ // type, but Bloodrage's spell is mana while the EFFECT is rage, so the bake never stamped it.
621
+ {
622
+ const POWER_RAGE = 1;
623
+ let fromEnergize = 0;
624
+ for (const e of effects) {
625
+ if (e.kind === 'energize' && e.powerType === POWER_RAGE) {
626
+ fromEnergize = Math.max(fromEnergize, Math.round((e.min ?? 0) / 10));
627
+ }
628
+ }
629
+ if (fromEnergize > 0) {
630
+ out.rageGenerated = Math.max(out.rageGenerated ?? 0, fromEnergize);
631
+ }
632
+ }
633
+ // ADD_COMBO_POINTS is stamped as the top-level generated count: strike riders never re-apply the
634
+ // effect, so a thin raw-only row would land the damage and drop the combo point.
635
+ {
636
+ let fromCp = 0;
637
+ for (const e of effects) {
638
+ if (e.kind === 'combo_points') fromCp = Math.max(fromCp, e.amount | 0);
639
+ }
640
+ if (fromCp > 0) {
641
+ out.comboPointsGenerated = Math.max(out.comboPointsGenerated ?? 0, fromCp);
642
+ }
643
+ }
644
+ // Drop the bake-time role when the effects were replaced: enrichers often stamped utility while the
645
+ // interpreter yields combat-usable kinds. Consumers re-derive it from the resolved list.
646
+ if (effects !== spell.effects) {
647
+ delete (out as { role?: string }).role;
648
+ }
649
+ // Phase Shift's combat stop is on APPLY, not a cast-time gate: the peaceful-only attribute on the
650
+ // bake row made the cast a no-op mid-fight, so pet AI never autocast it.
651
+ if (effects.some((e) => e.kind === 'mod_unattackable')) {
652
+ delete (out as { notInCombatOnly?: boolean }).notInCombatOnly;
653
+ delete (out as { outOfCombatOnly?: boolean }).outOfCombatOnly;
654
+ }
655
+ // A weapon-damage slot sets the strike role, preferred over a later buff-slot stamp — but NEVER over
656
+ // a non-derivable bake role: effect 58 says nothing about melee versus ranged, only SpellRange does.
657
+ if (
658
+ (result.role === 'strike' || (result.strikeBonus != null && result.strikeBonus > 0))
659
+ && !(bakeRole && NON_DERIVABLE_ROLES.has(bakeRole))
660
+ ) {
661
+ // Ranged weapon sample (Multi/Aimed, dmgClass RANGED) is not a melee strike.
662
+ // Cite: SpellEffects.cpp EffectWeaponDmg RANGED_ATTACK; KI-745.
663
+ if ((spell.dmgClass ?? -1) === 3) {
664
+ out.role = (spell.castTimeMs ?? 0) > 0 ? 'nuke' : 'instant_nuke';
665
+ } else {
666
+ out.role = 'strike';
667
+ }
668
+ }
669
+ // Seal materialization is the combat role (rotation classify / AI seal upkeep).
670
+ if (sealFx) {
671
+ out.role = 'seal';
672
+ }
673
+ // Preserve baked roles that are NOT a function of the resolved effects. For those the bake is the
674
+ // only source there will ever be, so discarding one drops the spell out of the spellbook entirely.
675
+ if (!out.role && bakeRole && NON_DERIVABLE_ROLES.has(bakeRole)) {
676
+ out.role = bakeRole;
677
+ }
678
+ // Paid role=shoot casts (Multi/Aimed) are not Auto Shot toggles — reclass after preserve.
679
+ // Pure Auto Shot / Shoot / Throw stay shoot (cost 0, cast 0, gcd 0). Cite: KI-745.
680
+ if (
681
+ out.role === 'shoot'
682
+ && ((out.cost ?? 0) > 0 || (out.castTimeMs ?? 0) > 0 || (out.gcdMs ?? 0) > 0)
683
+ ) {
684
+ out.role = (out.castTimeMs ?? 0) > 0 ? 'nuke' : 'instant_nuke';
685
+ }
686
+ // The spell mechanic: prefer the bake, else fold the raw slots. Template immunity masks and the
687
+ // diminishing-returns key both read this field. Cite: SharedDefines.h Mechanics.
688
+ if (!out.mechanic || out.mechanic === 'none') {
689
+ // Adopt a slot mechanic ONLY when every real slot carries the same one. Taking any slot's made
690
+ // Frostbolt's snare the SPELL's mechanic, and 146 damage spells went unusable on snare immunes.
691
+ const slots = (spell.rawEffects ?? []).filter((r) => (r.effect | 0) > 0);
692
+ const mechs = slots.map((r) => r.mechanic | 0);
693
+ const distinct = [...new Set(mechs.filter((m) => m > 0))];
694
+ if (distinct.length === 1 && mechs.every((m) => m === distinct[0])) {
695
+ const named = MECHANIC_NAME_FROM_ID[distinct[0]!];
696
+ if (named) out.mechanic = named;
697
+ }
698
+ }
699
+ // Warriors never use combo points: the finisher attribute on Overpower is not the combo-point one,
700
+ // so clear it or the ability list is unusable after a dodge. Cite: SpellMgr.h NeedsComboPoints.
701
+ if (out.requiresComboPoints && out.powerType === 'rage') {
702
+ delete (out as { requiresComboPoints?: boolean }).requiresComboPoints;
703
+ delete (out as { finishingScalesDamage?: boolean }).finishingScalesDamage;
704
+ }
705
+ // The interpreter can set the pet-heal role from a pet target even with no bake role — keep that
706
+ // stamp, or combat's health restore heals the owner instead of the pet.
707
+ if (!out.role && result.role && NON_DERIVABLE_ROLES.has(result.role)) {
708
+ out.role = result.role;
709
+ }
710
+ // AoE: enemy-area ImplicitTarget on raw slots (enrich-spell-aoe retired).
711
+ // Cite: SharedDefines Targets 15/16/22/24/28; combat castOnTargets.
712
+ if (out.aoe == null) {
713
+ const AREA_ENEMY = new Set([15, 16, 22, 24, 28]);
714
+ for (const r of spell.rawEffects ?? []) {
715
+ const a = r.targetA | 0;
716
+ const b = r.targetB | 0;
717
+ if (AREA_ENEMY.has(a) || AREA_ENEMY.has(b)) {
718
+ out.aoe = true;
719
+ break;
720
+ }
721
+ }
722
+ }
723
+ // The not-shapeshift and allow-while-not attributes plus the form cost percent, from the ClassicDB
724
+ // map: the bake keeps only the stance columns, and the form attributes were lost with the enricher.
725
+ return applyFormAttrPatch(out);
726
+ }
727
+
728
+ // On-use: resolve ItemDef.useSpell through resolveSpellEffects. Returns null when the item has no useSpell
729
+ // or the spell is missing.
730
+ export function resolveItemOnUse(
731
+ item: Pick<ItemDef, 'useSpell'>,
732
+ lookup: SpellLookup,
733
+ ctx: ResolveSpellEffectsOpts = {},
734
+ ): { spellId: number; spell: SpellDef; result: InterpretResult } | null {
735
+ const spellId = item.useSpell;
736
+ if (spellId == null) return null;
737
+ const spell = lookup(spellId) ?? undefined;
738
+ if (!spell) return null;
739
+ return { spellId, spell, result: resolveSpellEffects(spell, ctx) };
740
+ }
741
+
742
+ // Combat bag-item surface: first buff or instant heal from an interpret result. Same shapes as
743
+ // character.combatItems today (apply_buff / restore_health).
744
+ export function combatUseEffectFromInterpret(
745
+ result: InterpretResult,
746
+ spellId: number,
747
+ ):
748
+ | {
749
+ kind: 'apply_buff';
750
+ mod: BuffMod;
751
+ amount: number;
752
+ durationMs: number;
753
+ spellId: number;
754
+ }
755
+ | { kind: 'restore_health'; min: number; max: number }
756
+ | null {
757
+ for (const e of result.effects) {
758
+ if (e.kind === 'buff') {
759
+ return {
760
+ kind: 'apply_buff',
761
+ mod: e.mod,
762
+ amount: e.amount,
763
+ durationMs: e.durationMs,
764
+ spellId,
765
+ };
766
+ }
767
+ }
768
+ for (const e of result.effects) {
769
+ if (e.kind === 'heal') {
770
+ return { kind: 'restore_health', min: e.min, max: e.max };
771
+ }
772
+ }
773
+ return null;
774
+ }
775
+
776
+ // On-use → combatItems effect when bake path is empty/inert but interpreter yields buff/heal. Skips
777
+ // food/drink restore_* (OOC only) when those appear on bake effects.
778
+ export function resolveCombatUseFromItem(
779
+ item: Pick<ItemDef, 'useSpell' | 'requiredLevel'>,
780
+ lookup: SpellLookup,
781
+ opts: { level: number; ctx?: ResolveSpellEffectsOpts } = { level: 1 },
782
+ ):
783
+ | {
784
+ kind: 'apply_buff';
785
+ mod: BuffMod;
786
+ amount: number;
787
+ durationMs: number;
788
+ spellId: number;
789
+ cooldownMs: number;
790
+ }
791
+ | {
792
+ kind: 'restore_health';
793
+ min: number;
794
+ max: number;
795
+ cooldownMs: number;
796
+ spellId: number;
797
+ }
798
+ | null {
799
+ const resolved = resolveItemOnUse(item, lookup, opts.ctx);
800
+ if (!resolved) return null;
801
+ const { spell, spellId, result } = resolved;
802
+
803
+ // Skip OOC food/drink when bake still tags them (interpreter may not re-emit restore_*)
804
+ const hasFoodDrinkRestore = (spell.effects ?? []).some(
805
+ (e) => e.kind === 'restore_health' || e.kind === 'restore_power',
806
+ );
807
+ if (hasFoodDrinkRestore) return null;
808
+
809
+ // Item.RequiredLevel only — spell.reqLevel over-gates pots (KI-855); alone under-gates (KI-837).
810
+ // Cite: Player.cpp:9797 CanUseItem.
811
+ const req = (item.requiredLevel | 0) || 1;
812
+ if (opts.level < req) return null;
813
+
814
+ const use = combatUseEffectFromInterpret(result, spellId);
815
+ if (!use) return null;
816
+ const cooldownMs = spell.cooldownMs ?? 0;
817
+ if (use.kind === 'apply_buff') {
818
+ return { ...use, cooldownMs };
819
+ }
820
+ return { ...use, cooldownMs, spellId };
821
+ }
822
+
823
+ // On-equip: resolve each equipSpells[] id through the interpreter. Additive path for previously inert
824
+ // empty-effects equip auras (does not replace equipMods).
825
+ export function resolveEquipSpells(
826
+ equipSpellIds: number[] | undefined | null,
827
+ lookup: SpellLookup,
828
+ ctx: ResolveSpellEffectsOpts = {},
829
+ ): Array<{ spellId: number; spell: SpellDef; result: InterpretResult }> {
830
+ const out: Array<{ spellId: number; spell: SpellDef; result: InterpretResult }> = [];
831
+ if (!equipSpellIds?.length) return out;
832
+ for (const spellId of equipSpellIds) {
833
+ const spell = lookup(spellId) ?? undefined;
834
+ if (!spell) continue;
835
+ out.push({ spellId, spell, result: resolveSpellEffects(spell, ctx) });
836
+ }
837
+ return out;
838
+ }
839
+
840
+ // Buff mods from equip spells (interpreter when bake empty). Non-hostile buff only. Caller may merge with
841
+ // ItemDef.equipMods without dropping either side.
842
+ export function resolveEquipBuffMods(
843
+ equipSpellIds: number[] | undefined | null,
844
+ lookup: SpellLookup,
845
+ ctx: ResolveSpellEffectsOpts = {},
846
+ ): Array<{ mod: string; amount: number; spellId: number }> {
847
+ const mods: Array<{ mod: string; amount: number; spellId: number }> = [];
848
+ for (const { spellId, result } of resolveEquipSpells(equipSpellIds, lookup, ctx)) {
849
+ for (const e of result.effects) {
850
+ if (e.kind !== 'buff') continue;
851
+ if (e.hostile) continue;
852
+ mods.push({ mod: e.mod, amount: e.amount, spellId });
853
+ }
854
+ }
855
+ return mods;
856
+ }
857
+
858
+ // Build the proc metadata from an item's proc row and an optional holder spell. The rates and flags
859
+ // come from the item first, then the holder's proc event and spell row — never invented.
860
+ export function buildItemProcMeta(
861
+ proc: ItemProcRow,
862
+ holderSpell?: SpellDef | null,
863
+ ): ProcTriggerSpellMeta {
864
+ const holderId = (holderSpell?.id ?? proc.spell) | 0;
865
+ const pe = holderSpell?.spellProcEvent;
866
+
867
+ // Aura-42 trigger chain when holder rawEffects expose it.
868
+ let triggerSpellId = proc.spell | 0;
869
+ let amount = 0;
870
+ let fromAura42 = false;
871
+ if (holderSpell?.rawEffects?.length) {
872
+ for (const raw of holderSpell.rawEffects) {
873
+ if ((raw.effect | 0) !== SPELL_EFFECT_APPLY_AURA) continue;
874
+ if ((raw.auraName | 0) !== SPELL_AURA_PROC_TRIGGER_SPELL) continue;
875
+ fromAura42 = true;
876
+ const rawTrig = raw.triggerSpell | 0;
877
+ triggerSpellId = resolveProcTriggerSpellId(
878
+ holderId,
879
+ rawTrig,
880
+ holderSpell.spellFamilyName,
881
+ holderSpell.spellFamilyFlags,
882
+ );
883
+ const { min } = effectAmountRange(raw);
884
+ amount = min;
885
+ break;
886
+ }
887
+ }
888
+ // Prefer full meta builder when aura-42 raw is present (Lightning Shield specials, etc.).
889
+ if (fromAura42 && holderSpell?.rawEffects) {
890
+ const raw42 = holderSpell.rawEffects.find(
891
+ (r) =>
892
+ (r.effect | 0) === SPELL_EFFECT_APPLY_AURA &&
893
+ (r.auraName | 0) === SPELL_AURA_PROC_TRIGGER_SPELL,
894
+ );
895
+ if (raw42) {
896
+ const { min, max } = effectAmountRange(raw42);
897
+ const built = buildProcTriggerSpellMeta(
898
+ holderSpell,
899
+ raw42,
900
+ min,
901
+ max || min,
902
+ 0,
903
+ holderSpell.school ?? 'physical',
904
+ );
905
+ if (built) {
906
+ // Overlay the item row's rates when the bake exposes them — the same sourced numbers. Flags
907
+ // come from the item row only, so a fight with no item filters stays seed-stable.
908
+ return {
909
+ ...built,
910
+ // ITEM/enchant proc: `chancePct > 100` is the "use GetWeaponProcChance()" sentinel here,
911
+ // not "always". Cite: Player.cpp:7388. Aura procs must NOT carry this.
912
+ isItemProc: true,
913
+ chancePct:
914
+ proc.chancePct != null && proc.chancePct > 0
915
+ ? proc.chancePct
916
+ : built.chancePct,
917
+ ppmRate:
918
+ proc.ppm != null && proc.ppm > 0
919
+ ? proc.ppm
920
+ : built.ppmRate,
921
+ cooldownMs:
922
+ proc.cooldownMs != null && proc.cooldownMs > 0
923
+ ? proc.cooldownMs
924
+ : built.cooldownMs,
925
+ procFlags: (proc.flags ?? 0) | 0,
926
+ procEx:
927
+ proc.procEx != null && proc.procEx !== 0
928
+ ? proc.procEx
929
+ : undefined,
930
+ schoolMask: proc.schoolMask,
931
+ spellFamilyName: proc.spellFamilyName,
932
+ spellFamilyMask: proc.spellFamilyMask,
933
+ };
934
+ }
935
+ }
936
+ }
937
+
938
+ // Flat ItemDef-driven meta (no aura-42 body, or builder returned null).
939
+ let chancePct = 0;
940
+ if (proc.chancePct != null && proc.chancePct > 0) {
941
+ chancePct = proc.chancePct;
942
+ } else if (pe?.customChance != null && pe.customChance > 0) {
943
+ chancePct = pe.customChance;
944
+ } else if (holderSpell?.procChance != null && holderSpell.procChance > 0) {
945
+ chancePct = holderSpell.procChance;
946
+ }
947
+
948
+ const ppmRate =
949
+ proc.ppm != null && proc.ppm > 0
950
+ ? proc.ppm
951
+ : pe?.ppmRate != null && pe.ppmRate > 0
952
+ ? pe.ppmRate
953
+ : undefined;
954
+
955
+ // ICD: ItemDef.cooldownMs first; else spell_proc_event.Cooldown (sourced bake).
956
+ const cooldownMs =
957
+ proc.cooldownMs != null && proc.cooldownMs > 0
958
+ ? proc.cooldownMs
959
+ : pe?.cooldownMs != null && pe.cooldownMs > 0
960
+ ? pe.cooldownMs
961
+ : undefined;
962
+
963
+ return {
964
+ holderSpellId: holderId,
965
+ triggerSpellId,
966
+ amount,
967
+ // ITEM/enchant proc: `chancePct > 100` is the "use GetWeaponProcChance()" sentinel on this path,
968
+ // not "always". Cite: Player.cpp:7388. Aura procs must NOT carry this.
969
+ isItemProc: true,
970
+ // ItemDef.flags only — 0 = no ProcFlags filter (legacy gear path).
971
+ procFlags: (proc.flags ?? 0) | 0,
972
+ procEx:
973
+ proc.procEx != null && proc.procEx !== 0
974
+ ? proc.procEx
975
+ : undefined,
976
+ chancePct,
977
+ ppmRate,
978
+ cooldownMs,
979
+ schoolMask: proc.schoolMask,
980
+ spellFamilyName: proc.spellFamilyName,
981
+ spellFamilyMask: proc.spellFamilyMask,
982
+ cooldownOnFailure: holderSpell ? (hasAttrEx2(holderSpell, SPELL_ATTR_EX2.PROC_COOLDOWN_ON_FAILURE) ? true : undefined) : undefined,
983
+ bakeKind: 'proc_trigger_spell',
984
+ };
985
+ }
986
+
987
+ // Chance-on-hit roll via SI-PROC subsystem (PPM / flat chance + ICD). Does not apply effects — caller
988
+ // resolves trigger on fire.
989
+ export function tryItemChanceOnHit(
990
+ proc: ItemProcRow,
991
+ holderSpell: SpellDef | undefined | null,
992
+ eventCtx: ProcEventContext,
993
+ rng: Rng,
994
+ opts?: { cooldownReadyAt?: number },
995
+ ): { fired: boolean; cooldownReadyAt: number | null; meta: ProcTriggerSpellMeta } {
996
+ const meta = buildItemProcMeta(proc, holderSpell);
997
+ const roll = tryProcTriggerSpell(meta, eventCtx, rng, opts);
998
+ return { fired: roll.fired, cooldownReadyAt: roll.cooldownReadyAt, meta };
999
+ }
1000
+
1001
+ // After a successful gear-proc roll, produce a SpellDef whose `effects` are applyable. Empty bake holders:
1002
+ // interpret → follow aura-42 triggerSpell when present.
1003
+ export function resolveGearProcApplySpell(
1004
+ holderSpell: SpellDef,
1005
+ lookup: SpellLookup,
1006
+ ctx: ResolveSpellEffectsOpts = {},
1007
+ ): SpellDef | null {
1008
+ // Non-empty bake: legacy path (unchanged surface).
1009
+ if (!isBakeEffectsEmpty(holderSpell)) {
1010
+ return holderSpell;
1011
+ }
1012
+ if (!holderSpell.rawEffects?.length) return null;
1013
+
1014
+ const result = resolveSpellEffects(holderSpell, ctx);
1015
+
1016
+ const hasDirect = result.effects.some(
1017
+ (e) =>
1018
+ e.kind === 'direct_damage' ||
1019
+ e.kind === 'dot' ||
1020
+ e.kind === 'heal' ||
1021
+ e.kind === 'buff' ||
1022
+ e.kind === 'cc' ||
1023
+ e.kind === 'conjure',
1024
+ );
1025
+ if (hasDirect) {
1026
+ return withEffects(holderSpell, result.effects);
1027
+ }
1028
+
1029
+ // Aura-42 / intent: cast the trigger spell's effects.
1030
+ let triggerId: number | undefined;
1031
+ for (const e of result.effects) {
1032
+ if (e.kind === 'proc_trigger_spell') {
1033
+ triggerId = e.triggerSpellId;
1034
+ break;
1035
+ }
1036
+ }
1037
+ if (triggerId == null && result.intents) {
1038
+ for (const i of result.intents) {
1039
+ if (i.kind === 'proc_trigger_spell') {
1040
+ triggerId = i.triggerSpellId;
1041
+ break;
1042
+ }
1043
+ if (i.kind === 'proc_triggered_cast') {
1044
+ triggerId = i.triggerSpellId;
1045
+ break;
1046
+ }
1047
+ }
1048
+ }
1049
+ // Raw trigger when interpret only left unhandled/empty secondary.
1050
+ if (triggerId == null) {
1051
+ for (const raw of holderSpell.rawEffects) {
1052
+ if (
1053
+ (raw.effect | 0) === SPELL_EFFECT_APPLY_AURA &&
1054
+ (raw.auraName | 0) === SPELL_AURA_PROC_TRIGGER_SPELL &&
1055
+ (raw.triggerSpell | 0) > 0
1056
+ ) {
1057
+ triggerId = resolveProcTriggerSpellId(
1058
+ holderSpell.id,
1059
+ raw.triggerSpell | 0,
1060
+ holderSpell.spellFamilyName,
1061
+ holderSpell.spellFamilyFlags,
1062
+ );
1063
+ break;
1064
+ }
1065
+ }
1066
+ }
1067
+
1068
+ if (triggerId != null && triggerId > 0) {
1069
+ const trig = lookup(triggerId) ?? undefined;
1070
+ if (!trig) return null;
1071
+ const trigResult = resolveSpellEffects(trig, ctx);
1072
+ const effects =
1073
+ trigResult.effects.length > 0 ? trigResult.effects : (trig.effects ?? []);
1074
+ if (!effects.length) return null;
1075
+ return withEffects(trig, effects);
1076
+ }
1077
+
1078
+ if (result.effects.length > 0) {
1079
+ return withEffects(holderSpell, result.effects);
1080
+ }
1081
+ return null;
1082
+ }
1083
+
1084
+ function withEffects(spell: SpellDef, effects: SpellEffect[]): SpellDef {
1085
+ return { ...spell, effects };
1086
+ }
1087
+
1088
+ // Nested trigger spell ids for gear procs (aura-42 holders) so combat kits can resolve them. Pure; does not
1089
+ // invent ids.
1090
+ export function gearProcTriggerSpellIds(
1091
+ procs: ItemProcRow[] | undefined | null,
1092
+ lookup: SpellLookup,
1093
+ ): number[] {
1094
+ const ids: number[] = [];
1095
+ const seen = new Set<number>();
1096
+ for (const p of procs ?? []) {
1097
+ if (!p.spell || seen.has(p.spell)) continue;
1098
+ seen.add(p.spell);
1099
+ ids.push(p.spell);
1100
+ const holder = lookup(p.spell) ?? undefined;
1101
+ if (!holder?.rawEffects) continue;
1102
+ for (const raw of holder.rawEffects) {
1103
+ if (
1104
+ (raw.effect | 0) === SPELL_EFFECT_APPLY_AURA &&
1105
+ (raw.auraName | 0) === SPELL_AURA_PROC_TRIGGER_SPELL
1106
+ ) {
1107
+ const tid = resolveProcTriggerSpellId(
1108
+ holder.id,
1109
+ raw.triggerSpell | 0,
1110
+ holder.spellFamilyName,
1111
+ holder.spellFamilyFlags,
1112
+ );
1113
+ if (tid > 0 && !seen.has(tid)) {
1114
+ seen.add(tid);
1115
+ ids.push(tid);
1116
+ }
1117
+ }
1118
+ }
1119
+ }
1120
+ return ids;
1121
+ }