azeroth-shell 0.0.0-stage → 0.1.1

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 +35 -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 +144 -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,1897 @@
1
+ // Combat types (Wave 4 S24) — extracted from engine/combat.ts.
2
+ // Public surface re-exported via combat.ts barrel; Fighter/ActiveEffect/etc. for combat/* modules.
3
+
4
+ import type {
5
+ SpellDef,
6
+ PowerType,
7
+ School,
8
+ BuffMod,
9
+ ControlKind,
10
+ Mechanic,
11
+ ShapeshiftFormId,
12
+ TotemSlot,
13
+ CreatureCastEntry,
14
+ CreatureAiBundle,
15
+ CreatureSpellListEntry,
16
+ CombatConditionDef,
17
+ UnitConditionDef,
18
+ } from '../../data/schema.ts';
19
+ import type { CombatEvent, Side, TotemSide } from '../core/events.ts';
20
+ import type { CombatantId } from './threat.ts';
21
+ import type { AllyFilter, HaltDpsSchool, RotationSnapshot, RuleAfter, RuleAfterStep, RuleMove } from '../../domain/rotation/rotation.ts';
22
+ import type { CombatPosYd, PullGeometryAnchor, UnitPositionsYd } from './combatGeometry.ts';
23
+ import type {
24
+ SchoolAbsorbAura,
25
+ ManaShieldAura,
26
+ SplitDamagePctAura,
27
+ SplitDamageFlatAura,
28
+ } from '../spells/absorbs.ts';
29
+ import type { CreatureImmunitySet, ImmunityState } from '../spells/immunity.ts';
30
+ import type { SpellMod } from '../spells/spellMods.ts';
31
+ import type { OwnedSpellMod } from '../spells/spellModIntents.ts';
32
+ import type { ActiveSeal, StartActiveSeal } from './activeSeal.ts';
33
+ import type { AuraStackIdentity } from '../spells/auraStacking.ts';
34
+
35
+ export type { ActiveSeal, StartActiveSeal } from './activeSeal.ts';
36
+
37
+ export interface ActiveWeaponImbue {
38
+ spellId: number;
39
+ name: string;
40
+ expiresAt: number;
41
+ enchantId?: number;
42
+ family?: string;
43
+ attackPower?: number;
44
+ // TYPE_EQUIP_SPELL passive (oil mp5/SP, lure), cast on apply and dropped with the enchant.
45
+ // Rockbiter carries `attackPower` instead — never both. Cite: Player.cpp:11299-11310.
46
+ equipSpellId?: number;
47
+ combatChancePct?: number;
48
+ combatPpm?: number;
49
+ damageFlat?: number;
50
+ rockbiterAmount?: number;
51
+ combat?: {
52
+ spellId: number;
53
+ name: string;
54
+ direct?: { school: School; min: number; max: number };
55
+ dot?: { school: School; min: number; max: number; durationMs: number; tickMs: number };
56
+ extraAttacks?: number;
57
+ apBonus?: number;
58
+ /** Frostbrand / Crippling Poison snare. Cite: KI-581 / KI-717. */
59
+ speed?: {
60
+ aura: number;
61
+ pct: number;
62
+ durationMs: number;
63
+ hostile?: boolean;
64
+ mechanic?: string;
65
+ };
66
+ /** Mind-numbing / Wound Poison hostile buffs. Cite: KI-717. */
67
+ buffs?: Array<{
68
+ mod: string;
69
+ amount: number;
70
+ durationMs: number;
71
+ hostile?: boolean;
72
+ }>;
73
+ };
74
+ }
75
+
76
+ export interface WeaponProfile {
77
+ dmgMin: number;
78
+ dmgMax: number;
79
+ speedMs: number;
80
+ school: School;
81
+ twoHand?: boolean; // true for a two-handed weapon (item slot 'twohand'); selects the 2H seal formula
82
+ }
83
+
84
+ export interface ProcDef {
85
+ triggerSpellId: number;
86
+ // `SPELL_ATTR_EX3_CAN_PROC_FROM_PROCS` on the aura that owns the proc, not the payload; 34 rows.
87
+ // Absent = the proc cannot fire from a triggered cast. Cite: UnitAuraProcHandler.cpp:610.
88
+ canProcFromProcs?: boolean;
89
+ // `SPELL_ATTR_PROC_FAILURE_BURNS_CHARGE` on the aura — a failed roll still spends a charge.
90
+ // 12 rows: every Windfury Weapon and Totem rank, Drain Soul. Cite: UnitAuraProcHandler.cpp:505.
91
+ failureBurnsCharge?: boolean;
92
+ spellIconId?: number;
93
+ chance: number | null; // 0..1 probability per trigger event, or null if ppm-driven
94
+ ppm: number | null; // procs-per-minute (requires speed scaling at trigger sites)
95
+ /** SpellMgr.h ProcFlags bitmask; absent = match any damage hit context. */
96
+ procFlags?: number;
97
+ // SpellEntry.Stances of the talent rank that owns the proc — Blood Frenzy is cat, Primal Fury is
98
+ // bear/dire. 0 or absent = no form requirement. Cite: DBCStructure.h:864 CanBeUsedInForm.
99
+ stances?: number;
100
+ /** SpellMgr.h ProcFlagsEx; e.g. CRITICAL_HIT only. Absent = no ex filter. */
101
+ procEx?: number;
102
+ /** Hidden CD on the triggered spell (ms) from SpellProcEventEntry.cooldown. */
103
+ cooldownMs?: number;
104
+ /** SpellProcEventEntry.customChance as 0..1 (overrides chance when set). */
105
+ customChance?: number;
106
+ /** spell_proc_event.schoolMask — filter by triggering spell school. */
107
+ schoolMask?: number;
108
+ /** spell_proc_event.spellFamilyName. */
109
+ spellFamilyName?: number;
110
+ /** spell_proc_event.spellFamilyMask[3]. */
111
+ spellFamilyMask?: number[];
112
+ }
113
+
114
+ /** Per-school damage multiplier from talents (and future sources). Values are percentage points, e.g. 10 = +10%. */
115
+ export type DamagePctBySchool = Partial<Record<School, number>>;
116
+
117
+ /** Group role hint for ally combatants (drives the S0 role-branched AI; S1 replaces with rotations). */
118
+ export type GroupRole = 'tank' | 'healer' | 'damage';
119
+
120
+ export interface CombatantSpec {
121
+ name: string;
122
+ level: number;
123
+ /** 0 male, 1 female (Character.gender convention; GENDER_MALE=0). Absent defaults male. */
124
+ gender?: 0 | 1;
125
+ // Live player drunkenness 0..0xFFFF during a fight (mirrors Character.drunkValue).
126
+ // Cite: Player.cpp m_drunk / SetDrunkValue; SPELL_EFFECT_INEBRIATE; KI-734.
127
+ drunkValue?: number;
128
+ /** Unit m_movementInfo.moveFlags. Cite: Object.h:750 MOVEFLAG_HOVER; Unit.cpp:12428 SetHover. */
129
+ movementFlags?: number;
130
+ // healer heals the lowest friendly, tank taunts when not the victim and prefers threat kit,
131
+ // damage or absent falls back to class heuristics. Ignored on pet/enemy specs.
132
+ groupRole?: GroupRole;
133
+ // World cooldowns carried into the fight, as remaining ms at t=0 — the same relative form
134
+ // `CombatConfig.initialSpellCooldowns` gives the player.
135
+ initialSpellCooldowns?: Record<number, number>;
136
+ initialCategoryCooldowns?: Record<number, number>;
137
+ // 0-based raid subgroup; party targets reach only the caster's subgroup, and absent = ungrouped
138
+ // so every party fan fails open. Cite: Spell.cpp:7325–7345 FillRaidOrPartyTargets.
139
+ subgroup?: number;
140
+ // Friendlies only, absent = 'auto'. 'auto' closes or steps back to `standYards`, 'hold' never
141
+ // auto-moves, 'melee' always closes to reach.
142
+ movement?: 'auto' | 'hold' | 'melee';
143
+ // Yards to hold from the focus (Rotation.standYards). Absent → kitWantsMeleeBand.
144
+ // 5 = melee pile; 20–30 = ranged default.
145
+ standYards?: number;
146
+ /** False suppresses the voluntary PBAoE pack walk-in (autopilot aoeMode 'single'). Absent = allowed. */
147
+ packClose?: boolean;
148
+ /** Player class id (schema CLASS / SharedDefines). Used for live strength→AP cascades. */
149
+ classId?: number;
150
+ maxHealth: number;
151
+ startHealth?: number;
152
+ powerType: PowerType;
153
+ maxPower: number;
154
+ startPower: number;
155
+ armor: number;
156
+ // The BASE (item) slice of `armor` — what a mid-fight aura 142 BASE_PCT multiplies. Absent on
157
+ // mobs and fixtures. Cite: Unit.cpp:9067 (base_value * base_pct) + total_value.
158
+ baseArmor?: number;
159
+ weapon: WeaponProfile; // main-hand melee auto-attack
160
+ // Off-hand weapon when dual-wielding. Absent when empty, shield, or form-overridden speed.
161
+ // Cite: hasOffhandWeaponForAttack; UNIT_FIELD_*OFFHANDDAMAGE.
162
+ offhand?: WeaponProfile;
163
+ ranged?: WeaponProfile; // equipped ranged weapon (wand/bow/gun); powers Shoot / Auto Shot
164
+ rangedAuto?: boolean; // true → auto-attacks at range with `ranged` (a Hunter with a bow) instead of meleeing
165
+ // Ammo DPS from the selected projectile; 0 or absent when no ammo is selected, incompatible,
166
+ // count 0, or not baked. Cite: Player.cpp _ApplyAmmoBonuses.
167
+ ammoDpsMin?: number;
168
+ ammoDpsMax?: number;
169
+ // Live projectile ammo for the mid-fight gate and consume, decremented into itemsConsumed.
170
+ // Cite: Spell.cpp TakeAmmo / CheckCast NO_AMMO.
171
+ ammoEntry?: number;
172
+ ammoRemaining?: number;
173
+ /** Projectile subclass (arrow=2 / bullet=3) for compatibility re-check. */
174
+ ammoSubclass?: number;
175
+ /** Equipped ranged weapon subclass (bow/gun/xbow/wand/thrown). */
176
+ rangedWeaponSubclass?: number;
177
+ /** MH weapon subclass for HasItemFitToSpellReqirements. Cite: Player.cpp:18595–18601. */
178
+ mainhandWeaponSubclass?: number;
179
+ /** OH weapon subclass when dual-wielding (not shield). Cite: Player.cpp:18595–18601. */
180
+ offhandWeaponSubclass?: number;
181
+ /** 0-dur paperdoll weapon subclass (fit omits; reason → 'broken weapon'). KI-891/798. */
182
+ brokenMainhandWeaponSubclass?: number;
183
+ brokenOffhandWeaponSubclass?: number;
184
+ brokenRangedWeaponSubclass?: number;
185
+ /** OH armor subclass (shield/holdable). Cite: Player.cpp:18611–18614. */
186
+ offhandArmorSubclass?: number;
187
+ /** Body-slot armor subclasses for ITEM_CLASS_ARMOR fit. Cite: Player.cpp:18605–18609. */
188
+ bodyArmorSubclasses?: number[];
189
+ /** Ranged-slot relic armor subclass. Cite: Player.cpp:18616–18619. */
190
+ rangedArmorSubclass?: number;
191
+ /** Paperdoll scanned at pull; absent → fixture grace for non-ranged EquippedItem*. */
192
+ equippedItemFitReady?: boolean;
193
+ // Stackable thrown remaining (equipped + bags); absent when not thrown, 0 → NO_AMMO.
194
+ // Cite: Spell.cpp TakeAmmo thrown path.
195
+ thrownRemaining?: number;
196
+ /** Thrown weapon item entry when ranged slot is thrown (for itemsConsumed). */
197
+ thrownEntry?: number;
198
+ // SpellItemEnchantment TYPE_DAMAGE flats per hand. Cite: Player.cpp SetEnchantmentModifier ~11281.
199
+ enchantFlatMh?: number;
200
+ enchantFlatOh?: number;
201
+ enchantFlatRanged?: number;
202
+ attackPower: number;
203
+ // Sheet agility at pull, for the mid-fight Cat AGI→AP re-sync; absent or 0 → no form AGI AP delta.
204
+ // Cite: StatSystem.cpp UpdateAttackPowerAndDamage.
205
+ agility?: number;
206
+ /** Ranged AP when computed (hunters etc.); optional for test/mob specs. */
207
+ rangedAttackPower?: number;
208
+ critChance: number;
209
+ /** Spell crit from intellect curves (0..1). Falls back to critChance for mobs/tests. */
210
+ spellCritChance?: number;
211
+ hitChance: number;
212
+ // Gear SPELL_AURA_MOD_SPELL_HIT_CHANCE (55) in percentage points, seeding
213
+ // Fighter.spellHitBonusPercent. Cite: Unit.cpp CalculateSpellMissChance.
214
+ spellHitBonusPercent?: number;
215
+ haste?: number; // percent, e.g. 10 = +10% attack/cast/GCD speed
216
+ // Ranged-only haste % from quiver/ammo pouch equip spells (SPELL_AURA_MOD_RANGED_AMMO_HASTE).
217
+ // Cite: SpellAuras.cpp HandleRangedAmmoHaste.
218
+ rangedHastePct?: number;
219
+ dodgeChance?: number; // base dodge chance (agi + class base) as 0..1
220
+ parryChance?: number;
221
+ blockChance?: number;
222
+ /** Flat damage reduced on a successful block (Player::GetShieldBlockValue). Optional. */
223
+ blockValue?: number;
224
+ blockValuePct?: number;
225
+ canBlock?: boolean; // has a shield equipped → can block incoming melee
226
+ canParry?: boolean; // wields a weapon → can parry incoming melee
227
+ // MH weapon skill for attack-table math (pure trained + MOD_SKILL bonuses).
228
+ // Cite: Unit.h GetSkillMaxForLevel; Unit.cpp GetWeaponSkillValue.
229
+ weaponSkill?: number;
230
+ // Defense skill for attack-table math (pure + bonuses). Cite: Unit.cpp GetDefenseSkillValue.
231
+ defenseSkill?: number;
232
+ /** CMaNGOS skill id for MH weapon (Item::GetSkill). Used for skill gain. */
233
+ weaponSkillId?: number;
234
+ /** OH weapon skill id when dual-wielding. */
235
+ offhandSkillId?: number;
236
+ /** Ranged weapon skill id. */
237
+ rangedSkillId?: number;
238
+ // OH / ranged effective skill (trained + bonuses), falling back to weaponSkill when absent.
239
+ // Cite: GetWeaponSkillValue(OFF_ATTACK / RANGED_ATTACK).
240
+ offhandWeaponSkill?: number;
241
+ rangedWeaponSkill?: number;
242
+ // MOD_SKILL bonuses by skill line id, kept separate from pure combatSkills so a mid-fight gain
243
+ // recomputes GetSkillValue = pure + bonus. Cite: Player.cpp ModifySkillBonus.
244
+ skillBonuses?: Partial<Record<number, number>>;
245
+ // Live combat skill map (pure trained values) for skill gain, mutated during the fight and
246
+ // returned on CombatResult. Absent → pure L×5, with bonuses still stacking via skillBonuses.
247
+ combatSkills?: Partial<Record<number, { current: number; max: number }>>;
248
+ /** Intellect for UpdateCombatSkills weapon intellect bonus. */
249
+ intellect?: number;
250
+ // Player-controlled unit, which decides glance/crush eligibility and NPC skill-diff factors.
251
+ // Absent → inferred from the combat side (player/pet/totem = true).
252
+ isPlayerOrPet?: boolean;
253
+ // Pet bar state the session opens with (pet spec only).
254
+ // Absent = the summon default, COMMAND_FOLLOW + REACT_DEFENSIVE.
255
+ petCommand?: 'attack' | 'follow' | 'stay';
256
+ petReact?: 'aggressive' | 'defensive' | 'passive';
257
+ // GuardianAI unit (IsPet && GUARDIAN_PET); follow parks at 1.5, not PET_FOLLOW_DIST.
258
+ // Cite: GuardianAI.cpp:31, :76–81 Permissible.
259
+ isGuardian?: boolean;
260
+ /** UNIT_CREATED_BY_SPELL. GuardianAI.cpp:33–37 spell 11939 → follow 3. */
261
+ createdBySpell?: number;
262
+ // The unit that summoned this ally seat: marks the seat recyclable and keeps the body out of the
263
+ // party-wipe test. Cite: SpellEffects.cpp AddGuardian.
264
+ summonOwnerSide?: Side;
265
+ // A creature-cast totem body (not one of the party's four slots): its health comes from the summon
266
+ // spell and it unsummons with its owner. Cite: SpellEffects.cpp:4538; Totem.cpp:79-84.
267
+ isTotem?: boolean;
268
+ // Every ability the pet knows, autocast-off included; `spells` is only the enabled subset the AI
269
+ // may pick, and a pet-bar press may still fire a disabled one. Cite: Pet.h PetSpellMap.
270
+ petFullKit?: SpellDef[];
271
+ // Dual-wield equipped: auto swings get +19% miss (not abilities or on-next-swing) and a second
272
+ // OH swing timer runs. Cite: Unit.cpp CalculateEffectiveMissChance ~3767.
273
+ dualWield?: boolean;
274
+ // Active TEMP_ENCHANTMENT_SLOT imbues/poisons at pull (from Character.tempEnchants).
275
+ // Cite: EffectEnchantItemTmp; Player::CastItemCombatSpell.
276
+ tempEnchants?: Partial<Record<'mainhand' | 'offhand', ActiveWeaponImbue>>;
277
+ // Preferred hand for mid-fight weapon_imbue casts, read by applySpellLate; omitted → mainhand.
278
+ // Cite: SpellEffects.cpp EffectEnchantItemTmp itemTarget.
279
+ weaponImbueCastHand?: 'mainhand' | 'offhand';
280
+ // OOC damage shields (Lightning Shield) carried in, seeded from Character.activeAuras when the
281
+ // spell has a damage_shield effect. Cite: SPELL_AURA_PROC_TRIGGER_SPELL.
282
+ startDamageShields?: Array<{
283
+ spellId: number;
284
+ name: string;
285
+ school: School;
286
+ min: number;
287
+ max: number;
288
+ remainingMs: number;
289
+ charges?: number;
290
+ cooldownMs?: number;
291
+ }>;
292
+ /** OOC generic aura-42 proc triggers carried into combat. */
293
+ startProcTriggers?: Array<{
294
+ spellId: number;
295
+ name: string;
296
+ triggerSpellId: number;
297
+ remainingMs: number;
298
+ charges?: number;
299
+ cooldownMs?: number;
300
+ /** SpellDef.procFlags / spell_proc_event — deal vs take filtering. */
301
+ procFlags?: number;
302
+ /** spell_proc_event.ppmRate when present. */
303
+ procPpm?: number | null;
304
+ /** Flat 0..1 chance when present. */
305
+ procChance?: number | null;
306
+ // World/combat yards where the GO was placed (caster feet at arm).
307
+ // Cite: SpellEffects.cpp EffectSummonObject GetClosePoint; GameObject trap Use.
308
+ trapPosYd?: CombatPosYd;
309
+ }>;
310
+ // SPELL_AURA_ADD_TARGET_TRIGGER (109) talent passives, seeded onto Fighter.addTargetTriggers
311
+ // until cancelled. Cite: Spell.cpp:7433–7468 ProcSpellAuraTriggers.
312
+ startAddTargetTriggers?: Array<{
313
+ spellId: number;
314
+ triggerSpellId: number;
315
+ chancePct: number;
316
+ familyName: number;
317
+ familyFlags: number;
318
+ }>;
319
+ // OOC school_absorb auras carried in from Character.activeAuras; the pool rolls once at fight
320
+ // start, as an in-combat apply does. Cite: SPELL_AURA_SCHOOL_ABSORB; Unit.cpp ~2391; KI-181.
321
+ startSchoolAbsorbs?: Array<{
322
+ spellId: number;
323
+ name: string;
324
+ schoolMask: number;
325
+ min: number;
326
+ max: number;
327
+ remainingMs: number;
328
+ }>;
329
+ // Speed auras a body carries with nothing running: the boots enchant and spent talent ranks
330
+ // (Pursuit of Justice, Feline Swiftness in cat). Not effect rows — they never expire, never show
331
+ // a buff icon and cannot be dispelled. UpdateSpeed buckets them by aura and takes the max of each,
332
+ // so they can only replace a weaker source, never add to one. Cite: Unit.cpp:8352.
333
+ permanentSpeedAuras?: Array<{ aura: number; pct: number }>;
334
+ // Talent auras the shapeshift handler casts on form APPLY, keyed by form id, as a delta on the
335
+ // form-free spec above. Feline Swiftness (cat), Sharpened Claws (cat/bear/dire), Defiance
336
+ // (defensive stance). applyFormCombatEnter adds one row, clearFormCombatBonuses takes it back, so a
337
+ // stance dance moves them live. Cite: SpellAuras.cpp:4296-4304 HandleShapeshiftBoosts.
338
+ formTalentAuras?: Record<number, {
339
+ crit: number;
340
+ dodge: number;
341
+ threatPctBySchool: Partial<Record<School, number>>;
342
+ speedAuras: Array<{ aura: number; pct: number }>;
343
+ stealthLevel: number;
344
+ damagePctBySchool: Partial<Record<School, number>>;
345
+ formThreatPct: number;
346
+ attackPower?: number;
347
+ health?: number;
348
+ }>;
349
+ // The mount this body is riding, absent when on foot. Its percent enters as aura 32 and swings
350
+ // UpdateSpeed onto the mounted buckets (32/130/172). Cite: Unit.cpp:8345-8348; Unit::IsMounted.
351
+ mount?: { speedPct: number };
352
+ /** OOC HoT / OBS_MOD_HEALTH (KI-182; Fel Stamina 18790 pctOfMax — KI-833). */
353
+ startRestoreHealth?: Array<{ spellId: number; name: string; amountPerTick: number; tickMs: number; remainingMs: number; pctOfMax?: number }>;
354
+ /** OOC OBS_MOD_MANA Fel Energy 18792. Cite: Warlock.cpp DemonicSacrifice; KI-833. */
355
+ startRestorePower?: Array<{ spellId: number; name: string; amountPerTick: number; tickMs: number; remainingMs: number; pctOfMax?: number; powerType?: number }>;
356
+ // OOC mana_shield auras carried into combat (same import path as school_absorb).
357
+ // Cite: SPELL_AURA_MANA_SHIELD; Unit.cpp ~2457.
358
+ startManaShields?: Array<{
359
+ spellId: number;
360
+ name: string;
361
+ schoolMask: number;
362
+ min: number;
363
+ max: number;
364
+ manaMultiplier: number;
365
+ remainingMs: number;
366
+ }>;
367
+ // Display/duration carry of OOC buffs; stats are already folded into CombatantSpec, so these only
368
+ // seed buffActive and a duration row. `liveBuffs` and the immunity maps do apply combat state.
369
+ startDisplayAuras?: Array<{
370
+ spellId: number;
371
+ name: string;
372
+ remainingMs?: number;
373
+ permanent?: boolean;
374
+ /** Live buff mods to apply at pull (threat_mod, armor_pct, etc.). Reversed on expiry. */
375
+ liveBuffs?: Array<{ mod: BuffMod; amount: number; school?: School }>;
376
+ /** SPELL_AURA_MECHANIC_IMMUNITY (77) mechanic ids to grant at pull. */
377
+ mechanicImmunities?: number[];
378
+ /** SPELL_AURA_DISPEL_IMMUNITY (41) DispelType ids to grant at pull (Stoneform poison). */
379
+ dispelImmunities?: number[];
380
+ /** Remaining SpellEntry.procCharges. Cite: SpellAuras.cpp DropAuraCharge. */
381
+ charges?: number;
382
+ /** SpellDef.procFlags so take-hit consume matches without the holder in spec.spells. */
383
+ procFlags?: number;
384
+ // Sheet-baked buff mods (armor / AP) already in CombatantSpec, seeded as reverseable rows
385
+ // without applyBuffMod so the last-charge reverse subtracts the sheet.
386
+ chargedSheetBuffs?: Array<{ mod: BuffMod; amount: number; school?: School }>;
387
+ // A party AREA aura (effect 35): its sheet-baked mods seed as reversible rows, since a sibling
388
+ // rank or the holder's remove arm can take it mid-fight. Cite: SpellAuras.cpp:591-620.
389
+ sheetBuffs?: Array<{ mod: BuffMod; amount: number; school?: School }>;
390
+ exclusionGroup?: number;
391
+ stackIdent?: AuraStackIdentity;
392
+ }>;
393
+ // OOC next_cast_mod (Presence of Mind, Nature's Swiftness, Cold Blood) armed into combat.
394
+ // durationMs 0 = until-consumed; combat uses 600s when bake duration is 0. Cite: KI-540.
395
+ startPendingSpellMod?: {
396
+ spellId: number;
397
+ name: string;
398
+ appliesTo: 'any' | 'nature' | 'heal' | 'summon' | 'curse';
399
+ critAdd?: number;
400
+ instant?: boolean;
401
+ freeCost?: boolean;
402
+ /** SPELLMOD_COST % on resolved cost. Prefer costModPct; costPct kept for buildCombatant. */
403
+ costModPct?: number;
404
+ /** @deprecated Use costModPct — not SpellDef.costPct / ManaCostPercentage. */
405
+ costPct?: number;
406
+ /** SPELLMOD_COST flat. Cite: SpellDefines.h SPELLMOD_COST=14. */
407
+ costFlat?: number;
408
+ effectPct?: number;
409
+ castTimeFlat?: number;
410
+ /** Source SpellFamilyName — consume only same-family casts. Cite: Player.cpp:354. */
411
+ spellFamilyName?: number;
412
+ /** EffectItemType mask; 0 = family-name only. Cite: Player.cpp:350–357. */
413
+ familyFlags?: number;
414
+ /** The holder's 107/108 rows. Cite: spellModIntents.chargedSpellModsFromSpell. */
415
+ rows?: readonly OwnedSpellMod[];
416
+ remainingMs: number;
417
+ };
418
+ // OOC Sweeping Strikes (12292) carried into combat: remaining charges + duration.
419
+ // Cite: UnitAuraProcHandler.cpp:810–841; applySpellLate sweeping_strikes.
420
+ startSweepingStrikes?: {
421
+ spellId: number;
422
+ name: string;
423
+ charges: number;
424
+ remainingMs: number;
425
+ };
426
+ // OOC Combustion (11129) carried into combat: fire crits left plus the stacks already up.
427
+ // Cite: UnitAuraProcHandler.cpp:991-1003; applySpellLate combustion.
428
+ startCombustion?: {
429
+ spellId: number;
430
+ name: string;
431
+ charges: number;
432
+ stacks: number;
433
+ remainingMs: number;
434
+ };
435
+ // OOC Vampiric Embrace (15286) pct carried into combat.
436
+ // Cite: UnitAuraProcHandler.cpp:1015–1028; applySpellLate vampiric_embrace.
437
+ startVampiricEmbrace?: {
438
+ spellId: number;
439
+ name: string;
440
+ pct: number;
441
+ remainingMs: number;
442
+ };
443
+ /** OOC paladin seal → ActiveSeal + buff chip. Cite: activeSeal.ts; KI-894. */
444
+ startActiveSeal?: StartActiveSeal;
445
+ // OOC school_immunity auras carried in from Character.activeAuras; createSession grants the live
446
+ // ImmunityState via grantImmunityAura. Cite: SpellAuras HandleAuraModSchoolImmunity; KI-086.
447
+ startSchoolImmunities?: Array<{
448
+ spellId: number;
449
+ name: string;
450
+ schoolMask: number;
451
+ remainingMs: number;
452
+ positive?: boolean;
453
+ /** The spell's own mechanic id, so a carried-in Divine Shield stays unpierceable. */
454
+ mechanic?: number;
455
+ }>;
456
+ // Per-school magic resistance; absent or 0 = no mitigation. Reduces incoming magic damage and
457
+ // raises the chance to fully resist a crowd-control land.
458
+ resistances?: Partial<Record<School, number>>;
459
+ // CREATURE_TYPE for CC immunity: Polymorph lands only on Humanoid/Beast/Critter, Turn Evil only on
460
+ // Undead/Demon, undead mobs are fear-immune. Absent = treated as Humanoid.
461
+ creatureType?: number;
462
+ // creature_template.RegenerateStats — REGEN_FLAG_POWER_IN_COMBAT 0x4 gates the creature mana
463
+ // tick. Absent means the default 14 every other row carries. Cite: Creature.cpp:1803-1808.
464
+ regenerateStats?: number;
465
+ // creature_template.entry when this combatant is spawned from a creature, so scripted effects key
466
+ // off it (Demonic Sacrifice picks its self-buff by demon entry). Absent on player specs.
467
+ creatureEntry?: number;
468
+ /** creature.MovementType = GetDefaultMovementType(); absent = unknown, not idle. Cite: naxxramas.cpp:995 */
469
+ movementType?: number;
470
+ // Who this unit is for its whole life in the instance, minted by the world and never re-minted on
471
+ // inject; the side is a recycled slot, not an identity. Cite: liveAggroStream.ts:301-318.
472
+ guid?: number;
473
+ // The seat this companion's pet occupies, stamped once at session build from
474
+ // `CombatConfig.allyPetIndex`. Not `summonOwnerSide`, which points the other way.
475
+ petSide?: Side;
476
+ // UNIT_FIELD_COMBATREACH in yards; melee contact sums both bodies' reach plus 1.33, floored at 5,
477
+ // so Onyxia 23.4 is meleeable from 26.2 yd. Cite: Object.cpp:1741-1758 GetCombinedCombatReach.
478
+ combatReachYd?: number;
479
+ // creature_template.UnitClass (1 warrior, 2 paladin, 4 rogue, 8 mage) — the key
480
+ // creature_template_classlevelstats uses for creature-level spell scaling. Cite: Object.cpp:3005.
481
+ unitClass?: number;
482
+ // creature_template.ExtraFlags. AGGRO_ZONE (512) → SetInCombatWithZone on enter combat.
483
+ // Cite: Creature.h CREATURE_EXTRA_FLAG_AGGRO_ZONE; Unit.cpp:7986–7988.
484
+ extraFlags?: number;
485
+ // creature_template.StaticFlags: UNKILLABLE 0x8 clamps damage to 1 HP, SESSILE 0x100 cannot close,
486
+ // LARGE_AOI 0x80000000 widens visibility. Cite: CreatureDefines.h CreatureStaticFlags.
487
+ staticFlags?: number;
488
+ // creature_template.StaticFlags2. NO_CRUSHING_BLOWS (0x10) gates crush.
489
+ // Cite: CreatureDefines.h CreatureStaticFlags2; Unit.cpp:3109.
490
+ staticFlags2?: number;
491
+ // Current map id for CheckCast gates that key off GetMapId() (AQ40 mounts require 531).
492
+ // Cite: Spell.cpp:5762–5775.
493
+ mapId?: number;
494
+ // Mutable string-key flags for one-shot CheckCast bookkeeping (e.g. Screecher Spirit hit).
495
+ // Cite: Spell.cpp Summon Screecher Spirit already-hit gate.
496
+ flags?: Record<string, boolean>;
497
+ // ScriptDev UpdateEntry morph targets resolved at spec build time; `update_entry` swaps name, max
498
+ // health (refilled), armor and weapon. Cite: boss_dathrohan_balnazzar.cpp UpdateEntry.
499
+ scriptDevMorphs?: Array<{
500
+ creatureEntry: number;
501
+ name: string;
502
+ maxHealth: number;
503
+ armor?: number;
504
+ weapon?: WeaponProfile;
505
+ }>;
506
+ // When present, combat uses the creature cast scheduler instead of class-heuristic pickAction.
507
+ // Absent → bare spells[] still get a synthetic schedule so trash can cast.
508
+ creatureCasts?: CreatureCastEntry[];
509
+ // Top-level creature_spell_list schedule, armed as TIMER_IN_COMBAT slots on the creatureCasts
510
+ // scheduler. Cite: UnitAI.cpp AddInitialCooldowns / UpdateSpellLists.
511
+ spellList?: CreatureSpellListEntry[];
512
+ // EventAI bundle; the combat interpreter runs non-CAST actions (SET_PHASE / SPAWN / SUMMON_ID /
513
+ // FLEE) and phase-gates casts. Absent → cast-only path. Cite: CreatureEventAI.
514
+ ai?: CreatureAiBundle;
515
+ /** creature_template.SchoolImmuneMask — (1 << school). */
516
+ schoolImmuneMask?: number;
517
+ /** creature_template.MechanicImmuneMask — (1 << (mechanic-1)). */
518
+ mechanicImmuneMask?: number;
519
+ // creature_template.UnitFlags as spawned. STUNNED / PACIFIED seed the fighter's own timers, so a
520
+ // Target Dummy stands there instead of swinging. Cite: Unit.h:483-485.
521
+ spawnUnitFlags?: number;
522
+ // creature_immunities set 0 (effect ids / aura-type ids / dispel mask), applied at spawn.
523
+ // Cite: Creature.cpp:613 UpdateImmunitiesSet(0).
524
+ immunities?: CreatureImmunitySet;
525
+ // SPELL_AURA_MOD_MECHANIC_RESISTANCE (117) totals by mechanic id, added to the one SpellHitResult
526
+ // resist chance. Cite: Unit.cpp:4015–4031; KI-823.
527
+ mechanicResistPct?: Partial<Record<number, number>>;
528
+ /** CLASSMASK_WAND_USERS glance-chance special (pre-30 curve). Cite: Unit.cpp:3310. */
529
+ wandUser?: boolean;
530
+ /** Caster glance amount bases (CLASSMASK_WAND_USERS). Cite: Unit.cpp:3349. */
531
+ casterGlance?: boolean;
532
+ // Talent-driven (Phase C): school damage % (e.g. +fire damage), extra crit, and procs.
533
+ // Absent values mean no change from baseline (pre-talent bakes unaffected).
534
+ damagePctBySchool?: DamagePctBySchool;
535
+ critChanceBonus?: number; // flat percentage points to add to critChance (e.g. 5 for +5%)
536
+ procs?: ProcDef[];
537
+ // Gear procs (ItemDef.procs) collected at buildCombatant time for the on-hit/on-equip engine (E1).
538
+ gearProcs?: Array<{
539
+ spell: number;
540
+ trigger: number;
541
+ chancePct?: number;
542
+ ppm?: number;
543
+ flags?: number;
544
+ procEx?: number;
545
+ cooldownMs?: number;
546
+ schoolMask?: number;
547
+ spellFamilyName?: number;
548
+ spellFamilyMask?: number[];
549
+ }>;
550
+ // Advertised generic spell damage, read only when the spell has effectBonusCoefficient*; absent
551
+ // or 0 leaves the baked min/max path unchanged. Cite: Unit.cpp SpellBaseDamageBonusDone ~7129.
552
+ spellPower?: number;
553
+ // Per-school flat +spell damage; benefit = spellPower + spellDamageBySchool[school].
554
+ // Cite: Unit.cpp SpellBaseDamageBonusDone mask ∩ school.
555
+ spellDamageBySchool?: Partial<Record<School, number>>;
556
+ // Flat +healing done (SIE healing_power / equipMods healing_done).
557
+ // Cite: SpellAuras.cpp HandleModHealingDone; KI-590.
558
+ healingPower?: number;
559
+ // SPELLMOD_RADIUS (op 6) mods this unit owns, read by `effectiveAreaRadiusYd` for every area aura
560
+ // and totem it owns. Cite: SpellAuras.cpp:307–309; Spell.cpp:7550.
561
+ radiusSpellMods?: SpellMod[];
562
+ // Lasting SPELL_AURA_ADD_*_MODIFIER owned at pull; charged next-cast auras stay on
563
+ // startPendingSpellMod. Cite: Player.cpp AddSpellMod.
564
+ startOwnedSpellMods?: OwnedSpellMod[];
565
+ spells: SpellDef[];
566
+ items?: CombatItem[]; // consumables usable mid-fight (health/mana potion, healthstone, mana gem)
567
+ // Live bag counts for CheckItems / TakeReagents, decremented into itemsConsumed on a successful
568
+ // cast; absent on NPCs without bags. Cite: Spell.cpp CheckItems ~6560; TakeReagents ~4332.
569
+ bagItemCounts?: Record<number, number>;
570
+ /** Paperdoll item entries. Rotation `itemEquipped` reads this; absent → 0. */
571
+ equippedItemEntries?: readonly number[];
572
+ /** Active shapeshift form id at fight start (0 / absent = humanoid). */
573
+ form?: ShapeshiftFormId;
574
+ // Parallel mana pool for Druid multi-power: mirrors startPower when the active power is mana,
575
+ // else holds the mana bar for form costs and the dual-bar UI.
576
+ mana?: number;
577
+ maxMana?: number;
578
+ /** Base/create mana for ManaCostPercentage form costs (player_classlevelstats.basemana). */
579
+ createMana?: number;
580
+ // Base/create health for POWER_HEALTH ManaCostPercentage (player_classlevelstats.basehp).
581
+ // Cite: Spell.cpp CalculatePowerCost POWER_HEALTH (Bloodrage).
582
+ createHealth?: number;
583
+ /** Gear weapon speed (ms) before any form override — restored on leave form. */
584
+ baseWeaponSpeedMs?: number;
585
+ /** Gear weapon min damage before any form override — restored on leave form. */
586
+ baseWeaponDmgMin?: number;
587
+ /** Gear weapon max damage before any form override — restored on leave form. */
588
+ baseWeaponDmgMax?: number;
589
+ // Start the fight already stealthed. `spellId` is the aura that granted it, and without it
590
+ // breakStealth cannot fade the chip seedDisplayAuras put on the frame.
591
+ stealth?: { spellId?: number; strength: number; levelBonus?: number; breakFlags?: number };
592
+ /** Passive MOD_STEALTH_LEVEL when not bundled into stealth.levelBonus. */
593
+ stealthLevelBonus?: number;
594
+ /** Detector strength on this unit (Perception etc. if pre-applied). */
595
+ stealthDetectStrength?: number;
596
+ // Spirit for OCT mana regen; absent → no combat mana regen.
597
+ // Cite: Player::UpdateManaRegen / OCTRegenMPPerSpirit.
598
+ spirit?: number;
599
+ /** Flat MP5 from gear/auras (SPELL_AURA_MOD_POWER_REGEN total over 5s). */
600
+ mp5?: number;
601
+ // SPELL_AURA_MOD_MANA_REGEN_INTERRUPT percent (0–100).
602
+ // Classic baseline 0 → the 5SR window allows only mp5.
603
+ manaRegenInterruptPct?: number;
604
+ // Product of (100+amount)/100 over OOC SPELL_AURA_MOD_POWER_REGEN_PERCENT (110) auras; default 1.
605
+ // Cite: StatSystem.cpp:551–552; KI-424.
606
+ manaRegenPctMult?: number; healthRegenDuringCombatPct?: number; // aura116 KI-898
607
+ // Product of (100+amount)/100 over SPELL_AURA_MOD_HEALTH_REGEN_PERCENT (88) auras; default 1.
608
+ // OOC only, exactly as the C++ gates it. Cite: Player.cpp:2393-2398.
609
+ healthRegenPctMult?: number;
610
+ // GetResistancePenetration per school (positive values); physical → armor pen, magic → resist pen.
611
+ // Cite: Unit.cpp GetResistancePenetration ~3890.
612
+ resistancePenetration?: Partial<Record<School, number>>;
613
+ // SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS (102) — flat AP vs a creature-type mask, applied in
614
+ // MeleeDamageBonusDone as APbonus rather than sheet AP. Cite: Unit.cpp:7476.
615
+ attackPowerVersus?: Array<{ creatureTypeMask: number; amount: number }>;
616
+ // SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS (131). Cite: Unit.cpp:7471.
617
+ rangedAttackPowerVersus?: Array<{ creatureTypeMask: number; amount: number }>;
618
+ // SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS (180). Cite: Unit.cpp:7055.
619
+ spellDamageVersus?: Array<{ creatureTypeMask: number; amount: number }>;
620
+ // SPELL_AURA_MOD_DAMAGE_DONE_VERSUS (168) — whole-percent multiplier vs a creature-type mask.
621
+ // Cite: Unit.cpp:7058, :7503.
622
+ damageDoneVersusPct?: Array<{ creatureTypeMask: number; amount: number }>;
623
+ // SPELL_AURA_MOD_DAMAGE_DONE_CREATURE (59) — flat melee DoneFlat vs a creature-type mask; the
624
+ // spell path folds the same rows into spellDamageVersus. Cite: Unit.cpp:7465; KI-1043.
625
+ damageDoneCreature?: Array<{ creatureTypeMask: number; amount: number }>;
626
+ // SPELL_AURA_MOD_CRIT_PERCENT_VERSUS (169) — whole percent onto the crit multiplier vs a
627
+ // creature-type mask. Cite: Unit.cpp:3555-3563.
628
+ critDamageVersusPct?: Array<{ creatureTypeMask: number; amount: number }>;
629
+ // SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT (122) — whole percent onto the 0.5 off-hand TOTAL_PCT.
630
+ // Cite: SpellAuras.cpp:4175-4184.
631
+ offhandDamagePct?: number;
632
+ // Victim-side attacker-chance auras (185-188), signed percentage points as the DBC ships them.
633
+ // Cite: Unit.cpp:3525-3528, :3794, :3874.
634
+ attackerMeleeCrit?: number;
635
+ attackerRangedCrit?: number;
636
+ attackerRangedHit?: number;
637
+ /** Aura 186 is mask-bearing, so it is kept per school like its crit twin (179). */
638
+ attackerSpellHitBySchool?: Partial<Record<School, number>>;
639
+ /** OVERRIDE_CLASS_SCRIPTS (112) misc values the sheet carries. Cite: Unit.cpp:11969-11985. */
640
+ overrideScriptIds?: readonly number[];
641
+ // SPELL_AURA_MOD_THREAT multipliers by school (default 1), multiplied with formThreatPct in
642
+ // ApplyTotalThreatModifier. Cite: Unit.cpp ~8626; SpellAuras.cpp HandleModThreat.
643
+ threatModifierBySchool?: Partial<Record<School, number>>;
644
+ // Player-state snapshot for the conditions evaluator, captured at fight start by game.ts.
645
+ // Absent (mobs/tests) → those condition types fail closed. Cite: Conditions.cpp Meets.
646
+ conditionCtx?: {
647
+ /** Reputation rank (0–7) by faction id, precomputed for every baked faction. */
648
+ reputationRanks?: Record<number, number>;
649
+ /** Base skill value by skill line id (professions + weapon/defense). */
650
+ skillValues?: Record<number, number>;
651
+ /** Game event ids active at fight start (GameEventMgr::IsActiveEvent). */
652
+ activeEvents?: number[];
653
+ /** Holidays.dbc ids active at fight start (GameEventMgr::IsActiveHoliday). */
654
+ activeHolidays?: number[];
655
+ /** SharedDefines.h Team: ALLIANCE=469 / HORDE=67. */
656
+ team?: number;
657
+ /** HonorRankInfo.rank 0..18. Cite: Conditions.cpp:236-243 CONDITION_PVP_RANK. */
658
+ pvpRank?: number;
659
+ /** GetVariable map. Cite: Conditions.cpp:496 WORLDSTATE. */
660
+ worldStates?: Record<number, number>;
661
+ };
662
+ }
663
+
664
+ /** A consumable the player can use mid-fight (restore potion or self buff). Built from ItemDef.useInCombat / useBuff / useSpell. */
665
+ export interface CombatItem {
666
+ entry: number;
667
+ name: string;
668
+ /** Real ItemDef.icon basename for UI (action bar / combat strip). */
669
+ icon?: string;
670
+ // Rank-ladder key (domain/items/consumableFamily.ts) and this rung's itemLevel, stamped by
671
+ // `combatItems`. A family row resolves against these; the session holds no DataStore.
672
+ family?: string;
673
+ rank?: number;
674
+ effect:
675
+ | { kind: 'restore_health' | 'restore_power'; min: number; max: number; powerType?: number }
676
+ // Buff consumable (elixir / flask / scroll / drink / on-use trinket). mod+amount is the PRIMARY
677
+ // mod only; a multi-effect item rides its SpellDef so itemUse casts it whole via castOnTargets.
678
+ | { kind: 'apply_buff'; mod: BuffMod; amount: number; durationMs: number; spellId?: number; spell?: SpellDef }
679
+ // A thrown/offensive item (grenades, Tidal Charm, Slumber Sand), carrying the resolved SpellDef so
680
+ // the session routes it through `castOnTargets` — AoE fan, resists, immunities and threat for free.
681
+ | { kind: 'hostile_cast'; spellId: number; spell: SpellDef }
682
+ // A defensive on-use whose payload is an immunity or a cleanse rather than a stat buff: Free
683
+ // Action Potion 5634, Living Action Potion 20008, PvP Insignia 23273/23274/23276/23277.
684
+ | { kind: 'friendly_cast'; spellId: number; spell: SpellDef };
685
+ cooldownMs: number;
686
+ // item_template.spellcategory_N — shared category cooldown (bombs=24, potions=4), honoured via
687
+ // Fighter.categoryCooldowns so throwing one grenade locks the whole category.
688
+ category?: number;
689
+ /** item_template.spellcategorycooldown_N (ms). Bombs: 60000. */
690
+ categoryCooldownMs?: number;
691
+ count: number; // how many are carried into the fight
692
+ // Gear whose use never costs a UNIT: spellcharges_1 == 0 (unlimited) or positive (runs out, item
693
+ // kept). Set by combatItems from that column, never from equippability.
694
+ reusable?: boolean;
695
+ // Charges left on THIS unit (|spellcharges_1| when the row has one). Absent = not charge-based; at 0
696
+ // the item refuses instead of firing. Cite: Spell.cpp:6462 NO_CHARGES_REMAIN; spendKitItem below.
697
+ charges?: number;
698
+ // An on-use that can fail on the user instead of firing: Goblin Rocket Boots roll 8893 and are
699
+ // destroyed into `destroysInto`. Cite: domain/items/rocketBoots.ts.
700
+ malfunction?: { chancePct: number; spell: SpellDef; destroysInto: number };
701
+ }
702
+
703
+ // One kit item, one use: the charge counter drops first, and the UNIT goes only when a destroy-at-zero
704
+ // row runs out. `reusable` gear never loses a unit. Cite: Spell.cpp:4209 TakeCastItem.
705
+ export function spendKitItem(it: CombatItem, spentMap: Map<number, number>): void {
706
+ if (it.charges != null) {
707
+ it.charges = Math.max(0, it.charges - 1);
708
+ if (it.charges > 0 || it.reusable) return;
709
+ } else if (it.reusable) {
710
+ return;
711
+ }
712
+ it.count -= 1;
713
+ spentMap.set(it.entry, (spentMap.get(it.entry) ?? 0) + 1);
714
+ }
715
+
716
+ /** The player's chosen action for a tick: a spell id, a dest-bearing ground cast, an item use, or nothing. */
717
+ export type CombatAction =
718
+ | number
719
+ | {
720
+ spell: number;
721
+ dest?: CombatPosYd;
722
+ after?: RuleAfter;
723
+ // Cast at a living hostile that is not the focus and is not already CC'd (sheep the second
724
+ // mob). No such hostile ⇒ skip the spell.
725
+ offTarget?: boolean;
726
+ // Aim a friendly cast at this ally instead of letting triage pick. Ignored for hostile spells,
727
+ // and dropped if that unit is dead or out of the caster's friendly pool.
728
+ ally?: CombatantId;
729
+ }
730
+ | { item: number; target?: CombatantId }
731
+ | null;
732
+
733
+ // Ally pick for a tick: spell id, item use, or null. `lowestAlly: true` targets the lowest-HP
734
+ // living friendly, the same semantics as the player's item-rule `lowest_ally` selector.
735
+ export type AllyCombatAction =
736
+ | number
737
+ // `offTarget: true` casts at a living hostile that is not this unit's focus and is not already
738
+ // crowd-controlled; no such hostile ⇒ the rule is skipped rather than redirected onto the focus.
739
+ | {
740
+ spell: number;
741
+ after?: RuleAfter;
742
+ offTarget?: boolean;
743
+ ally?: CombatantId;
744
+ dest?: CombatPosYd;
745
+ creatureEntry?: number;
746
+ role?: 'tank' | 'healer' | 'damage';
747
+ /** RuleSpellTarget `{ priority }` — first living of these creature_template.entry ids. */
748
+ priority?: readonly number[];
749
+ /** RuleSpellTarget `{ allyMissingAura }` — nearest living friendly not holding this aura. */
750
+ allyMissingAura?: number;
751
+ /** RuleSpellTarget `{ lowestHp }` — pin the lowest-HP living friendly. */
752
+ lowestAlly?: boolean;
753
+ /** `{ lowestHp, among }` / `{ allyMissingAura, among }` — narrow to role / class / one seat. */
754
+ among?: AllyFilter;
755
+ }
756
+ | { item: number; target?: CombatantId; lowestAlly?: boolean; among?: AllyFilter }
757
+ // A mechanic run-out. `altSpell` is what the rotation would have cast without that row, fired
758
+ // only when it is instant, because movement cancels a cast with time left on it.
759
+ | { move: RuleMove; altSpell?: number }
760
+ | { haltDps: true; school?: HaltDpsSchool; entries?: readonly number[] }
761
+ | { useObject: number }
762
+ | null;
763
+
764
+ // Which O(roster) snapshot fields a provider's rotation can actually read, stamped on the closure
765
+ // at build time so allySnapshot skips a row this unit never reads. Absent ⇒ assume everything.
766
+ export interface ProviderNeeds {
767
+ /** metric `nearbyAlliesBelowHpCount` → allyDistHp */
768
+ allyDistHp: boolean;
769
+ /** metric `allyLowestBuffPresent` → allyTriageBuffs */
770
+ allyTriageBuffs: boolean;
771
+ /** any condition with `subject: 'ally'` → allySubject (one aura walk per filter per tick) */
772
+ allySubject: boolean;
773
+ /** metric `charmedHostileCount` */
774
+ charmedHostileCount: boolean;
775
+ /** metric `enemiesWithinYd` with subject `target` → enemyDistsFromTarget */
776
+ enemyDistsFromTarget: boolean;
777
+ /** metric `enemiesWithinYd` on self → enemyDists (PBAoE density at the caster) */
778
+ enemyDists: boolean;
779
+ /** metric `enemyHealersWithinYd` → enemyHealerDists */
780
+ enemyHealerDists: boolean;
781
+ /** metric `hasAggro` */
782
+ hasAggro: boolean;
783
+ /** metric `enemyCastingOnAlly` — walks the hostiles' threat tables, so it is opt-in */
784
+ enemyCastingOnAlly: boolean;
785
+ /** metric `enemyCastingOnSelf` — same walk, vid === acting unit */
786
+ enemyCastingOnSelf: boolean;
787
+ /** any `kind: 'item'` rule — allySnapshot still fills itemCounts when set */
788
+ items: boolean;
789
+ /** metric `hazardProximityYd` → nearest ground-pool edge yards */
790
+ groundPools: boolean;
791
+ /** metric `inTargetCone` → the target's facing arc test */
792
+ targetCone: boolean;
793
+ /** RuleSpellTarget `{ creatureEntry }` / hostileCreatureEntries snapshot */
794
+ hostileCreatureEntries: boolean;
795
+ // metric `canAfford` → price the acting unit's whole kit. O(kit) per pick, so it stays opt-in the
796
+ // way enemyCastingOnAlly does: no rotation naming the metric, no walk.
797
+ spellCosts: boolean;
798
+ /** metric `dispellablePresent` — walks the friendly and hostile pools for a cure/purge */
799
+ dispellablePresent: boolean;
800
+ /** metric `castingPresent` on subject `target` — walks hostiles for an interruptible add bar */
801
+ kickableCastPresent: boolean;
802
+ /** metric `aggroHolderDebuffPresent` / `aggroHolderDebuffStacks` — tank-swap chips */
803
+ aggroHolder: boolean;
804
+ }
805
+
806
+ // A per-ally combat brain: given a rotation snapshot it returns a spell id, an item use, or null.
807
+ // Composed in engine/game.ts as a closure over the editable Rotation. Must be pure — no rng, no clock.
808
+ export type AllyActionProvider = ((snap: RotationSnapshot) => AllyCombatAction) & {
809
+ needs?: ProviderNeeds;
810
+ // Arm school halt before evaluate. pickAction sets `f.haltDpsSchool` from this so `usableSpell`
811
+ // can refuse the wrong school while a lower rule still casts.
812
+ peekHalt?: (snap: RotationSnapshot) => {
813
+ school: HaltDpsSchool;
814
+ entries?: readonly number[];
815
+ } | null;
816
+ /** Arm kill-order before evaluate. pickAction retargets DPS onto the first living entry. */
817
+ peekKillOrder?: (snap: RotationSnapshot) => readonly number[] | null;
818
+ /** Spell ids this rotation's keep_aura rows forbid auto-dispelling. */
819
+ keepAuraIds?: ReadonlySet<number>;
820
+ };
821
+
822
+ // One `spell_script_target` gameobject an ACTIVATE_OBJECT spell lights, already resolved.
823
+ // Cite: Spell.cpp:2599-2615 CheckScriptTargeting; GameObject.cpp:1513-1532 GAMEOBJECT_TYPE_TRAP Use.
824
+ export interface SpellTrapSite {
825
+ /** The ACTIVATE_OBJECT spell. */
826
+ spellId: number;
827
+ /** The gameobject it names. */
828
+ goEntry: number;
829
+ /** inverseEffectMask: a SET bit means that effect slot may NOT hit this object. */
830
+ inverseEffectMask: number;
831
+ /** trap.spellId payload, already through resolveCombatSpell. */
832
+ spell: SpellDef;
833
+ cooldownMs: number;
834
+ durationMs: number;
835
+ /** The object's own spawn, in COMBAT yards. */
836
+ origin: CombatPosYd;
837
+ }
838
+
839
+ export interface CombatObjectTrap {
840
+ /** The GO a raider clicks. */
841
+ goEntry: number;
842
+ /** buddyEntry the command activates - the trap that fires. */
843
+ buddyEntry: number;
844
+ /** trap.spellId payload, already through resolveCombatSpell. */
845
+ spell: SpellDef;
846
+ /** trap.cooldown re-arm. GameObject.cpp:1532 defaults to 4 s when the field is 0. */
847
+ cooldownMs: number;
848
+ /** How long the activated trap stays live. */
849
+ durationMs: number;
850
+ /** Trap position in COMBAT yards; absent falls back to the clicker's own spot. */
851
+ origin?: CombatPosYd;
852
+ }
853
+
854
+ // Values the game layer supplies WITH each tick, because a sim on another thread cannot reach back for
855
+ // them mid-step (PERF-RUNSHEET S6b mechanism 2). An omitted call keeps the last set given.
856
+ export type SimTickInputs = {
857
+ // Bag entries worth clicking THIS tick. A dark gnomeface button is present but inert and only the
858
+ // game layer knows which. Undefined = every bag entry is actionable. Cite: instance_gnomeregan.cpp:264.
859
+ actionableObjects?: ReadonlySet<number>;
860
+ // Quest entries the player's log currently holds as 'active'. A ScriptDev spell-hit row gated on
861
+ // `requireQuestIncomplete` reads this. Undefined = no log, and such a row stays shut.
862
+ activeQuests?: ReadonlySet<number>;
863
+ // Per-ally companion knobs, keyed by side. The provider used to read these off a LIVE companion ref
864
+ // it closed over; a worker cannot hold one, so they ride in. Cite: PERF-RUNSHEET S6b.
865
+ companionKnobs?: ReadonlyMap<string, { aoeMode: number; offHeal: boolean }>;
866
+ };
867
+
868
+ export interface CombatConfig {
869
+ tickMs?: number;
870
+ sitting?: boolean;
871
+ maxMs?: number;
872
+ // A killing blow on either duelist floors HP at 1 and ends the fight instead of killing; a pet is
873
+ // TYPEID_UNIT with no duel pointer and dies normally. Cite: Unit.cpp:966-978 DealDamage.
874
+ duel?: boolean;
875
+ // Per-ally action providers, index-aligned with `allySpecs`. A missing or null slot falls back to
876
+ // the role-branched heuristics for that ally; solo sessions ignore this.
877
+ allyActionProviders?: readonly (AllyActionProvider | null | undefined)[];
878
+ // The player's own rotation, for the ticks the engine drives them: same closure type and
879
+ // evaluator as an ally's. Absent → the engine heuristics.
880
+ playerActionProvider?: AllyActionProvider | null;
881
+ // Per-enemy action providers, index-aligned with `enemySpecs`. A missing or null slot keeps the
882
+ // class heuristics for that body; absent → never consulted.
883
+ enemyActionProviders?: readonly (AllyActionProvider | null | undefined)[];
884
+ // Companion → pet mapping, index-aligned with the human companions in `allySpecs`: the ally index
885
+ // of that companion's pet, or null when they have none. Pet allies themselves are not listed.
886
+ allyPetIndex?: readonly (number | null | undefined)[];
887
+ // SPELL_ATTR_SCALES_WITH_CREATURE_LEVEL multiplies a creature-cast amount by BaseDamage(caster) /
888
+ // BaseDamage(spell); absent means creature spells keep their baked numbers. Cite: Object.cpp:3005.
889
+ creatureBaseDamageAt?: (level: number, unitClass: number) => number | undefined;
890
+ // The rank ladder (2,212 baked rows) that aura identity needs: a higher rank of the same chain
891
+ // refuses the apply, a different rank replaces its sibling. Cite: Unit.cpp:5014-5017.
892
+ spellChainOf?: (spellId: number) => { first: number; rank: number } | undefined;
893
+ // Spell 1604 Dazed, the -50% snare an NPC white hit from behind lands on a player; absent = no
894
+ // daze. Cite: Unit.cpp:2227 CastSpell(victim, 1604); :3124 CanDazeInCombat.
895
+ dazeSpell?: SpellDef;
896
+ // `SpellEntry.AuraInterruptFlags` by spell id (582 of 22,374 rows), needed because a live holder
897
+ // is an `effects` row with a spell id, not a SpellDef. Cite: Unit.cpp:5197.
898
+ auraInterruptFlagsOf?: (spellId: number) => number;
899
+ // The global spell store, so a triggered payload resolves by id instead of by membership in the
900
+ // caster kit. Cite: Unit.cpp:1447-1449 sSpellTemplate.LookupEntry.
901
+ spellOf?: (id: number) => SpellDef | undefined;
902
+ /** Seeded remainings (ms) at the start of this session (t=0) for persisting long CDs across fights / from OOC. */
903
+ initialSpellCooldowns?: Record<number, number>;
904
+ initialCategoryCooldowns?: Record<number, number>;
905
+ // Encounter distance (yards) for the stealth detect formula on pull; absent = skip detect. Legacy
906
+ // single-distance EVENT_T_RANGE fallback. Cite: ObjectVisibility.cpp GetStealthVisibilityDistance.
907
+ encounterDistanceYd?: number;
908
+ // Per-combatant yards from pull origin: pairwise EVENT_T_RANGE, rangeMax, AoE fan, pool radius.
909
+ // Seeded from the pack layout, never RNG. Cite: docs/dungeons/PACK-COMBAT-VISION.md §7.
910
+ unitPositionsYd?: UnitPositionsYd;
911
+ // PvP match session: deaths bench units but NEVER end it — only `maxMs` or the caller does.
912
+ // Pair with `reviveUnit` for graveyard cycles.
913
+ endless?: boolean;
914
+ // `Map::IsDungeon()`, supplied by the caller. Gates far-evade despawn: outdoors a mob dragged
915
+ // 150 yd from home despawns, in a dungeon it walks back. Cite: HomeMovementGenerator.cpp:52-62.
916
+ dungeonMap?: boolean;
917
+ // `Map::IsBattleGround()` — gates only the stealth detect cadence (500 ms vs 2000 ms).
918
+ // Absent = world/dungeon. Cite: Player.cpp:1546.
919
+ battlegroundMap?: boolean;
920
+ // RTS hand mode: friendly AI gap-close may only move within this radius of the unit's anchor,
921
+ // and beyond it walks back. Enemies unaffected. Absent → dungeon chase behaviour.
922
+ friendlyHoldYd?: number;
923
+ // The party bubble: a friendly with no target inside `acquireRangeYd` walks back to the player
924
+ // until it is this close (sessionFollow.ts advancePartyFollow). Also caps how far a TANK's peel
925
+ // scan may look for a mob eating someone else (sessionFocus.ts:180).
926
+ partyFollowYd?: number;
927
+ // Local target acquisition (BG + endless): auto-acquire only hostiles within this many yards,
928
+ // nearest first. Product 45; absent → full-list, order-first. Cite: World.cpp visibility floor 45.
929
+ acquireRangeYd?: number;
930
+ // BG: a hard-CC'd unit with an idle action auto-pops a bag item whose immunity cancels the control
931
+ // (PvP Insignia / Free Action Potion), the same CheckCasterAuras exemption. Absent → manual only.
932
+ autoRescueItems?: boolean;
933
+ /**
934
+ * The enemy side is a TEAM of player-shaped seats (an arena match), not a mob pack, so its seats
935
+ * pick a target the way the player faction does — `preferFocusHostile`, healers first — instead of
936
+ * off the creature threat list. Absent → threat, which is what every dungeon and raid pull wants.
937
+ * Measured at 3v3 without it: side A put 42% of its damage on the enemy HEALER and side B only
938
+ * 18%, and B's healer died first in 4 of 5 mirrors (`repro-arena-seat-gap.mjs`).
939
+ */
940
+ enemiesAreATeam?: boolean;
941
+ /**
942
+ * DEV ONLY. Pass a Map and `allySnapshot` stores the last snapshot it built for each side — the
943
+ * only way to read a NON-LEAD or enemy-side seat's rotation CONDITION values. The seat's CAST
944
+ * gates are `session.abilitiesFor(side)`, which is a different question. Absent, nothing is
945
+ * written and a normal fight pays one branch. Cite: arena-setup-wars.md §W11 link 1.
946
+ */
947
+ snapshotCapture?: Map<string, unknown>;
948
+ // Which frame `unitPositionsYd` live in, set by the product seeder from the layout it produced.
949
+ // Absent means `pull-local`, which forbids a renderer pinning offsets to world coordinates.
950
+ geometryAnchor?: PullGeometryAnchor;
951
+ // Motion clamps to the walkable surface but never runs A*: one `isWalkable` per unit per tick,
952
+ // at the price of a greedy wall-slide that `noProgressStuck` gives up on after 1 s.
953
+ navClampOnly?: boolean;
954
+ // Hostile casts require `losClear`. Default false, so a false LOS reading cannot freeze a
955
+ // dungeon pull.
956
+ navLos?: boolean;
957
+ // Whether this pull sits under open sky, gating SPELL_ATTR_ONLY_OUTDOORS. Absent means outdoors,
958
+ // as TerrainInfo::IsOutdoors does. Cite: Spell.cpp:4604-4612; GridMap.cpp:892-903.
959
+ outdoors?: boolean;
960
+ // AttackStart-equivalent: put the player on every enemy threat list at t=0. Default false, so a
961
+ // mob you have not touched does not move; the endless floor forces it false.
962
+ seedAttackStart?: boolean;
963
+ // Team match (arena): an enemy whose threat list empties re-opens on the nearest living hostile
964
+ // instead of standing down. Default false — a CREATURE with an empty list is meant to stand down
965
+ // and walk home. Cite: sessionFocus.ts reacquireEmptyThreat.
966
+ reacquireOnEmptyThreat?: boolean;
967
+ // GameObject entries present in this fight, one slot per baked spawn; a `use_object` rotation
968
+ // click consumes one matching entry. Cite: dungeonGameObjects.
969
+ combatObjects?: readonly number[];
970
+ // Bag entries a click does not spend: a button resets to its default state instead of despawning,
971
+ // so Thermaplugg's six faces stay pressable all fight. Cite: GameObject.cpp:1458.
972
+ combatObjectsReusable?: readonly number[];
973
+ // The main-thread supplier of `SimTickInputs`, called ONCE at the top of each step. Off-thread the
974
+ // caller passes the same shape to `tick(action, inputs)` instead; exactly one of the two exists.
975
+ tickInputs?: () => SimTickInputs;
976
+ // Where each bag entry stands in combat yards, so a clicker walks to it instead of pressing it
977
+ // from across the room. Absent = no site, and the click needs no walk.
978
+ combatObjectSites?: readonly { goEntry: number; origin: CombatPosYd }[];
979
+ /** Fired after a successful combat GO click (game layer may call useInstanceObject). */
980
+ // Apply one recorded effect. Called at the END of a step, never from inside the tick, so the sim
981
+ // can run where these writes are unreachable (S6b mechanism 1). Replaced the five `on*` closures.
982
+ applyEffect?: (effect: import('./simEffects.ts').SimEffect) => void;
983
+ // Traps the clickable combat GOs activate, resolved by the game layer off the bake; `applySpell`
984
+ // reads `src.spec.spells` and cannot reach a trap that belongs to a gameobject.
985
+ combatObjectTraps?: readonly CombatObjectTrap[];
986
+ // Traps a cast activates, one row per named gameobject. `spell_script_target` and
987
+ // `gameobject_template` are unreachable from a pure engine module, so the sites arrive resolved.
988
+ spellTrapSites?: readonly SpellTrapSite[];
989
+ // CallAssistance: ms after a creature enters combat before its pack neighbours join (core default
990
+ // 1500). Who joins is decided at pull build. Cite: Unit.cpp:7993; Creature.cpp:2163.
991
+ packAssistDelayMs?: number;
992
+ // Baked `conditions` rows by id so spells carrying only a conditionId resolve.
993
+ // Absent → conditionId-gated spells fail closed.
994
+ conditionTable?: import('../spells/conditions.ts').ConditionTable;
995
+ // EventAI summon inject: resolve a summoned creatureId → CombatantSpec.
996
+ // Cite: CreatureEventAI.cpp ACTION_T_SPAWN / SUMMON_ID SummonCreature.
997
+ resolveSummon?: (creatureId: number) => CombatantSpec | null;
998
+ // combat_condition / unit_condition lookups for the creature_spell_list gate; absent leaves every
999
+ // gated row open. Cite: UnitAI.cpp:1218-1224 UpdateSpellLists.
1000
+ combatConditionTable?: {
1001
+ combatCondition: (id: number) => CombatConditionDef | undefined;
1002
+ unitCondition: (id: number) => UnitConditionDef | undefined;
1003
+ };
1004
+ // Seed for ACTION_T_SET_INST_DATA; ScriptDev instance scripts read the same store.
1005
+ // Cite: CreatureEventAI.cpp ACTION_T_SET_INST_DATA ~1044–1054.
1006
+ instanceData?: Record<number, number>;
1007
+ // After OnCreatureDeath → applyInstanceSetData: persist the store and stamp openDoors onto
1008
+ // goRuntime. Cite: sunken_temple.cpp:162-178 TYPE_PROTECTORS + GO 149431.
1009
+
1010
+ // ACTION_T_QUEST_EVENT credit hook; the caller applies recordEventHappens, and group credit when
1011
+ // rewardGroup. Cite: CreatureEventAI.cpp ~847–862; Player.cpp AreaExploredOrEventHappens.
1012
+
1013
+ // Is this quest still incomplete? Some ScriptDev SpellHit rows only fire while their quest is
1014
+ // open; absent → the gate stays shut. Cite: stranglethorn_vale.cpp:55-64.
1015
+ // `isQuestIncomplete` used to sit here. It is `SimTickInputs.activeQuests` now (S6b mechanism 2).
1016
+ // ACTION_T_KILLED_MONSTER (33) credits an entry that is not the one that died; absent = inert.
1017
+ // Cite: CreatureEventAI.cpp ProcessAction case 33.
1018
+
1019
+ // ACTION_T_START_RELAY_SCRIPT (53) hands a `dbscripts_on_relay` id to the host; absent = the relay
1020
+ // is only logged. Cite: CreatureEventAI.cpp:1225-1244 ScriptsStart(SCRIPT_TYPE_RELAY, …).
1021
+
1022
+ // SPELL_EFFECT_PICKPOCKET in a live fight: grants loot and gold without breaking stealth, and
1023
+ // returns both for the event text. Cite: SpellEffects.cpp EffectPickPocket; KI-612.
1024
+ onPickPocket?: (creatureEntry: number) => {
1025
+ ok: boolean;
1026
+ drops?: { item: number; count: number }[];
1027
+ goldCopper?: number;
1028
+ reason?: string;
1029
+ };
1030
+ }
1031
+
1032
+ export interface CombatResult {
1033
+ events: CombatEvent[];
1034
+ // Scripted-mechanic counts for the whole fight, tallied at push time, so unlike the 8192-row
1035
+ // `events` ring this still reports a boss's early phase transitions. Absent when nothing fired.
1036
+ mechanics?: Record<string, { count: number; firstT: number; lastT: number }>;
1037
+ // Damage that landed, keyed by the side that took it, plus `_unattributed` for rows with no
1038
+ // target. Push-time like `mechanics`, because anything derived from `events` undercounts.
1039
+ damageTakenBySide?: Record<string, number>;
1040
+ // Every death in order with the killing blow that caused it, tallied at push time so an early
1041
+ // wipe death survives the ring. Capped at 512 rows; `deathsTotal` counts them all.
1042
+ deaths?: { side: string; name: string; t: number; by?: string; byName?: string; cause?: string }[];
1043
+ deathsTotal?: number;
1044
+ // Rows the session event ring discarded. Non-zero means `events`, and anything read off it,
1045
+ // covers only the tail of the fight.
1046
+ eventsDropped?: number;
1047
+ winner: Side | 'timeout';
1048
+ durationMs: number;
1049
+ player: {
1050
+ hp: number;
1051
+ power: number;
1052
+ /** Ending form id (0/absent = humanoid). */
1053
+ form?: ShapeshiftFormId;
1054
+ /** Ending mana (parallel pool for multi-power / always for mana users). */
1055
+ mana?: number;
1056
+ powerType?: PowerType;
1057
+ // Ending combat skill map after mid-fight gains (only when the fight started with combatSkills).
1058
+ // Applied onto Character.combatSkills in resolveFight.
1059
+ combatSkills?: Partial<Record<number, { current: number; max: number }>>;
1060
+ };
1061
+ /** Absent when the session held no primary enemy (continuous floor run). E1.3. */
1062
+ enemy?: {
1063
+ hp: number;
1064
+ power: number;
1065
+ // Primary enemy's creatureEntry at fight end. After a scriptdev UpdateEntry morph (Dathrohan →
1066
+ // Balnazzar) loot, XP and kill credit follow the final form, not the pulled template.
1067
+ finalCreatureEntry?: number;
1068
+ };
1069
+ itemsConsumed?: { entry: number; count: number }[]; // player in-combat consumables spent, to remove from bags
1070
+ // Charges left on surviving charged units (spellcharges_1 < -1), written back onto the bag stack or
1071
+ // the worn instance. Cite: Spell.cpp:4209 TakeCastItem; domain/items/inventory.ts.
1072
+ itemChargesLeft?: { entry: number; charges: number }[];
1073
+ // Items a fight PUT in the player's bags: a Rocket Boots malfunction leaves Scorched Rocket Boots
1074
+ // where the boots were. Cite: src_spell_template 8893 EffectItemType3 = 7190.
1075
+ itemsGained?: { entry: number; count: number }[];
1076
+ // M7: consumables spent by allies (ally_0 → index 0). Debited from companion bags in
1077
+ // resolveFight, never from the player's inventory.
1078
+ allyItemsConsumed?: { allyIndex: number; entry: number; count: number }[];
1079
+ // The mirror of `itemsGained` for a companion: a Drain Soul kill puts a Soul Shard in its own bag.
1080
+ allyItemsGained?: { allyIndex: number; entry: number; count: number }[];
1081
+ // Pet's ending vitals, to carry back onto the character. `unsummoned` marks the owner's death
1082
+ // taking it (RemovePet), so `hp` is what it left with and the writeback must not read a slaying.
1083
+ pet?: { hp: number; power: number; unsummoned?: boolean } | null;
1084
+ soulShardsGained?: number; // warlock: 1 per Drain Soul kill that had the DoT active
1085
+ /** Ally ending vitals in ally_0.. order. Present only when the session had allies. */
1086
+ allies?: { hp: number; power: number }[];
1087
+ }
1088
+
1089
+ /** Live view of a combatant for the UI (unit frames + cast bar). */
1090
+ export interface CombatantView {
1091
+ // WHICH SEAT this row is, so a reader never recomputes `enemySideAt(i)` from its own loop index
1092
+ // and reads a filtered view against the wrong seat. Cite: ENGINE-REBUILD E1.1.
1093
+ side: Side;
1094
+ name: string;
1095
+ // Creature template entry for an NPC combatant (absent for the player). Without it every pack
1096
+ // member drew the primary's icon. Cite: docs/archive/TACTICAL-VIEW-RUNSHEET.md T3.
1097
+ creatureEntry?: number;
1098
+ // UNIT_FIELD_LEVEL — the level SelectLevel rolled for this body, so a frame can print it
1099
+ // without re-reading the template's min/max. Cite: combatEnemySpec.ts:42 buildEnemySpecFromCreature.
1100
+ level: number;
1101
+ /** True on an ally seat holding one of OUR summons — the map draws it as a minion. */
1102
+ summoned?: boolean;
1103
+ /** UNIT_FIELD_MOUNTDISPLAYID. Spread-omitted when 0. Cite: Unit.cpp:7748. */
1104
+ mountDisplayId?: number;
1105
+ mounted?: boolean;
1106
+ /** Party job (tank/healer/damage) — absent for solo player/pet/enemies. */
1107
+ groupRole?: GroupRole;
1108
+ /** 0-based raid subgroup; omitted for group 0, so read it as `subgroup ?? 0`. */
1109
+ subgroup?: number;
1110
+ /** Present ('ranged') only for units in ranged attack mode; melee is the omitted default. */
1111
+ attackMode?: 'ranged';
1112
+ hp: number;
1113
+ maxHp: number;
1114
+ power: number;
1115
+ maxPower: number;
1116
+ powerType: PowerType;
1117
+ // `school`/`isHeal` describe the in-flight cast so rotations can gate interrupts without a
1118
+ // DataStore lookup. `channeled` drains the bar from full and puts `endsAt` at the channel end.
1119
+ casting: {
1120
+ spellId: number; name: string; startedAt: number; endsAt: number;
1121
+ school?: School; isHeal?: boolean; channeled?: true;
1122
+ } | null;
1123
+ rooted: boolean;
1124
+ // The active crowd-control on this combatant (most-severe: stun > fear > incapacitate > silence
1125
+ // > disarm), for the UI badge + "you can't act" banner; null when free. (Root is `rooted` above.)
1126
+ controlled: { control: ControlKind; until: number } | null;
1127
+ mode: 'melee' | 'ranged'; // which auto-attack is active: melee (Attack) or ranged/wand (Shoot)
1128
+ /** Present (true) only on an enemy with a live threat table — floor passives omit it. */
1129
+ engaged?: boolean;
1130
+ /** Present (true) only while untargetable/immune mid-mechanic — floor leash holds on it. */
1131
+ unattackable?: boolean;
1132
+ // `stacks` is present only when the aura is stacked above 1 (Sunder Armor x5); `charges` is the
1133
+ // remaining SpellEntry.procCharges (Inner Fire 20, Lightning Shield 3).
1134
+ buffs: Array<{ spellId: number; remainingMs?: number; stacks?: number; charges?: number }>;
1135
+ debuffs: Array<{ spellId: number; remainingMs?: number; stacks?: number; charges?: number }>;
1136
+ /** Combo points this fighter currently has on its combo target (0..5). Rogue/feral. */
1137
+ comboPoints?: number;
1138
+ /** Active shapeshift form id (0 = none). */
1139
+ form?: ShapeshiftFormId;
1140
+ // Spell id that entered the current form, for the RemoveAurasDueToSpell reverse.
1141
+ // Absent or 0 when the form is none or not owned by a spell.
1142
+ formSpellId?: number;
1143
+ /** Parallel mana for dual-bar display (Druid). Present when maxMana is set. */
1144
+ mana?: number;
1145
+ maxMana?: number;
1146
+ /** True while MOD_STEALTH is active. */
1147
+ stealthed?: boolean;
1148
+ /** Combined stealth strength (aura 16 + 154) for UI / debug. */
1149
+ stealthStrength?: number;
1150
+ /** Live melee AP (includes form package + Cat AGI when shapeshifted). */
1151
+ attackPower?: number;
1152
+ /** Live armor (includes form MOD_BASE_RESISTANCE_PCT package when shapeshifted). */
1153
+ armor?: number;
1154
+ /** Hands with an active TEMP weapon enchant (imbue / poison). */
1155
+ weaponImbueHands?: Array<'mainhand' | 'offhand'>;
1156
+ /** True within 5s of this combatant DODGING a melee swing (Overpower-style gates). */
1157
+ dodgedRecently?: boolean;
1158
+ /** CMaNGOS CreatureType (1 Beast, 3 Demon, 6 Undead, 7 Humanoid, …). Rotation creatureTypeMask gates. */
1159
+ creatureType?: number;
1160
+ // Auto-attack is on, with `mode` saying melee or ranged. Read by `/startattack` and by
1161
+ // `/cast !Attack`, which must not toggle a swing already running.
1162
+ autoAttack?: boolean;
1163
+ // True within 5s of this combatant setting AURA_STATE_DEFENSE: its own dodge (not rogues), parry
1164
+ // (not hunters) or block. Cite: UnitAuraProcHandler.cpp:296-328.
1165
+ defenseReactRecently?: boolean;
1166
+ // True within 5s of this combatant setting AURA_STATE_HUNTER_PARRY, which is Counterattack's
1167
+ // gate. Cite: UnitAuraProcHandler.cpp:310-316.
1168
+ hunterParryRecently?: boolean;
1169
+ }
1170
+
1171
+ /** How long a dodge stays "recent" for dodge-reactive attacks (classic Overpower: 5 sec). */
1172
+ export const RECENT_DODGE_MS = 5000;
1173
+
1174
+ // PvP combat flag duration after the last combat touch.
1175
+ // Cite: CombatManager.cpp:192 `m_combatTimer = pvp ? 5000 : m_owner->GetPursuit()`.
1176
+ export const PVP_COMBAT_TIMER_MS = 5000;
1177
+
1178
+ /** How long a dodge/parry/block stays "recent" for defense-react attacks (classic Revenge: 5 sec). */
1179
+ export const RECENT_DEFENSE_REACT_MS = 5000;
1180
+
1181
+ // Healer-ally triage threshold: heal the lowest friendly below this HP fraction. A heuristic, not a
1182
+ // sourced formula — rotations replace it with editable gates.
1183
+ export const ALLY_HEAL_THRESHOLD = 0.75;
1184
+
1185
+ /** An ability offered on the action bar, with its current usability. */
1186
+ export interface AbilityStatus {
1187
+ spell: SpellDef;
1188
+ usable: boolean;
1189
+ reason?: string;
1190
+ cooldownRemainingMs: number;
1191
+ queued?: boolean; // an on-next-swing ability that's armed and waiting for your next swing
1192
+ }
1193
+
1194
+ /** A usable in-combat item, with its current usability (mirrors AbilityStatus). */
1195
+ export interface CombatItemStatus {
1196
+ item: CombatItem;
1197
+ usable: boolean;
1198
+ reason?: string;
1199
+ cooldownRemainingMs: number;
1200
+ count: number;
1201
+ }
1202
+
1203
+ export interface ActiveEffect {
1204
+ kind: 'dot' | 'buff' | 'root' | 'cc' | 'restore_health' | 'restore_power' | 'damage_shield' | 'proc_trigger_spell' | 'school_absorb' | 'mana_shield' | 'immunity' | 'speed' | 'reflect' | 'resist' | 'mod_taunt' | 'spell_magnet';
1205
+ source: Side;
1206
+ target: Side;
1207
+ spellId: number;
1208
+ name: string;
1209
+ school?: School;
1210
+ min?: number;
1211
+ max?: number;
1212
+ nextTickAt?: number;
1213
+ tickMs?: number;
1214
+ amountPerTick?: number;
1215
+ // When set, restore_health/power ticks use floor(max × pctOfMax / 100) instead of flat
1216
+ // amountPerTick (SPELL_AURA_OBS_MOD_HEALTH/MANA). Cite: SpellAuras PeriodicTick.
1217
+ pctOfMax?: number;
1218
+ // restore_power: the Powers index this row fills (0 mana … 3 energy). Absent reads as mana, so a
1219
+ // rage or energy bearer gets nothing rather than the wrong pool. Cite: SpellAuras.cpp:4836-4844.
1220
+ powerType?: number;
1221
+ /** damage_shield / proc_trigger_spell: next time this may retaliate. */
1222
+ nextProcAt?: number;
1223
+ /** damage_shield / proc_trigger_spell: internal proc CD (ms). */
1224
+ cooldownMs?: number;
1225
+ /** proc_trigger_spell: EffectTriggerSpell (or CMaNGOS override) id. */
1226
+ triggerSpellId?: number;
1227
+ // Aura-removal bodies. Present → this row is a pure holder: it never procs and never ticks, it
1228
+ // only fires when the aura goes away. Cite: SpellAuras.cpp HandleAuraDummy(!apply).
1229
+ onRemove?: readonly import('../../data/schema.ts').AuraRemoveBody[];
1230
+ // Judgement of Light target debuff: heal the striker on a landed melee hit. Applied directly
1231
+ // because the 5373 intermediate and its heal rows are absent from the bake. Cite: Paladin.cpp.
1232
+ onHitHeal?: number;
1233
+ // Judgement of Wisdom target debuff: restore mana to the striker on a landed melee hit.
1234
+ // Cite: Paladin.cpp JudgementOfWisdomIntermediate; Spell.sql energize carriers (20268…).
1235
+ onHitMana?: number;
1236
+ // Aura-42 / talent-style proc match, filtering deal-side (Seal of Justice) from take-side (Touch
1237
+ // of Weakness). Cite: SpellMgr.h ProcFlags; spell_proc_event.
1238
+ procFlags?: number;
1239
+ /** spell_proc_event.ppmRate for Classic PPM on melee deal. */
1240
+ procPpm?: number | null;
1241
+ /** Flat proc chance 0..1 when present (customChance / ProcChance). */
1242
+ procChance?: number | null;
1243
+ // PERIODIC_TRIGGER_SPELL (23) per-tick roll, 0..1, separate from `procChance` so a spell carrying
1244
+ // both keeps them independent. Cite: SpellAuras.cpp:975–981 Brood Affliction: Bronze.
1245
+ tickChance?: number;
1246
+ // Copied from SpellDef.spellFamilyFlags at DoT apply, for family-gated procs on ticks.
1247
+ // Cite: UnitAuraProcHandler.cpp:1355–1362 Hellfire 0x40 / RoF 0x20.
1248
+ spellFamilyFlags?: number;
1249
+ // Aura::GetAuraTicks() after the current periodic (1-based), for the CoA tick curve.
1250
+ // Cite: Warlock.cpp:23–34; SpellAuras PeriodicTick.
1251
+ auraTicks?: number;
1252
+ // Copied from SpellDef.grantsSoulShardOnKill at apply: a death under this aura yields a shard.
1253
+ // Cite: EffectItemType 6265.
1254
+ grantsSoulShardOnKill?: boolean;
1255
+ // SpellMgr.h IsBinarySpell for the source spell, used on DoT ticks (binary DoTs get ×0.1 partial
1256
+ // resist). Absent → treat as non-binary.
1257
+ binary?: boolean;
1258
+ // SPELL_AURA_PERIODIC_LEECH (53): heal the caster for dealt × this multiplier each tick.
1259
+ // Cite: SpellAuras.cpp PeriodicTick :4645, :4677–4682.
1260
+ leechMultiple?: number;
1261
+ // SPELL_AURA_PERIODIC_HEALTH_FUNNEL (62): reverse leech — damage the source, heal the target for
1262
+ // dealt × leechMultiple. Cite: SpellAuras.cpp PeriodicTick :4606–4612.
1263
+ healthFunnel?: boolean;
1264
+ // SPELL_AURA_RETAIN_COMBO_POINTS (148): on expire-by-time only, remove this many CP.
1265
+ // Cite: SpellAuras.cpp HandleAuraRetainComboPoints :4436–4452.
1266
+ retainComboAmount?: number;
1267
+ // cc-only: the control kind, its DR mechanic, and whether it shatters on damage. `broken` flags
1268
+ // an early break so the expiry sweep removes the mirror silently.
1269
+ control?: ControlKind;
1270
+ mechanic?: Mechanic;
1271
+ breakOnDamage?: boolean;
1272
+ broken?: boolean;
1273
+ // SPELL_ATTR_HEARTBEAT_RESIST (0x40000000, 146 rows): the holder rolls to break early on its own
1274
+ // clock, armed from the same land-die chance the cast used. Cite: SpellAuras.cpp:5995-6032.
1275
+ heartbeat?: import('./heartbeatResist.ts').HeartbeatHolder;
1276
+ // Only attack_power/armor/haste/stamina/strength/physical_taken are applied live in combat;
1277
+ // other BuffMod values are out-of-combat attribute buffs.
1278
+ mod?: BuffMod;
1279
+ amount?: number;
1280
+ // SPELL_AURA_MOD_DETECT_RANGE yards on this buff row, reversed into Fighter.detectRangeMod on
1281
+ // expire or dispel. Cite: Unit.cpp:11772; KI-796.
1282
+ detectRangeAmount?: number;
1283
+ // SPELL_AURA_MOD_MECHANIC_RESISTANCE (117) on this buff row, distinct from pushback `amount` so
1284
+ // expiry does not subtract pushbackResistChance. Cite: Unit.cpp:4015–4031.
1285
+ mechanicResist?: { mechanic: number; amount: number };
1286
+ // Creature-type mask for versus BuffMods (102/131/180), the EffectMiscValue mask.
1287
+ // Cite: Unit.cpp GetTotalAuraModifierByMiscMask; Unit.h GetCreatureTypeMask.
1288
+ creatureTypeMask?: number;
1289
+ // SpellSchoolMask for target_resistance (123). Cite: Unit.cpp:3894.
1290
+ schoolMask?: number;
1291
+ // SpellDef.exclusionGroup mirrored at apply time so sibling auras in the same exclusive
1292
+ // spell_group can be stripped without a data-store lookup. Cite: SpellGroupStackRule.
1293
+ exclusionGroup?: number;
1294
+ // AuraStackIdentity mirrored the same way, for the pairs no spell_group covers — Gift of the
1295
+ // Wild over Mark of the Wild. Cite: engine/spells/auraStacking.ts; SpellStacking.cpp:135,352.
1296
+ stackIdent?: AuraStackIdentity;
1297
+ /** speed aura id (31/32/33/…) when kind === 'speed'. */
1298
+ aura?: number;
1299
+ /** speed percent (signed) when kind === 'speed'; reflect chance % when kind === 'reflect'. */
1300
+ pct?: number;
1301
+ /** Hostile snare vs beneficial aspect/sprint when kind === 'speed'. */
1302
+ hostile?: boolean;
1303
+ // SPELL_AURA_MOD_TOTAL_THREAT (103) Fade: per-enemy flat threat deltas applied at cast and
1304
+ // reversed on expire. Cite: HostileRefManager.cpp:82–99; ThreatManager.cpp:693–702.
1305
+ threatFadeDeltas?: ReadonlyArray<{ id: Side; delta: number }>;
1306
+ expiresAt: number;
1307
+ /** Tick this aura was applied. Same-tick white must not break Frost Nova. Cite: Spell.cpp effect order; KI-1062. */
1308
+ appliedAt?: number;
1309
+ /** When set, this aura is tied to a totem side and is stripped on unsummon. */
1310
+ fromTotem?: TotemSide;
1311
+ // This proc row IS a weapon enchant. Dead wherever CanUseEquippedWeapon is false — a form whose
1312
+ // attack speed is overridden, or a disarmed hand. Cite: Unit.cpp:10877-10891 (per attack type).
1313
+ fromWeaponEnchant?: boolean;
1314
+ // DynamicObject pool id for a PersistentAreaAura membership row; the pulse path deals the damage
1315
+ // and this row is enter/leave/refresh. Cite: DynamicObject.h m_affected.
1316
+ fromDynamicObject?: number;
1317
+ /** Current stack count (SpellEntry.StackAmount). Absent/1 = single stack. */
1318
+ stacks?: number;
1319
+ /** Remaining proc charges (SpellEntry.procCharges). Absent = unlimited. */
1320
+ charges?: number;
1321
+ // SPELL_AURA_MECHANIC_IMMUNITY EffectMiscValue ids when kind === 'immunity'.
1322
+ // Cite: SpellAuras.cpp HandleModMechanicImmunity; Fear Ward mechanic 5.
1323
+ immunityMechanics?: number[];
1324
+ // Hunter trap GO yards at arm time; proximity is vs this point, not the hunter.
1325
+ // Cite: SpellEffects.cpp EffectSummonObject; GameObject.cpp:436–503.
1326
+ trapPosYd?: CombatPosYd;
1327
+ }
1328
+
1329
+ export interface Fighter {
1330
+ side: Side;
1331
+ spec: CombatantSpec;
1332
+ // Live SPELLMOD_RADIUS mods (mirrors `spec.radiusSpellMods`, on the fighter so gear procs and
1333
+ // talent auras can push rows mid-fight). Cite: areaAura.ts effectiveAreaRadiusYd.
1334
+ radiusSpellMods: SpellMod[];
1335
+ // Live lasting SpellModifiers (Arcane Power COST, Barkskin CASTING_TIME, set bonuses).
1336
+ // Cite: Player.cpp m_spellMods; spellModIntents.ts applyOwnedSpellMod.
1337
+ ownedSpellMods: OwnedSpellMod[];
1338
+ hp: number;
1339
+ power: number;
1340
+ attackPower: number;
1341
+ armor: number;
1342
+ // Percent armor modifier from aura 101 MOD_RESISTANCE_PCT (Pierce Armor −50); effective armor =
1343
+ // max(0, armor × (1 + armorPctMod/100)). Cite: SpellAuras.cpp HandleModResistancePercent.
1344
+ armorPctMod: number;
1345
+ // Live BASE (item) armor, the slice `armorBasePctMod` multiplies. Seeded from spec.baseArmor;
1346
+ // flat armor buffs and agi×2 land on `armor` only.
1347
+ baseArmor: number;
1348
+ // Aura 142 MOD_BASE_RESISTANCE_PCT: multiplies baseArmor only, before armorPctMod, and is
1349
+ // additive across auras. Cite: SpellAuras.cpp:3435; Unit.cpp:9067.
1350
+ armorBasePctMod: number;
1351
+ /** ATTACK-speed percent: MH/OH/ranged swing timers only (auras 9 / 138 / 140 / 141 + gear). */
1352
+ haste: number;
1353
+ sitting?: boolean;
1354
+ // Cast-speed percent (aura 65): cast time and the hasted GCD, never a swing timer — the core
1355
+ // keeps UNIT_MOD_CAST_SPEED off the attack timers. Cite: Unit.cpp:10481; SpellAuras.cpp:3915.
1356
+ castHaste: number;
1357
+ // Live form package and Cat AGI AP currently baked into attackPower/armor/maxHealth, cleared on
1358
+ // leave so a mid-fight form switch re-syncs without double-counting.
1359
+ formApBonus: number;
1360
+ formArmorBonus: number;
1361
+ formHealthBonus: number;
1362
+ /** SPELL_AURA_MOD_THREAT percent from form package (cat −29 / bear +30 / battle −20). */
1363
+ formThreatPct: number;
1364
+ // physical_taken_pct from the form package, tracked so leave reverses applyBuffMod exactly.
1365
+ // Cite: HandleShapeshiftBoosts 7376/7381.
1366
+ formPhysicalTakenPctBonus: number;
1367
+ // damage_done_pct from the form package, tracked so leave reverses applyBuffMod exactly.
1368
+ // Cite: HandleShapeshiftBoosts 7376.
1369
+ formDamageDonePctBonus: number;
1370
+ swingReadyAt: number;
1371
+ // Off-hand auto-attack ready time, advanced only when dual-wielding with an OH weapon; combat
1372
+ // enter delays OH to half period. Cite: Unit.cpp Attack ~6312–6314.
1373
+ ohSwingReadyAt: number;
1374
+ /** A death marked this unit (sessionDeaths): decide at the first GCD-ready tick, not the slow-update slice. */
1375
+ decideDirty?: boolean;
1376
+ // Earliest t this unit will run pickAction again unless decideDirty; 0 = think now.
1377
+ // Set after each think via nextDecideWakeAt.
1378
+ nextWakeAt: number;
1379
+ // Last values `refreshCheapDirty` compared against, for the four inputs that dirty a decision
1380
+ // without a mark of their own. Undefined at birth so a unit's first tick still dirties.
1381
+ seenDecideHp?: number;
1382
+ seenDodgedAt?: number;
1383
+ seenDefenseReactAt?: number;
1384
+ seenHunterParryAt?: number;
1385
+ gcdUntil: number;
1386
+ // Friendly target this unit's current cast was aimed at, set when the cast starts and cleared
1387
+ // once the effects apply. Null or absent = triage picks, which is every AI cast.
1388
+ friendlyPin?: Side | null;
1389
+ castingSpell: SpellDef | null;
1390
+ // Ground dest for this in-flight or instant cast, set at startOrCast from a dest-bearing
1391
+ // CombatAction. Cite: SpellEffects.cpp EffectPersistentAA DynamicObject at dest.
1392
+ castDest: CombatPosYd | null;
1393
+ // Active channelled cast, armed when a spell with `channelMs` lands and cleared on natural end,
1394
+ // damage cancel, or action interrupt.
1395
+ channeling: import('./channel.ts').ChannelState | null;
1396
+ // Session time of this fighter's last dodge; dodge-reactive attacks such as Overpower are usable
1397
+ // against it for 5s after.
1398
+ lastDodgedAt: number;
1399
+ // Session time this fighter last set AURA_STATE_DEFENSE; Revenge / Riposte / Mongoose Bite are
1400
+ // usable for 5s after. Cite: UnitAuraProcHandler.cpp:296-328.
1401
+ lastDefenseReactAt: number;
1402
+ // Ms this unit has been unable to close on its victim, the counter sessionMotion runs toward its
1403
+ // 5 s unreachable-evade; 0 = closing fine. Cite: CreatureEventAI.cpp:545-547.
1404
+ targetUnreachableMs: number;
1405
+ // Explicit orientation override in radians. Null = derive it: face the current foe unless walking
1406
+ // away from it, else the last movement heading. Cite: Object.cpp:1515-1573.
1407
+ facing: number | null;
1408
+ // Session time this fighter last set AURA_STATE_HUNTER_PARRY; Counterattack reads it, and every
1409
+ // other class routes a parry to lastDefenseReactAt. Cite: UnitAuraProcHandler.cpp:310-316.
1410
+ lastHunterParryAt: number;
1411
+ // EVENT_T_SPELLHIT pulse: the spell that last landed on this unit, its school mask, and when.
1412
+ // Cite: Spell.cpp:1345 unit->AI()->SpellHit; CreatureEventAI.cpp:1666-1670.
1413
+ spellHitId?: number;
1414
+ spellHitSchoolMask?: number;
1415
+ spellHitAt?: number;
1416
+ castStartedAt: number;
1417
+ castFinishAt: number;
1418
+ // Damage pushbacks applied to the current cast (the GetNextDelayAtDamageMsTime ladder index) and
1419
+ // the haste-modified full cast time for the remaining-cannot-exceed-cast-time cap.
1420
+ castPushbacks: number;
1421
+ castBaseMs: number;
1422
+ // Power cost held for the in-flight cast (0 when nothing is owed): cast() takes it when the timer
1423
+ // reaches 0 and cancel() takes none, so an interrupted cast costs nothing. Cite: Spell.cpp ~3168.
1424
+ castCost: number;
1425
+ /** Pool the held cast cost is drawn from (undefined = the fighter's active power type). */
1426
+ castCostPower?: PowerType;
1427
+ cooldowns: Map<number, number>;
1428
+ categoryCooldowns: Map<number, number>;
1429
+ // SPELL_ATTR_COOLDOWN_ON_EVENT spells whose timer has not started: spellId → the ms to stamp once
1430
+ // the aura fades, with `cooldowns` holding PERMANENT_COOLDOWN_READY_AT. Cite: Spell.cpp:3414.
1431
+ deferredCooldowns?: Map<number, number>;
1432
+ /** The category half of the same defer: spellId → its category and duration. */
1433
+ deferredCategoryCooldowns?: Map<number, { category: number; ms: number }>;
1434
+ rootedUntil: number;
1435
+ // Crowd-control lockout timers (0 = free), set only when a cc effect lands, so a fight with no CC
1436
+ // leaves them all 0 and the swing/action gates below evaluate false.
1437
+ stunnedUntil: number;
1438
+ fearedUntil: number;
1439
+ incapUntil: number;
1440
+ silencedUntil: number;
1441
+ disarmedUntil: number;
1442
+ // Caster sides whose break-on-damage CC on this body our own damage shattered. A CC rule never
1443
+ // re-picks such a body, because the party chose to kill it.
1444
+ ccDamageBrokenBy?: Set<Side>;
1445
+ // SPELL_AURA_MOD_CHARM: the target fights for the charmer until this time (0 = free). Not a hard
1446
+ // lockout — the unit keeps acting, against its former allies. Cite: SpellAuras.cpp HandleModCharm.
1447
+ charmedUntil: number;
1448
+ /** Side id of the unit that charmed this fighter (TakeCharmOf caster). */
1449
+ charmedBy: Side | null;
1450
+ /** Holder spell id for the active charm (e.g. 17244 Possess). */
1451
+ charmSpellId: number;
1452
+ // Scripted HP-fraction break: remove charm when hp ≤ frac × maxHealth, 0 = no HP break.
1453
+ // Cite: boss_baroness_anastari.cpp AnastariPossess OnPeriodicTickEnd.
1454
+ charmBreakHpFrac: number;
1455
+ /** Next ScriptDev aura onPeriodic tick (Anastari ForcePeriodicity 1000). 0 = none. */
1456
+ charmPeriodicAt: number;
1457
+ // Untargetable and unattackable until this time (Possess Inv 17250 while Anastari possesses).
1458
+ // Cite: boss_baroness_anastari.cpp SPELL_POSSESS_INV = 17250.
1459
+ unattackableUntil: number;
1460
+ // SPELL_AURA_FEIGN_DEATH pose: CombatStop and untargetable until cancelled.
1461
+ // Cite: Unit.cpp SetFeignDeath :10083–10140; SpellDefines AuraInterruptFlags 0x3c3c.
1462
+ feigningUntil: number;
1463
+ /** Aura spell id that armed feigningUntil (5384, creature Fake Death, …). */
1464
+ feignSpellId: number;
1465
+ /** SPELL_AURA_MOD_PACIFY — cannot melee/ranged attack (can still cast). Cite: HandleAuraModPacify. */
1466
+ pacifiedUntil: number;
1467
+ // Per-school interrupt lockout readyAt, indexed by SpellSchools (physical=0 … arcane=6), 0 = free.
1468
+ // Distinct from silencedUntil. Cite: Object.cpp m_lockoutMap / LockOutSpells / CheckLockout.
1469
+ schoolLockoutUntil: number[];
1470
+ // active CC immunity by DR-category (Will of the Forsaken), and per-category diminishing-returns
1471
+ // bookkeeping (application step + reset time). Both empty unless CC is involved.
1472
+ ccImmuneUntil: Map<string, number>;
1473
+ dr: Map<string, { step: number; resetAt: number }>;
1474
+ resistances: Partial<Record<School, number>>;
1475
+ creatureType: number;
1476
+ mode: 'melee' | 'ranged'; // auto-attack mode (Attack vs Shoot); melee by default, ranged for a rangedAuto class
1477
+ buffActive: Set<number>;
1478
+ /** Unit m_movementInfo.moveFlags. Cite: Object.h:750; Unit.cpp:12428 SetHover. */
1479
+ movementFlags?: number;
1480
+ activeSeal: ActiveSeal | null; // paladin: the one seal currently up (procs on swing, consumed by Judgement)
1481
+ /** Active weapon temp enchants (MH/OH). Replaced on re-imbue. */
1482
+ weaponImbues: Partial<Record<'mainhand' | 'offhand', ActiveWeaponImbue>>;
1483
+ // One-shot hand override for the next weapon_imbue cast, consumed by applySpellLate. Unset falls
1484
+ // back to CombatantSpec.weaponImbueCastHand, then mainhand.
1485
+ pendingWeaponImbueHand?: 'mainhand' | 'offhand';
1486
+ // Once-per-engagement gate for Charge, cleared on leave combat: Charge is
1487
+ // SPELL_ATTR_NOT_IN_COMBAT_ONLY_PEACEFUL. Cite: Spell.cpp:4598–4599 IsNonCombatSpell.
1488
+ chargeUsed: boolean;
1489
+ // Session clock when UNIT_FLAG_IN_COMBAT drops (0 = already out), refreshed to now+timer on every
1490
+ // combat touch. Cite: CombatManager.cpp:192 TriggerCombatTimer; Unit.cpp:7895 SetInCombatState.
1491
+ combatUntil: number;
1492
+ /** Session clock when THIS unit entered combat (0 = OOC). Per-unit, not party-wide. */
1493
+ combatEnteredAt: number;
1494
+ // Multi-tick charge/intercept travel: spend and CD apply on cast, and dest is melee-reach short
1495
+ // of the target. Cite: SpellEffects.cpp EffectCharge MoveCharge; BASE_CHARGE_SPEED.
1496
+ pendingCharge: { spell: SpellDef; targetSide: Side; speed: number; dest?: CombatPosYd } | null;
1497
+ pendingSwing: SpellDef | null; // armed on-next-swing ability, consumed by the next auto-attack
1498
+ damagePctBySchool: Partial<Record<School, number>>;
1499
+ // UNIT_FIELD_POWER_COST_MODIFIER / _MULTIPLIER per school (auras 73 flat, 72 percent):
1500
+ // CalculatePowerCost is (base + flat) × (1 + pct/100), clamped at 0. Cite: Spell.cpp:6358, :6368.
1501
+ powerCostFlatBySchool: Partial<Record<School, number>>;
1502
+ powerCostPctBySchool: Partial<Record<School, number>>;
1503
+ // SPELL_AURA_MOD_SPELL_HIT_CHANCE (55) in percentage points, subtracted from the magic miss roll.
1504
+ // Cite: Unit.cpp CalculateSpellMissChance `chance -= m_modSpellHitChance`.
1505
+ spellHitBonusPercent: number;
1506
+ // SPELL_AURA_MOD_AOE_AVOIDANCE (160) miss percentage points vs area spells.
1507
+ // Cite: Unit.cpp:3713–3715 MagicSpellHitResult.
1508
+ aoeAvoidancePercent: number;
1509
+ procs: ProcDef[];
1510
+ gearProcs: Array<{
1511
+ spell: number;
1512
+ trigger: number;
1513
+ chancePct?: number;
1514
+ ppm?: number;
1515
+ flags?: number;
1516
+ procEx?: number;
1517
+ cooldownMs?: number;
1518
+ schoolMask?: number;
1519
+ spellFamilyName?: number;
1520
+ spellFamilyMask?: number[];
1521
+ }>;
1522
+ // Hidden proc cooldowns (triggered spell id → readyAt ms), deterministic, from
1523
+ // SpellProcEventEntry.cooldown. Cite: SpellMgr.h SpellProcEventEntry ~1749.
1524
+ procCooldowns: Map<number, number>;
1525
+ // Combo points (CMaNGOS Unit::m_comboPoints / m_comboTargetGuid). Points are on a target;
1526
+ // switching builder target resets to the new count. Cap 0..5.
1527
+ comboPoints: number;
1528
+ comboTarget: Side | null;
1529
+ // Energy regen accumulator (ms toward the next energy tick quantum of 100ms).
1530
+ energyAccMs: number;
1531
+ /** Mana regen accumulator (ms toward whole-second quanta; Player::Regenerate POWER_MANA). */
1532
+ manaAccMs: number;
1533
+ /** Session time of last mana spend (−1 = never). 5SR while t − lastManaUseAt < LAST_MANA_USE_MS. */
1534
+ lastManaUseAt: number;
1535
+ /** Focus regen accumulator for hunter pets (Pet::RegenerateAll 4s quantum). */
1536
+ focusAccMs: number; healthRegenFrac: number; // residual aura116 KI-898
1537
+ /** OOC rage decay accumulator (ms toward the 200 ms quantum; Player::Regenerate POWER_RAGE). */
1538
+ rageDecayAccMs: number;
1539
+ // Shapeshift form + parallel mana (Druid multi-power). See domain/character/forms.ts.
1540
+ form: ShapeshiftFormId;
1541
+ // Spell id that entered the current form — RemoveAurasDueToSpell needs it to leave form.
1542
+ // Cite: SpellAuras.cpp HandleAuraModShapeshift apply=false.
1543
+ formSpellId: number;
1544
+ mana: number;
1545
+ maxMana: number;
1546
+ createMana: number;
1547
+ /** Base/create health for POWER_HEALTH % costs (Bloodrage). 0 when unknown (mobs/fixtures). */
1548
+ createHealth: number;
1549
+ /** Gear weapon speed (ms) before form override — restored on leave form. */
1550
+ baseWeaponSpeedMs: number;
1551
+ /** Gear weapon min damage before form override — restored on leave form. */
1552
+ baseWeaponDmgMin: number;
1553
+ /** Gear weapon max damage before form override — restored on leave form. */
1554
+ baseWeaponDmgMax: number;
1555
+ /** Flat add to incoming physical damage after armor (Stoneskin: negative). */
1556
+ physicalTakenMod: number;
1557
+ // SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN (113) — flat, ranged weapon attacks only (Windwall Totem).
1558
+ // Cite: SpellAuras.cpp :174 → Unit::MeleeDamageBonusTaken.
1559
+ rangedTakenMod: number;
1560
+ // Sum of SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN (physical mask) / MOD_MELEE_DAMAGE_TAKEN_PCT;
1561
+ // physical dmg *= (1 + pct/100) after armor + flat. Cite: Unit.cpp:7628 / :7634.
1562
+ physicalTakenPctMod: number;
1563
+ // School-scoped SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN (87) — CoE fire/frost, CoS shadow/arcane;
1564
+ // applied after resist/armor + flat taken. Cite: Unit.cpp:7628 GetTotalAuraMultiplierByMiscMask.
1565
+ damageTakenPctBySchool: DamagePctBySchool;
1566
+ /** Flat add to incoming spell/magic damage after resist (Dampen Magic: negative). */
1567
+ spellTakenMod: number;
1568
+ // Victim aura: attackers gain this much AP when striking this fighter (Hunter's Mark).
1569
+ // Cite: SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS (127).
1570
+ attackerAttackPowerBonus: number;
1571
+ // Victim aura: attackers gain whole-percent spell crit vs this fighter, keyed by school.
1572
+ // SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE (179), Winter's Chill. Cite: Unit.cpp:3530–3531.
1573
+ attackerSpellCritBySchool: Partial<Record<School, number>>;
1574
+ // Victim auras 185-188: signed percentage points off an attacker's roll against this fighter.
1575
+ // Cite: Unit.cpp:3525-3528 GetCritTakenChance; :3794; :3874.
1576
+ attackerMeleeCrit: number;
1577
+ attackerRangedCrit: number;
1578
+ attackerRangedHit: number;
1579
+ attackerSpellHitBySchool: Partial<Record<School, number>>;
1580
+ /** Aura 169 rows: crit MULTIPLIER percent vs a creature-type mask. Cite: Unit.cpp:3561. */
1581
+ critDamageVersusPct: Array<{ creatureTypeMask: number; amount: number }>;
1582
+ /** Aura 122: whole percent onto the 0.5 off-hand TOTAL_PCT. Cite: SpellAuras.cpp:4183. */
1583
+ offhandDamagePct: number;
1584
+ // OVERRIDE_CLASS_SCRIPTS (112) misc values from the sheet; `buffActive` only holds live auras, so
1585
+ // a script consumer must read both. Cite: Unit.cpp:11969-11985 HasOverrideScript.
1586
+ overrideScriptIds: ReadonlySet<number>;
1587
+ // Live MOD_MELEE_ATTACK_POWER_VERSUS rows (equip seed + mid-fight elixirs).
1588
+ // Cite: Unit.cpp:7476 MeleeDamageBonusDone.
1589
+ attackPowerVersus: Array<{ creatureTypeMask: number; amount: number }>;
1590
+ /** Live MOD_RANGED_ATTACK_POWER_VERSUS. Cite: Unit.cpp:7471. */
1591
+ rangedAttackPowerVersus: Array<{ creatureTypeMask: number; amount: number }>;
1592
+ /** Live MOD_FLAT_SPELL_DAMAGE_VERSUS. Cite: Unit.cpp:7055. */
1593
+ spellDamageVersus: Array<{ creatureTypeMask: number; amount: number }>;
1594
+ // Live SPELL_AURA_MOD_DAMAGE_DONE_VERSUS (168): whole-percent multiplier on melee, ranged and
1595
+ // spell damage when the creature-type mask matches. Cite: Unit.cpp:7058, :7503.
1596
+ damageDoneVersusPct: Array<{ creatureTypeMask: number; amount: number }>;
1597
+ // Live SPELL_AURA_MOD_DAMAGE_DONE_CREATURE (59) flats for melee DoneFlat.
1598
+ // Cite: Unit.cpp:7465; KI-1043.
1599
+ damageDoneCreature: Array<{ creatureTypeMask: number; amount: number }>;
1600
+ /** SPELL_AURA_MOD_TOTAL_THREAT (103) percent on threat generation (Fade: negative). */
1601
+ threatModPct: number;
1602
+ // Live SPELL_AURA_MOD_THREAT (10) school-scoped percent, additive; threatOps multiplies
1603
+ // (1 + pct/100) for that school only. Cite: SpellAuras.cpp:2836–2838.
1604
+ threatSchoolPct: Partial<Record<School, number>>;
1605
+ /** Flat healing taken modifier (SPELL_AURA_MOD_HEALING = 115). */
1606
+ healingTakenMod: number;
1607
+ // Percent healing taken (aura 118): the heal path is (amount + flat) × (1 + pct/100).
1608
+ // Cite: Unit.cpp:7239–7245 SpellHealingBonusTaken TakenTotalMod.
1609
+ healingTakenPctMod: number;
1610
+ // Live buff mp5 (SPELL_AURA_MOD_POWER_REGEN over 5s) beyond spec.mp5.
1611
+ // Cite: StatSystem.cpp UpdateManaRegen power_regen_mp5.
1612
+ mp5Bonus: number;
1613
+ // Live product of (100+amount)/100 for SPELL_AURA_MOD_POWER_REGEN_PERCENT (110): starts at 1, a
1614
+ // buff apply multiplies and the reverse divides. Cite: Unit.cpp:4611–4622; KI-424.
1615
+ manaRegenPctMult: number;
1616
+ /** Live additive % for SPELL_AURA_MOD_POWER_REGEN_PERCENT (110) on energy (Adrenaline Rush). */
1617
+ energyRegenPctMod: number;
1618
+ // Live additive SPELL_AURA_MOD_MANA_REGEN_INTERRUPT (134) percent beyond the spec baseline.
1619
+ // Cite: StatSystem.cpp:558–562.
1620
+ manaRegenInterruptBonus: number;
1621
+ // Live SPELL_AURA_SCHOOL_ABSORB (69) pools, consumed in dealDamage after resist.
1622
+ // Cite: Unit.cpp CalculateDamageAbsorbAndResist ~2391.
1623
+ schoolAbsorbs: SchoolAbsorbAura[];
1624
+ // Live SPELL_AURA_MANA_SHIELD (97) pools, applied after school absorb with mana paid per point.
1625
+ // Cite: Unit.cpp ~2457–2496.
1626
+ manaShields: ManaShieldAura[];
1627
+ /** SPELL_AURA_SPLIT_DAMAGE_PCT (81) — Soul Link style; at most one active. */
1628
+ splitDamage: SplitDamagePctAura | null;
1629
+ // SPELL_AURA_SPLIT_DAMAGE_FLAT (153), at most one active. Cite: Unit.cpp:2501–2537.
1630
+ splitDamageFlat: SplitDamageFlatAura | null;
1631
+ // SPELL_AURA_RESIST_PUSHBACK (149) total chance % to ignore cast pushback.
1632
+ // Cite: Spell.cpp:6817–6820.
1633
+ pushbackResistChance: number;
1634
+ // Live sum of SPELL_AURA_MOD_DETECT_RANGE (91) in signed yards, fed into GetAttackDistance.
1635
+ // Cite: Unit.cpp:11772; KI-796.
1636
+ detectRangeMod?: number;
1637
+ // Blessing of Light dual flat heal bonuses, family-flag filtered to Holy Light and Flash of Light.
1638
+ // Cite: Paladin.cpp BlessingOfLight; Unit.cpp:7261–7265.
1639
+ blessingOfLight: { holyLight: number; flashOfLight: number; spellId: number } | null;
1640
+ // Healing Way 29203 stacks on this unit (Healing Wave taken %).
1641
+ // Cite: Shaman.cpp:77–89; spell_template StackAmount 3.
1642
+ healingWay: { pct: number; stacks: number; spellId: number } | null;
1643
+ // Healing Way talent proc chance while the ADD_TARGET_TRIGGER holder is up.
1644
+ // Cite: Spell.cpp:7457–7458; spell_template 29206/29205/29202.
1645
+ healingWayChancePct: number;
1646
+ // Aura-granted immunities, composed with the creature_template masks by immunity.ts.
1647
+ // Cite: Unit.cpp IsImmuneToDamage ~7310.
1648
+ immunity: ImmunityState;
1649
+ // Pending white-swing extras from SPELL_EFFECT_ADD_EXTRA_ATTACKS (19), capped at 5 and consumed
1650
+ // after landed MH white swings. Cite: SpellEffects.cpp:4878–4880.
1651
+ extraAttacks: number;
1652
+ // True while DoExtraAttacks drains the queue; Windfury-class procs must not re-fire in this
1653
+ // window. Cite: Player.cpp:7383–7385; UnitAuraProcHandler.cpp:1550–1551.
1654
+ extraAttacksExecuting: boolean;
1655
+ // Spell that last granted extraAttacks, so the meter labels the drained whites as that ability
1656
+ // instead of anonymous Melee. Cleared when the queue hits 0.
1657
+ extraAttackSource?: { spellId: number; name: string } | null;
1658
+ // Summon timed despawn: the summoning spell's duration, 0 or absent = until killed.
1659
+ // Cite: SpellEffects.cpp:2765 EffectSummonWild duration = GetSpellDuration.
1660
+ summonDespawnAt?: number;
1661
+ // Totem-only: expire time, slot, and the player summon spell id for buffActive upkeep.
1662
+ totemExpiresAt?: number;
1663
+ totemSlot?: TotemSlot;
1664
+ totemSummonSpellId?: number;
1665
+ // Totem-only: which unit summoned it. The summon-spell rotation marker lives on that unit's
1666
+ // buffActive, so unsummon clears it from the owner, not from the player.
1667
+ totemOwnerSide?: Side;
1668
+ // Totem-only: `Totem::GetSpell()`, the first kit spell id and so the only aura UnSummon strips —
1669
+ // anything the kit triggered survives a slot swap. Cite: Totem.cpp UnSummon :131–158.
1670
+ totemKitSpellId?: number;
1671
+ // Totem-only: payload SpellDefs for kit `proc_trigger_spell` ids, kept off `spec.spells` so a
1672
+ // passive totem cannot cast them through TotemAI. Cite: Totem.cpp Summon TOTEM_PASSIVE.
1673
+ totemTriggerSpells?: SpellDef[];
1674
+ // Totem-only: widest SpellRadius yards over the whole kit, for the UI's reach readout. Not
1675
+ // derivable from `spec.spells`, which is empty by design on a passive totem.
1676
+ totemAuraRadiusYd?: number;
1677
+ // The player-side seat whose grantsSoulShardOnKill spell dealt the lethal blow, consumed in
1678
+ // checkDeaths alongside the active DoT flags. The shard is that warlock's, not the party's.
1679
+ soulShardLethalCredit?: Side | null;
1680
+ // ---- Stealth (docs/archive/classes/stealth.md) ------------------------------------
1681
+ /** MOD_STEALTH active (HasStealthAura). */
1682
+ stealthed: boolean;
1683
+ /** Active stealth aura strength (aura 16). */
1684
+ stealthAuraStrength: number;
1685
+ /** Passive/talent stealth level (aura 154) — stacks with aura strength for detect math. */
1686
+ stealthLevelBonus: number;
1687
+ /** Detect strength on this unit (aura 17). */
1688
+ stealthDetectStrength: number;
1689
+ /** AuraInterruptFlags of the active stealth aura (0 = use default damage|action|attack). */
1690
+ stealthBreakFlags: number;
1691
+ /** When false, white swings are suppressed (CANCELS_AUTO_ATTACK_COMBAT). */
1692
+ autoAttackEnabled: boolean;
1693
+ /** Spell id of the active stealth aura (for buff strip / UI). */
1694
+ stealthSpellId: number;
1695
+ // A one-shot spell modifier armed by a `next_cast_mod` self-buff, consumed by the next matching
1696
+ // cast in startOrCast. Null when nothing is armed.
1697
+ pendingSpellMod: PendingSpellMod | null;
1698
+ // Crit fraction (0..1) added to this cast only, set when a `next_cast_mod` with `critAdd` is
1699
+ // consumed and cleared once the empowered spell resolves.
1700
+ castCritAdd: number;
1701
+ // Signed percent added to this cast's rolled effect magnitude, read as a (1 + pct/100) multiplier
1702
+ // on its damage, dot, buff and heal rolls. Cleared once the empowered spell resolves.
1703
+ castEffectPct: number;
1704
+ // Live % healing-done bonus (SPELL_AURA_MOD_HEALING_DONE_PERCENT), applied as (1 + pct/100) when
1705
+ // this fighter's heal amounts are rolled.
1706
+ healingPct: number;
1707
+ // Flat +healing done (aura 135), added after the base roll and before healingPct.
1708
+ // Cite: Unit.cpp SpellHealingBonusDone.
1709
+ healingDoneFlat: number;
1710
+ /** Sweeping Strikes (12292): remaining melee attacks that also cleave a second enemy (0 = none). */
1711
+ sweepingStrikesCharges: number;
1712
+ // Combustion (11129): fire crits left before the buff ends, and the live 28682 stack count.
1713
+ // Cite: UnitAuraProcHandler.cpp:991-1003.
1714
+ combustionCharges: number;
1715
+ combustionStacks: number;
1716
+ // Vampiric Embrace (15286) on the afflicted target: % of the VE caster's shadow damage healed
1717
+ // back to caster and party, 0 = inactive. Cite: UnitAuraProcHandler.cpp:1015–1028; KI-701.
1718
+ vampiricEmbracePct: number;
1719
+ /** Side of the priest who applied VE — only that caster's Shadow damage procs the heal. */
1720
+ vampiricEmbraceCasterSide?: Side;
1721
+ // Eye for an Eye (9799/25988): % of magic damage taken returned to the attacker, capped at 50% of
1722
+ // max health, 0 = inactive. Cite: UnitAuraProcHandler.cpp:795–808.
1723
+ eyeForAnEyePct: number;
1724
+ // Oracle Healing Bonus (26169): % of heals dealt returned as a self-heal via 26170, 0 = inactive.
1725
+ // Cite: UnitAuraProcHandler.cpp:1046–1052.
1726
+ oracleHealingBonusPct: number;
1727
+ // Obsidian Armor (27539) dummy active: school damage taken → school resist buff.
1728
+ // Cite: UnitAuraProcHandler.cpp:910–930.
1729
+ obsidianArmorActive: boolean;
1730
+ // Adaptive Warding (28764) dummy active: school damage taken under Mage Armor → resist buff.
1731
+ // Cite: UnitAuraProcHandler.cpp:870–907.
1732
+ adaptiveWardingActive: boolean;
1733
+ // Holy Power / Totemic Power set bonus currently active. Cite: UnitAuraProcHandler.cpp:1153–1219.
1734
+ classPowerSetKind: 'holy_power' | 'totemic_power' | null;
1735
+ /** Vestments of Faith 4pc (28809). Cite: UnitAuraProcHandler.cpp:1055–1058. */
1736
+ vestmentsGreaterHealActive: boolean;
1737
+ /** Dreamwalker Raiment HT mana refund (28719). Cite: UnitAuraProcHandler.cpp:1068–1074. */
1738
+ dreamwalkerHealingTouchActive: boolean;
1739
+ /** Idol of Longevity HT refund (28847). Cite: UnitAuraProcHandler.cpp:1077–1081. */
1740
+ idolHealingTouchRefundActive: boolean;
1741
+ /** Totem of Flowing Water LHW (28849). Cite: UnitAuraProcHandler.cpp:1222–1226. */
1742
+ totemLesserHealingWaveActive: boolean;
1743
+ /** Cheat Death set (28845) 20% HP gate. Cite: UnitAuraProcHandler.cpp:1378–1383. */
1744
+ cheatDeathActive: boolean;
1745
+ // Master of Elements refund percent while the dummy is up, 0 = inactive.
1746
+ // Cite: UnitAuraProcHandler.cpp:949–964.
1747
+ masterOfElementsPct: number;
1748
+ // Magic Absorption percent of max mana on a full resist, 0 = inactive.
1749
+ // Cite: UnitAuraProcHandler.cpp:938–947.
1750
+ magicAbsorptionPct: number;
1751
+ // Ignite talent rank spell id while the dummy aura is up, 0 = none; fire damage → DoT 12654.
1752
+ // Cite: UnitAuraProcHandler.cpp:970–985.
1753
+ igniteRankSpellId: number;
1754
+ // Setup hidden trigger 15250 while the talent proc is on the sheet, 0 = none.
1755
+ // Cite: Rogue.cpp:112–118 SetupRogue; talent ranks 13983/14070/14071.
1756
+ setupTriggerSpellId: number;
1757
+ // Deep Wounds talent rank spell id while the passive is up, 0 = none; melee crit → DoT 12721.
1758
+ // Cite: UnitAuraProcHandler.cpp:1316–1342.
1759
+ deepWoundsRankSpellId: number;
1760
+ // Improved Sprint proc chance % while the talent passive is up (0 = inactive); on a successful
1761
+ // Sprint cast, roll → cast 30918. Cite: SpellEffects.cpp:4140–4147; spell_template 13743/13875.
1762
+ improvedSprintChancePct: number;
1763
+ // SPELL_AURA_ADD_TARGET_TRIGGER (109) holders: on a later successful hit, isAffectedOnSpell +
1764
+ // roll_chance_i → applyProc(triggerSpellId). Cite: Spell.cpp:7433–7468 ProcSpellAuraTriggers.
1765
+ addTargetTriggers: Array<{
1766
+ spellId: number;
1767
+ triggerSpellId: number;
1768
+ chancePct: number;
1769
+ familyName: number;
1770
+ familyFlags: number;
1771
+ expiresAt: number;
1772
+ }>;
1773
+ // Pyroclasm talent rank spell id while the dummy is up (0 = none); Hellfire/RoF tick → stun 18093.
1774
+ // Cite: UnitAuraProcHandler.cpp:1347–1375.
1775
+ pyroclasmRankSpellId: number;
1776
+ // Leader of the Pack form crit bonus currently applied (0 = none), reversed on leave form.
1777
+ // Cite: SpellAuras.cpp:4306–4311; spell_template 24932 bp2 → +3% crit.
1778
+ leaderOfThePackCritBonus: number;
1779
+ // Form whose `spec.formTalentAuras` row is currently applied (0 = none). Held so the leave path
1780
+ // reverses exactly the row the enter path added, never a re-read of the current form.
1781
+ formTalentAuraForm: number;
1782
+ // Combo points to grant after the current finisher clears CP (Seal Fate / Ruthlessness).
1783
+ // Cite: UnitAuraProcHandler.cpp:1510–1519 AddTriggeredSpell.
1784
+ pendingFinisherComboPoints: number;
1785
+ /** Lightwell (724): a placed well this fighter owns — reactive party heal with charges (null = none). */
1786
+ lightwell: { charges: number; healPerCharge: number; intervalMs: number; expiresAt: number; nextHealAt: number; spellId: number } | null;
1787
+ // Dirty run-speed cache; recompute only when a speed aura is applied or removed.
1788
+ // Cite: SpellAuras.cpp:2880–2917 HandleAuraMod*Speed → UpdateSpeed.
1789
+ speedDirty: boolean;
1790
+ /** Last effective run yd/s. Valid when `speedDirty` is false. */
1791
+ speedCache: number;
1792
+ /** Armed after-cast; applied only when this spellId actually starts/lands. */
1793
+ armedRuleAfter?: { spellId: number; after: RuleAfter };
1794
+ /** After-cast: walk this many yards away from focus once the cast is no longer in flight. */
1795
+ pendingStepBackYd?: number;
1796
+ /** Locked retreat heading, mesh-probed for walkable yards. Set on first retreat tick. */
1797
+ stepBackDirX?: number;
1798
+ stepBackDirY?: number;
1799
+ /** Yards already walked along {@link stepBackDirX}/{@link stepBackDirY}. */
1800
+ stepBackWalkedYd?: number;
1801
+ // Wall clock the retreat gives up at. A step-back suppresses every hostile spell, so a unit whose
1802
+ // nav cannot produce a hop was silenced for the rest of the fight (measured: 3 casts in 20 s).
1803
+ stepBackDeadline?: number;
1804
+ /** Consecutive ms in which no retreat heading produced a hop (wall / corner / snare). */
1805
+ stepBackBlockedMs?: number;
1806
+ /** After-cast chain still owed, in cast order (see RotationSnapshot.followUpChain). */
1807
+ pendingFollowUp?: RuleAfterStep[];
1808
+ pendingFollowUpUntil?: number;
1809
+ /** After a step-back, do not close below the dest distance until this time. */
1810
+ stepBackHoldUntil?: number;
1811
+ stepBackHoldYd?: number;
1812
+ // Armed mechanic move from a rotation `kind:'move'` row, honoured at the TOP of
1813
+ // `advanceGapClose` (before held-key / step-back / engage). Cite: PLAN.md §7.5.
1814
+ pendingMechanicMove?: RuleMove;
1815
+ // The bag object this unit is WALKING to press: a click needs INTERACTION_DISTANCE, so a far pick
1816
+ // becomes a `move_to` that outlives `RUNOUT_YIELD_AFTER_MS`. Cite: ObjectDefines.h:25.
1817
+ pendingObjectClick?: number;
1818
+ // This move WINDOW already reported `mechanic_move_done`. Per-window or the two counters cannot be
1819
+ // compared: naxxramas read move 303 and moveDone 2016 before it. Cleared at the new-claim edge.
1820
+ mechanicMoveDone?: boolean;
1821
+ // School halt from a `kind:'halt_dps'` row this tick. `'all'` = any damaging cast, else one or
1822
+ // more SpellDef.school strings. Cleared when a non-halt rule wins.
1823
+ haltDpsSchool?: HaltDpsSchool;
1824
+ // creature_template.entry bodies the armed halt covers; absent = every body. Set and cleared with
1825
+ // `haltDpsSchool` in the same three places. Cite: ENGINE-REBUILD E5.6.
1826
+ haltDpsEntries?: readonly number[];
1827
+ // When that halt stops being this unit's live answer — `nextWakeAt` at the arming decision, since
1828
+ // `haltDpsSchool` is a latch only pickAction clears. Absent or non-finite = do not trust per tick.
1829
+ haltDpsUntil?: number;
1830
+ // Kill-order creature_template.entry list for this tick, on DPS and off-tanks only, never the main
1831
+ // tank. pickAction.ts:2259 publishes it; sessionFocus.ts:183 reads it without re-deriving.
1832
+ killOrderEntries?: readonly number[];
1833
+ // Last body-avoidance heading (null when nothing is in the way), reused 2 of 3 ticks while it
1834
+ // still points toward dest. Cite: recoil-rts.md §3.
1835
+ lastAvoidanceDir: { x: number; y: number } | null;
1836
+ }
1837
+
1838
+ /** A consumed-on-next-cast spell modifier (see SpellEffect `next_cast_mod`). */
1839
+ export interface PendingSpellMod {
1840
+ spellId: number;
1841
+ name: string;
1842
+ appliesTo: 'any' | 'nature' | 'heal' | 'summon' | 'curse';
1843
+ critAdd?: number;
1844
+ instant?: boolean;
1845
+ freeCost?: boolean;
1846
+ // SPELLMOD_COST signed % applied to the already-resolved cast cost (Fel Domination −50).
1847
+ // Not SpellDef.costPct (ManaCostPercentage × create mana).
1848
+ costModPct?: number;
1849
+ /** SPELLMOD_COST flat (Warrior's Wrath −50 rage, Retributive Smite −300 mana). */
1850
+ costFlat?: number;
1851
+ effectPct?: number;
1852
+ /** SPELLMOD_CASTING_TIME flat ms (Nature's Grace −500). */
1853
+ castTimeFlat?: number;
1854
+ /** Source SpellFamilyName. Cite: SpellModifier::isAffectedOnSpell family equality. */
1855
+ spellFamilyName?: number;
1856
+ /** EffectItemType / spell_affect mask. 0 = family-name only. */
1857
+ familyFlags?: number;
1858
+ // The holder's own 107/108 rows. When present these decide what consumes it and what applies;
1859
+ // the fields above are derived shorthand. Cite: spellModIntents.chargedSpellModsFromSpell.
1860
+ rows?: readonly OwnedSpellMod[];
1861
+ }
1862
+
1863
+ export interface TotemView {
1864
+ slot: TotemSlot;
1865
+ side: TotemSide;
1866
+ name: string;
1867
+ hp: number;
1868
+ maxHp: number;
1869
+ remainingMs: number;
1870
+ casting: { spellId: number; name: string; startedAt: number; endsAt: number } | null;
1871
+ iconSpellId?: number;
1872
+ /** The player spell that summoned this totem — lets the UI name/icon it and the auto-battler twist. */
1873
+ summonSpellId?: number;
1874
+ /** Who dropped it (player or ally_N) — meter folds totem damage into this owner. */
1875
+ ownerSide?: Side;
1876
+ /** Kit auras this totem is currently granting the party, with their real remaining time. */
1877
+ auras?: { spellId: number; name: string; remainingMs: number }[];
1878
+ // Widest SpellRadius yards across this totem's kit — the ground it covers. `auras` only lists what
1879
+ // it grants the PLAYER, so Searing / Magma / Earthbind reported no reach. Omitted, never defaulted.
1880
+ auraRadiusYd?: number;
1881
+ }
1882
+
1883
+ /** Armed hunter trap GO (SUMMON_OBJECT_SLOT1) — the chip lives on the ground at `pos`, not on a unit. */
1884
+ export interface TrapView {
1885
+ spellId: number;
1886
+ name: string;
1887
+ remainingMs: number;
1888
+ /** GO trigger radius (yards). Classic trap GOs bake trap.radius = 5. */
1889
+ radiusYd: number;
1890
+ /** Who armed it (player or ally_N). */
1891
+ ownerSide: Side;
1892
+ triggerSpellId: number;
1893
+ /** Placement yards (caster feet at arm). Absent when the session has no geometry. */
1894
+ pos?: CombatPosYd;
1895
+ }
1896
+
1897
+ export type { CombatSession } from './session-types.ts';