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,767 @@
1
+ // Equipment Helper: toggleable auto-equip and upgrade suggestions, defaulting to enabled + 'suggest'.
2
+ // Scoring is SPEC-AWARE — the playerbots GetStatWeight pipeline, not a flat class tilt. All pure.
3
+
4
+ import type { DataStore } from '../../data/dataStore.ts';
5
+ import type { Character } from '../character/character.ts';
6
+ import type { Inventory } from './inventory.ts';
7
+ import type { ItemDef, EquipSlot, RandomPropertyDef, Stat } from '../../data/schema.ts';
8
+ import { equippedEntry, equippedInstance, type ItemInstance } from './itemInstance.ts';
9
+ import { BAG_SLOTS, itemSlotTargets, type EquipOpts } from './equipment.ts';
10
+ import { canEquipItem } from './itemRestrictions.ts';
11
+ import {
12
+ ammoHastePctFromItem,
13
+ isQuiverOrPouch,
14
+ quiverPouchMatchesRangedWeapon,
15
+ } from './ammo.ts';
16
+ import { gearEnchantGrant } from '../professions/gearEnchant.ts';
17
+ import { setPieceCounts } from '../character/characterStats.ts';
18
+ import {
19
+ calculateSingleStatWeight,
20
+ calculateStatWeight,
21
+ characterPlayerbotSpecId,
22
+ playerbotWeightScale,
23
+ pricedStatAmount,
24
+ shouldEquipItemForSpec,
25
+ type StatWeightOpts,
26
+ } from '../bots/playerbotStatWeight.ts';
27
+ import { BODY_ARMOR_SLOTS, canEquipArmor } from '../bots/playerbotEquipCache.ts';
28
+ import { isFishingPole } from '../professions/professions.ts';
29
+ import { attackPower, effectiveStats } from '../character/characterStats.ts';
30
+ import { octRegenMpPerSpirit } from '../../engine/combat/formulas.ts';
31
+ import { spenderWeaponDps } from './weaponSpender.ts';
32
+
33
+ export interface EquipmentHelperConfig {
34
+ enabled: boolean;
35
+ mode: 'auto' | 'suggest';
36
+ }
37
+
38
+ export const DEFAULT_EQUIPMENT_HELPER_CONFIG: EquipmentHelperConfig = {
39
+ enabled: true,
40
+ mode: 'suggest',
41
+ };
42
+
43
+ // Spirit-only mana regen per 5s, memoised per Character: MOD_MANA_REGEN_INTERRUPT grants a percent
44
+ // of it and findUpgrades scores every bag stack. Cite: floorRest.ts:83 updateManaRegen.
45
+ const SPIRIT_REGEN_MEMO = new WeakMap<Character, number>();
46
+
47
+ function spiritRegenPer5(char: Character, ds: DataStore): number {
48
+ const hit = SPIRIT_REGEN_MEMO.get(char);
49
+ if (hit !== undefined) return hit;
50
+ let v = 0;
51
+ try {
52
+ v = octRegenMpPerSpirit(char.cls, effectiveStats(char, ds).spi) * 5;
53
+ } catch {
54
+ v = 0;
55
+ }
56
+ SPIRIT_REGEN_MEMO.set(char, v);
57
+ return v;
58
+ }
59
+
60
+ // Melee AP, memoised the same way: the spender's per-cast roll is weapon damage plus AP × speed/14,
61
+ // and findUpgrades prices every bag stack. Cite: characterStats.ts:818 attackPower.
62
+ const MELEE_AP_MEMO = new WeakMap<Character, number>();
63
+
64
+ function meleeAttackPower(char: Character, ds: DataStore): number {
65
+ const hit = MELEE_AP_MEMO.get(char);
66
+ if (hit !== undefined) return hit;
67
+ let v = 0;
68
+ try {
69
+ v = attackPower(char, ds);
70
+ } catch {
71
+ v = 0;
72
+ }
73
+ MELEE_AP_MEMO.set(char, v);
74
+ return v;
75
+ }
76
+
77
+ /** Coerce stored value into a valid config (safe defaults). */
78
+ export function normalizeEquipmentHelperConfig(raw: unknown): EquipmentHelperConfig {
79
+ const r = (raw && typeof raw === 'object' ? raw : {}) as Partial<EquipmentHelperConfig>;
80
+ // Absent / partial configs fall through to DEFAULT, not a hardcoded other mode —
81
+ // a missing mode used to flip the Settings radio off the saved choice.
82
+ const mode: EquipmentHelperConfig['mode'] =
83
+ r.mode === 'auto' || r.mode === 'suggest' ? r.mode : DEFAULT_EQUIPMENT_HELPER_CONFIG.mode;
84
+ return {
85
+ enabled: typeof r.enabled === 'boolean' ? r.enabled : DEFAULT_EQUIPMENT_HELPER_CONFIG.enabled,
86
+ mode,
87
+ };
88
+ }
89
+
90
+ // Score a class-11 quiver or pouch: ammo capacity plus its ranged ammo-haste. A wrong weapon
91
+ // family scores 0 so a mismatch is never recommended. Haste stacking is handled in findUpgrades.
92
+ function quiverPouchValue(it: ItemDef, char: Character, ds: DataStore): number {
93
+ const rangedEntry = equippedEntry(char.equipped.ranged);
94
+ const ranged = rangedEntry != null ? ds.item(rangedEntry) : undefined;
95
+ if (!quiverPouchMatchesRangedWeapon(it, ranged)) return 0;
96
+ const slots = it.bagSlots ?? 0;
97
+ // Ammo-haste is the combat value of a quiver/pouch (SPELL_AURA_MOD_RANGED_AMMO_HASTE).
98
+ // Weight so a real haste upgrade beats a couple of extra ammo slots.
99
+ const hastePct = ammoHastePctFromItem(ds, it);
100
+ return slots + hastePct * 2.0;
101
+ }
102
+
103
+ /** Resolve the playerbots weightscale id used for this wearer's upgrade scoring. */
104
+ export function resolveGearSpecId(char: Character, ds: DataStore, opts?: EquipOpts): number {
105
+ if (opts?.specId != null && opts.specId > 0) return opts.specId;
106
+ return characterPlayerbotSpecId(char, ds, { role: opts?.role });
107
+ }
108
+
109
+ // The score contribution of the enchant already on the worn piece, weighted with the SAME
110
+ // coefficients itemValue uses. Without it "equip best" silently discarded a fresh enchant.
111
+ export function wornEnchantValue(
112
+ char: Character,
113
+ slot: EquipSlot,
114
+ ds: DataStore,
115
+ opts?: EquipOpts,
116
+ ): number {
117
+ const inst = equippedInstance(char.equipped[slot]);
118
+ return enchantIdValue(inst?.permEnchantId ?? char.enchants?.[slot], char, ds, opts);
119
+ }
120
+
121
+ // The same weighting for an enchant riding on a piece still in the bags. Pricing only the worn
122
+ // side made an enchanted candidate read as bare, so a worse unenchanted piece won.
123
+ export function candidateEnchantValue(
124
+ inst: ItemInstance | null | undefined,
125
+ char: Character,
126
+ ds: DataStore,
127
+ opts?: EquipOpts,
128
+ ): number {
129
+ return enchantIdValue(inst?.permEnchantId, char, ds, opts);
130
+ }
131
+
132
+ function enchantIdValue(
133
+ id: number | null | undefined,
134
+ char: Character,
135
+ ds: DataStore,
136
+ opts?: EquipOpts,
137
+ ): number {
138
+ if (id == null) return 0;
139
+ const grant = gearEnchantGrant(id, ds);
140
+ if (!grant) return 0;
141
+ const specId = resolveGearSpecId(char, ds, opts);
142
+ let score = calculateSingleStatWeight(specId, 'armor', grant.armor);
143
+ for (const st of grant.stats) {
144
+ // Same Stat → field map as calculateStatWeight (playerbotStatWeight STAT_TO_FIELD).
145
+ const field =
146
+ st.stat === 'str' ? 'str'
147
+ : st.stat === 'agi' ? 'agi'
148
+ : st.stat === 'sta' ? 'sta'
149
+ : st.stat === 'int' ? 'int'
150
+ : st.stat === 'spi' ? 'spi'
151
+ : st.stat === 'crit' ? 'critstrkrtng'
152
+ : st.stat === 'hit' ? 'hitrtng'
153
+ : (st.stat as string) === 'attackPower' ? 'atkpwr'
154
+ : (st.stat as string) === 'spellPower' ? 'splpwr'
155
+ : (st.stat as string) === 'healingPower' ? 'splheal'
156
+ : st.stat === 'mp5' ? 'manargn'
157
+ : st.stat === 'dodge' ? 'dodgertng'
158
+ : st.stat === 'parry' ? 'parryrtng'
159
+ : st.stat === 'defense' ? 'defrtng'
160
+ : st.stat === 'block' ? 'blockrtng'
161
+ : '';
162
+ if (field) score += calculateSingleStatWeight(specId, field, st.value);
163
+ }
164
+ // Flat weapon damage from enchants ≈ a slice of mledps (rough; classic kits use +dmg).
165
+ if (grant.weaponDamageFlat) {
166
+ score += calculateSingleStatWeight(specId, 'mledps', grant.weaponDamageFlat);
167
+ }
168
+ // Resistances: light count so a resist enchant is not free to discard.
169
+ for (const amount of Object.values(grant.resists)) {
170
+ score += (amount ?? 0) * 0.3;
171
+ }
172
+ return score;
173
+ }
174
+
175
+ // itemValue: the "power" of this item for this character's *active talent spec*. Uses playerbots
176
+ // GetStatWeight (spec-weighted) — same scale as companion spawn gear.
177
+ export function itemValue(
178
+ it: ItemDef,
179
+ char: Character,
180
+ ds: DataStore,
181
+ opts?: EquipOpts,
182
+ scoreOpts?: StatWeightOpts,
183
+ ): number {
184
+ if (!it.slot) return 0;
185
+
186
+ // Bags are special: better means strictly more bagSlots, scored by capacity so findUpgrades can
187
+ // replace the smallest worn bag. A class-11 quiver is ammo family + haste, not bag capacity.
188
+ if (it.slot === 'bag') {
189
+ if (isQuiverOrPouch(it)) return quiverPouchValue(it, char, ds);
190
+ return it.bagSlots ?? 0;
191
+ }
192
+
193
+ const specId = resolveGearSpecId(char, ds, opts);
194
+ // CalculateStatWeight already zeros wrong armor/weapon for the scale and weights
195
+ // primaries / armor / mledps / rgddps / spell power per the active weightscale.
196
+ return Math.max(0, calculateStatWeight(char.cls, specId, it, {
197
+ ...scoreOpts,
198
+ spell: (id) => ds.spell(id),
199
+ spiritRegenPer5: spiritRegenPer5(char, ds),
200
+ }));
201
+ }
202
+
203
+ // Value of a piece the wearer already has ON. The worn side must never be scored through the spec
204
+ // gates: a zeroed staff read as an empty slot and a gray axe was offered at +140.
205
+ export function wornItemValue(
206
+ it: ItemDef,
207
+ char: Character,
208
+ ds: DataStore,
209
+ opts?: EquipOpts,
210
+ scoreOpts?: StatWeightOpts,
211
+ ): number {
212
+ return itemValue(it, char, ds, opts, { ...scoreOpts, asWorn: true });
213
+ }
214
+
215
+ // Melee DPS a MAIN-hand candidate reaches through the spender. The off hand never gets it: the
216
+ // spender swings the main hand (weapon.ts hand === 'mainhand') and off-hand white damage is halved.
217
+ function mainHandAbilityDps(it: ItemDef, char: Character, ds: DataStore, opts?: EquipOpts): number {
218
+ if (!it.weapon || !opts?.weaponSpender) return 0;
219
+ return spenderWeaponDps(it, meleeAttackPower(char, ds), opts.weaponSpender);
220
+ }
221
+
222
+ /** Fold a rolled suffix onto a def copy so GetStatWeight sees the same stats the paperdoll does. */
223
+ function withRandomProp(it: ItemDef, ds: DataStore, inst?: ItemInstance | null): ItemDef {
224
+ const id = inst?.randomPropertyId;
225
+ if (id == null || id <= 0) return it;
226
+ const prop: RandomPropertyDef | undefined = ds.itemRandomProperty?.(id);
227
+ if (!prop) return it;
228
+ let stats = it.stats;
229
+ if (prop.stats) {
230
+ const by = new Map<string, number>((stats ?? []).map((s) => [s.stat, s.value]));
231
+ for (const [k, v] of Object.entries(prop.stats)) {
232
+ if (typeof v !== 'number' || !Number.isFinite(v) || v === 0) continue;
233
+ by.set(k, (by.get(k) ?? 0) + v);
234
+ }
235
+ stats = [...by.entries()].map(([stat, value]) => ({ stat: stat as Stat, value }));
236
+ }
237
+ const armor = prop.armor ? (it.armor ?? 0) + prop.armor : it.armor;
238
+ let weapon = it.weapon;
239
+ if (weapon && prop.weaponDamageFlat) {
240
+ weapon = {
241
+ ...weapon,
242
+ dmgMin: weapon.dmgMin + prop.weaponDamageFlat,
243
+ dmgMax: weapon.dmgMax + prop.weaponDamageFlat,
244
+ };
245
+ }
246
+ if (stats === it.stats && armor === it.armor && weapon === it.weapon) return it;
247
+ return { ...it, stats, armor, weapon };
248
+ }
249
+
250
+ // When the spec scale prices nothing, still rank quality, ilvl, armor and DPS so a green mail
251
+ // chest beats an empty slot. Only stats the active weightscale prices are added.
252
+ function fallbackGearScore(it: ItemDef, specId: number): number {
253
+ let n = (it.quality ?? 0) * 20 + (it.itemLevel ?? 0);
254
+ n += (it.armor ?? 0) * 0.1;
255
+ if (it.slot === 'bag') n += (it.bagSlots ?? 0) * 2;
256
+ if (it.weapon) {
257
+ const dps = (it.weapon.dmgMin + it.weapon.dmgMax) / 2 / ((it.weapon.delayMs || 2000) / 1000);
258
+ n += dps;
259
+ }
260
+ n += pricedStatAmount(specId, it);
261
+ return n;
262
+ }
263
+
264
+ /** Jewelry / cloaks with no weighted stats are not "a green chest" — leave them in bags. */
265
+ function fallbackSlotOk(it: ItemDef): boolean {
266
+ const slot = it.slot;
267
+ if (!slot || slot === 'bag') return true;
268
+ if (slot === 'neck' || slot === 'finger' || slot === 'trinket' || slot === 'back') return false;
269
+ // A shirt's weight 1 is upstream's "equippable" floor, not a stat (RandomItemMgr.cpp:1364
270
+ // `slot == EQUIPMENT_SLOT_BODY && statW <= 0 → 1`); quality×20+ilvl read it as +55.
271
+ if (slot === 'shirt' || slot === 'tabard') return false;
272
+ return true;
273
+ }
274
+
275
+ // Spec score when it has an opinion, else quality / ilvl / armor / DPS. A caller adding a
276
+ // cross-slot cost must use the same scale — the two differ by an order of magnitude.
277
+ export type CompareScale = 'spec' | 'fallback';
278
+
279
+ function upgradeCompare(
280
+ cand: ItemDef,
281
+ cur: ItemDef | undefined,
282
+ char: Character,
283
+ ds: DataStore,
284
+ opts?: EquipOpts,
285
+ ): { candVal: number; curVal: number; scale: CompareScale } {
286
+ const specId = resolveGearSpecId(char, ds, opts);
287
+ const prefCand = itemValue(cand, char, ds, opts);
288
+ const usableCand = wornItemValue(cand, char, ds, opts);
289
+ const usableCur = cur ? wornItemValue(cur, char, ds, opts) : 0;
290
+ const fbCand = fallbackGearScore(cand, specId);
291
+ const fbCur = cur ? fallbackGearScore(cur, specId) : 0;
292
+
293
+ if (cand.slot === 'bag') {
294
+ if (prefCand > 0 || usableCur > 0) {
295
+ return { candVal: prefCand, curVal: usableCur, scale: 'spec' };
296
+ }
297
+ return { candVal: fbCand, curVal: fbCur, scale: 'fallback' };
298
+ }
299
+
300
+ // Off-tier body armor never displaces an on-tier worn piece (rogue: cloth +10 agi over leather
301
+ // +15 sta); empty or off-tier slots keep the class-legal path. Cite: ItemUsageValue.cpp CanEquipArmor.
302
+ if (
303
+ cur
304
+ && cand.slot && BODY_ARMOR_SLOTS.has(cand.slot as EquipSlot)
305
+ && !canEquipArmor(char.cls, specId, char.level, cand)
306
+ && canEquipArmor(char.cls, specId, char.level, cur)
307
+ ) {
308
+ return { candVal: 0, curVal: Math.max(usableCur, 1), scale: 'spec' };
309
+ }
310
+ const specCand = prefCand > 0
311
+ ? prefCand
312
+ : (!cur && usableCand > 0 ? usableCand * 0.25 : usableCand);
313
+ // Class-legal armor the scale zeros (druid cloth on feralsps) still falls back. A mage cannot
314
+ // reach leather here: findUpgrades already ran canEquipItem. Cite: Player.cpp CanUseItem.
315
+ const allowFallback = fallbackSlotOk(cand);
316
+ const spec = { candVal: specCand, curVal: usableCur, scale: 'spec' as const };
317
+ const fb = { candVal: fbCand, curVal: fbCur, scale: 'fallback' as const };
318
+
319
+ // ONE scale per pair, read off BOTH sides as bestHandLoadout does: picking it from the candidate
320
+ // alone recommended A over worn B and B over worn A, 175 of 764 warrior chest pairs measured.
321
+ const specSpeaks = specCand > 1 || usableCur > 1; // 1 = playerbotStatWeight.ts:539's placeholder
322
+ // A silent scale with no fallback is a tie, not a +1: the placeholder alone put a statless
323
+ // shirt into an empty slot as a gain.
324
+ if (!specSpeaks) return allowFallback ? fb : { candVal: 0, curVal: 0, scale: 'spec' as const };
325
+ if (Math.abs(specCand - usableCur) > 0.6) return spec;
326
+ // The scale ties: quality / ilvl / armor / DPS break it, on one scale for both directions.
327
+ return allowFallback ? fb : spec;
328
+ }
329
+
330
+ // A candidate both lower quality and no higher item level than what is worn is never an upgrade,
331
+ // whatever the weightscale says: raw DPS × a big coefficient lets a gray weapon outbid an epic.
332
+ function isQualityRegression(cand: ItemDef, worn: ItemDef | undefined): boolean {
333
+ if (!worn) return false;
334
+ const cq = cand.quality ?? 0;
335
+ const wq = worn.quality ?? 0;
336
+ if (cq >= wq) return false;
337
+ return (cand.itemLevel ?? 0) <= (worn.itemLevel ?? 0);
338
+ }
339
+
340
+ /** Suggestion shape for callers. */
341
+ export interface UpgradeSuggestion {
342
+ entry: number;
343
+ targetSlot: EquipSlot;
344
+ currentEntry?: number;
345
+ valueDelta: number;
346
+ // Unit of valueDelta: weightscale points, or the quality/ilvl fallback when the scale is silent.
347
+ scale?: CompareScale;
348
+ // Rolled suffix on the bag stack that WON this compare (scoring already folds it in via
349
+ // withRandomProp). Carried so a UI row can name and tooltip the same item it scored.
350
+ randomPropertyId?: number;
351
+ // Slots this equip empties as a side effect of two-hand exclusivity (equipping an off-hand stows a worn
352
+ // 2H; equipping a 2H stows the off-hand). UI shows the cost.
353
+ displaces?: EquipSlot[];
354
+ }
355
+
356
+ /** A hand candidate with both denominations precomputed once. */
357
+ interface HandPiece {
358
+ entry: number;
359
+ def: ItemDef;
360
+ randomPropertyId?: number;
361
+ /** Spec score in the main hand — includes the spender's per-cast damage. */
362
+ specMh: number;
363
+ /** Spec score in the off hand — listed DPS only. */
364
+ specOh: number;
365
+ fb: number;
366
+ }
367
+
368
+ /** Hands are one decision: WoW values max(2H, MH+OH), never each socket alone. */
369
+ interface HandConfig {
370
+ mainhand?: HandPiece;
371
+ offhand?: HandPiece;
372
+ twoHandInMain: boolean;
373
+ }
374
+
375
+ function handConfigScore(c: HandConfig, scale: CompareScale): number {
376
+ const pick = (p: HandPiece | undefined, mainHand: boolean) =>
377
+ p ? (scale === 'spec' ? (mainHand ? p.specMh : p.specOh) : p.fb) : 0;
378
+ return pick(c.mainhand, true) + pick(c.offhand, false);
379
+ }
380
+
381
+ // The per-loadout hand comparison the per-slot loop cannot express. Scoring each hand against its
382
+ // own occupant made a shield "upgrade" an empty off hand under a 2H, and the swap never settled.
383
+ function bestHandLoadout(
384
+ char: Character,
385
+ inventory: Inventory,
386
+ ds: DataStore,
387
+ opts?: EquipOpts,
388
+ ): UpgradeSuggestion[] {
389
+ const piece = (
390
+ def: ItemDef,
391
+ entry: number,
392
+ wornSlot: EquipSlot | null,
393
+ inst?: ItemInstance | null,
394
+ ): HandPiece => {
395
+ const folded = withRandomProp(def, ds, inst);
396
+ // Enchant counts on BOTH sides: a bagged piece can carry permEnchantId (unequipped or
397
+ // bought enchanted), and pricing only the worn side stranded enchants the player paid for.
398
+ const ench = wornSlot
399
+ ? wornEnchantValue(char, wornSlot, ds, opts)
400
+ : candidateEnchantValue(inst, char, ds, opts);
401
+ const abilityDps = mainHandAbilityDps(folded, char, ds, opts);
402
+ return {
403
+ entry,
404
+ ...(inst?.randomPropertyId != null && inst.randomPropertyId > 0
405
+ ? { randomPropertyId: inst.randomPropertyId }
406
+ : {}),
407
+ def: folded,
408
+ specMh: wornItemValue(folded, char, ds, opts, { abilityDps }) + ench,
409
+ specOh: wornItemValue(folded, char, ds, opts) + ench,
410
+ fb: fallbackGearScore(folded, resolveGearSpecId(char, ds, opts)),
411
+ };
412
+ };
413
+ const specName = playerbotWeightScale(resolveGearSpecId(char, ds, opts))?.name ?? '';
414
+ // ONE gate for both sockets: a class-legal WEAPON is ranked, never rejected for sitting outside the
415
+ // scale's subclass set (the off hand alone refused a combat rogue an epic dagger). Shields stay gated.
416
+ const socketOk = (it: ItemDef, socket: EquipSlot, worn: ItemDef | undefined): boolean => {
417
+ if (socket === 'offhand' && !it.weapon
418
+ && !shouldEquipItemForSpec(char.cls, specName, it, socket)) {
419
+ return false;
420
+ }
421
+ if (it.weapon && worn?.weapon && isQualityRegression(it, worn)) return false;
422
+ return true;
423
+ };
424
+
425
+ const mhEntry = equippedEntry(char.equipped.mainhand);
426
+ const mhDef = mhEntry != null ? ds.item(mhEntry) : undefined;
427
+ const ohEntry = equippedEntry(char.equipped.offhand);
428
+ const ohDef = ohEntry != null ? ds.item(ohEntry) : undefined;
429
+
430
+ const wornMh = mhDef
431
+ ? piece(mhDef, mhEntry!, 'mainhand', equippedInstance(char.equipped.mainhand))
432
+ : undefined;
433
+ const wornOh = ohDef
434
+ ? piece(ohDef, ohEntry!, 'offhand', equippedInstance(char.equipped.offhand))
435
+ : undefined;
436
+ const wornIsTwoHand = mhDef?.slot === 'twohand';
437
+ // A worn pole is a tool, not a combat 2H. Big Iron's 19 DPS would beat a real 1H if scored;
438
+ // school throws re-wear it from bags. Cite: professions.ts:315 ensureFishingPoleEquipped.
439
+ const poleWorn = !!(mhDef && isFishingPole(mhDef));
440
+ const combatMh = poleWorn ? undefined : wornMh;
441
+ const combatOh = poleWorn ? undefined : wornOh;
442
+ const combatTwoHand = poleWorn ? false : wornIsTwoHand;
443
+
444
+ const current: HandConfig = {
445
+ mainhand: combatMh,
446
+ offhand: combatOh,
447
+ twoHandInMain: combatTwoHand,
448
+ };
449
+
450
+ // Candidate pool: bags plus whatever is already worn (a displaced 2H returns to bags, so
451
+ // it must stay a candidate or the comparison is not stable across the swap).
452
+ const twoHanders: HandPiece[] = [];
453
+ const mainHands: HandPiece[] = [];
454
+ const offHands: HandPiece[] = [];
455
+ if (combatTwoHand && combatMh) twoHanders.push(combatMh);
456
+ else if (combatMh) mainHands.push(combatMh);
457
+ if (combatOh) offHands.push(combatOh);
458
+
459
+ for (const stack of inventory.stacks) {
460
+ let it: ItemDef | undefined;
461
+ try {
462
+ it = ds.item(stack.item);
463
+ } catch {
464
+ continue;
465
+ }
466
+ if (!it?.slot || !canEquipItem(char, it, ds)) continue;
467
+ if ((it as { questItem?: boolean }).questItem) continue;
468
+ if (isFishingPole(it)) continue;
469
+ const targets = itemSlotTargets(it, opts);
470
+ const canMain = targets.includes('mainhand') && socketOk(it, 'mainhand', poleWorn ? undefined : mhDef);
471
+ const canOff = targets.includes('offhand') && socketOk(it, 'offhand', poleWorn ? undefined : ohDef);
472
+ if (!canMain && !canOff) continue;
473
+ let p: HandPiece;
474
+ try {
475
+ p = piece(it, it.entry, null, stack);
476
+ } catch {
477
+ continue;
478
+ }
479
+ if (it.slot === 'twohand') twoHanders.push(p);
480
+ else {
481
+ if (canMain) mainHands.push(p);
482
+ if (canOff) offHands.push(p);
483
+ }
484
+ }
485
+
486
+ if (!twoHanders.length && !mainHands.length && !offHands.length) return [];
487
+
488
+ // Bound the pairing: only the strongest few per socket can win a configuration.
489
+ const TOP = 4;
490
+ const byFb = (a: HandPiece, b: HandPiece) => b.fb - a.fb;
491
+ const top = (xs: HandPiece[]) => [...xs].sort(byFb).slice(0, TOP);
492
+
493
+ const configs: HandConfig[] = [current];
494
+ for (const th of top(twoHanders)) configs.push({ mainhand: th, twoHandInMain: true });
495
+ for (const mh of top(mainHands)) {
496
+ configs.push({ mainhand: mh, twoHandInMain: false });
497
+ for (const oh of top(offHands)) {
498
+ if (oh.entry === mh.entry) continue;
499
+ configs.push({ mainhand: mh, offhand: oh, twoHandInMain: false });
500
+ }
501
+ }
502
+ // Off-hand against the CURRENT main hand. With a 2H worn that main hand is dropped, so the
503
+ // configuration is off-hand alone — enumerate it or a shield can never replace a bad staff.
504
+ for (const oh of top(offHands)) {
505
+ configs.push({
506
+ mainhand: wornIsTwoHand ? undefined : wornMh,
507
+ offhand: oh,
508
+ twoHandInMain: false,
509
+ });
510
+ }
511
+
512
+ // ONE scale across every configuration in this decision. Fallback only when the spec
513
+ // weightscale has no opinion on any of them (common: 2/28 scales price armor).
514
+ const scale: CompareScale = configs.some((c) => handConfigScore(c, 'spec') > 0)
515
+ ? 'spec'
516
+ : 'fallback';
517
+ const curScore = handConfigScore(current, scale);
518
+
519
+ let best = current;
520
+ let bestScore = curScore;
521
+ for (const c of configs) {
522
+ const s = handConfigScore(c, scale);
523
+ if (s > bestScore + 0.6) {
524
+ bestScore = s;
525
+ best = c;
526
+ }
527
+ }
528
+ if (best === current) return [];
529
+
530
+ // Emit the differing sockets. Each step moves toward the same argmax over an unchanged
531
+ // candidate pool, so the pass converges instead of trading the same two items.
532
+ const out: UpgradeSuggestion[] = [];
533
+ const delta = bestScore - curScore;
534
+ if (best.mainhand && best.mainhand.entry !== wornMh?.entry) {
535
+ out.push({
536
+ entry: best.mainhand.entry,
537
+ targetSlot: 'mainhand',
538
+ ...(best.mainhand.randomPropertyId != null
539
+ ? { randomPropertyId: best.mainhand.randomPropertyId }
540
+ : {}),
541
+ currentEntry: mhEntry ?? undefined,
542
+ valueDelta: delta,
543
+ scale,
544
+ displaces: best.twoHandInMain && ohEntry != null ? ['offhand'] : undefined,
545
+ });
546
+ }
547
+ if (best.offhand && best.offhand.entry !== wornOh?.entry) {
548
+ out.push({
549
+ entry: best.offhand.entry,
550
+ targetSlot: 'offhand',
551
+ ...(best.offhand.randomPropertyId != null
552
+ ? { randomPropertyId: best.offhand.randomPropertyId }
553
+ : {}),
554
+ currentEntry: ohEntry ?? undefined,
555
+ valueDelta: delta,
556
+ scale,
557
+ displaces: wornIsTwoHand ? ['mainhand'] : undefined,
558
+ });
559
+ }
560
+ return out;
561
+ }
562
+
563
+ // Would unequipping `worn` drop a set below a bonus tier it currently satisfies? The recommender
564
+ // cannot price the bonus spell, so it used to strip a third set piece for +1 stamina.
565
+ function breaksActiveSetBonus(char: Character, ds: DataStore, worn: ItemDef | undefined): boolean {
566
+ const sid = worn?.setId;
567
+ if (sid == null) return false;
568
+ const set = ds.itemSet ? ds.itemSet(sid) : undefined;
569
+ if (!set?.bonuses?.length) return false;
570
+ const cnt = setPieceCounts(char, ds).get(sid) ?? 0;
571
+ return set.bonuses.some((b) => cnt >= b.pieces && cnt - 1 < b.pieces);
572
+ }
573
+
574
+ /** How much better a replacement must be before it is worth breaking a live set bonus. */
575
+ const SET_BREAK_MARGIN = 0.5;
576
+
577
+ /** Locate the bag slot that already holds a class-11 quiver/pouch, if any. */
578
+ function equippedQuiverPouchSlot(char: Character, ds: DataStore): EquipSlot | null {
579
+ for (const s of BAG_SLOTS) {
580
+ const entry = equippedEntry(char.equipped[s]);
581
+ if (entry == null) continue;
582
+ const bag = ds.item(entry);
583
+ if (bag && isQuiverOrPouch(bag)) return s;
584
+ }
585
+ return null;
586
+ }
587
+
588
+ // Find strict upgrades in the bags, sorted by descending delta. Only one class-11 quiver or pouch
589
+ // may be worn and its haste does not stack, so replacements score as a swap, never additively.
590
+ export function findUpgrades(
591
+ char: Character,
592
+ inventory: Inventory,
593
+ ds: DataStore,
594
+ opts?: EquipOpts,
595
+ ): UpgradeSuggestion[] {
596
+ const bestByEntry = new Map<number, UpgradeSuggestion>();
597
+ const scaleByEntry = new Map<number, CompareScale>();
598
+
599
+ // Hands are decided as one loadout by bestHandLoadout (max(2H, MH+OH)); the per-slot loop
600
+ // below cannot express that and used to trade a 2H for an off-hand and back forever.
601
+ const class11Slot = equippedQuiverPouchSlot(char, ds);
602
+ const rangedWeaponEntry = equippedEntry(char.equipped.ranged);
603
+ const rangedWeapon = rangedWeaponEntry != null ? ds.item(rangedWeaponEntry) : undefined;
604
+
605
+ for (const stack of inventory.stacks) {
606
+ let it: ItemDef | undefined;
607
+ try {
608
+ it = ds.item(stack.item);
609
+ } catch {
610
+ continue;
611
+ }
612
+ // Level / class / proficiency / requiredRep / allowableRace (FI4).
613
+ if (!it?.slot || !canEquipItem(char, it, ds)) continue;
614
+ // Quest items stay in bags until the player moves them — auto-equip must not
615
+ // swallow Surena's Choker (and friends) off the paperdoll for countItem gates.
616
+ if ((it as { questItem?: boolean }).questItem) continue;
617
+
618
+ // Quiver ↔ pouch must match the equipped projectile weapon; wrong family is never an upgrade.
619
+ if (isQuiverOrPouch(it) && !quiverPouchMatchesRangedWeapon(it, rangedWeapon)) {
620
+ continue;
621
+ }
622
+
623
+ // INVTYPE_WEAPON (canOffhand) → MH+OH only when Dual Wield is known.
624
+ // Rings/trinkets → both slots; findUpgrades picks the weaker occupant (best delta).
625
+ const targets = itemSlotTargets(it, opts);
626
+ // Hand candidates belong to the loadout compare, not to this per-slot loop.
627
+ if (targets.some((s) => s === 'mainhand' || s === 'offhand')) continue;
628
+ let bestDelta = -Infinity;
629
+ let bestSlot: EquipSlot | null = null;
630
+ let bestCurrent: number | undefined;
631
+ let bestScale: CompareScale = 'spec';
632
+ const rolled = stack.randomPropertyId != null && stack.randomPropertyId > 0
633
+ ? stack.randomPropertyId
634
+ : undefined;
635
+
636
+ for (const s of targets) {
637
+ // Class-11: only one among bag slots. If one is already worn, only compare as a
638
+ // replacement of that slot — never score against empty bag slots as if haste stacks.
639
+ if (isQuiverOrPouch(it)) {
640
+ if (class11Slot != null && s !== class11Slot) continue;
641
+ // Prefer empty bag slots when none worn; skip occupied non-class-11 bags unless
642
+ // we're only filling empties (capacity swap of normal bags is separate).
643
+ if (class11Slot == null && char.equipped[s] != null) {
644
+ const occupant = ds.item(equippedEntry(char.equipped[s])!);
645
+ // Do not displace a normal bag with a quiver or pouch of equal or less capacity unless
646
+ // the slot is empty. Upgrading a general bag's capacity stays a general-bag concern.
647
+ if (occupant && !isQuiverOrPouch(occupant)) continue;
648
+ }
649
+ }
650
+ const currentEntry = equippedEntry(char.equipped[s]);
651
+ const currentIt = currentEntry != null ? ds.item(currentEntry) : undefined;
652
+ if (isQualityRegression(it, currentIt)) continue;
653
+ let candDef: ItemDef;
654
+ let curDef: ItemDef | undefined;
655
+ let sides: { candVal: number; curVal: number; scale: CompareScale };
656
+ try {
657
+ candDef = withRandomProp(it, ds, stack);
658
+ curDef = currentIt
659
+ ? withRandomProp(currentIt, ds, equippedInstance(char.equipped[s]))
660
+ : undefined;
661
+ sides = upgradeCompare(candDef, curDef, char, ds, opts);
662
+ } catch {
663
+ continue;
664
+ }
665
+ let { candVal, curVal } = sides;
666
+ // Enchants on both sides, and only on the spec branch: wornEnchantValue is in spec points, so
667
+ // adding it to a fallbackGearScore pair would compare two different units.
668
+ if (sides.scale === 'spec') {
669
+ curVal += wornEnchantValue(char, s, ds, opts);
670
+ candVal += candidateEnchantValue(stack, char, ds, opts);
671
+ }
672
+ // Class-11 haste is max-not-sum: candVal/curVal each include that item's haste once.
673
+ // Delta is a swap (cand − cur), never additive stacking of both auras.
674
+ const delta = candVal - curVal;
675
+
676
+ // Losing a live set bonus costs a spell this scorer cannot price; demand a clear win.
677
+ if (breaksActiveSetBonus(char, ds, currentIt) && delta < curVal * SET_BREAK_MARGIN) {
678
+ continue;
679
+ }
680
+
681
+ // Strict improvement + hysteresis (avoid micro-swaps on near equals).
682
+ // Playerbot weights are integers; 0.6 still rejects pure ties / noise.
683
+ if (delta > bestDelta && delta > 0.6) {
684
+ bestDelta = delta;
685
+ bestSlot = s;
686
+ bestCurrent = currentEntry;
687
+ bestScale = sides.scale;
688
+ }
689
+ }
690
+
691
+ if (bestSlot && bestDelta > 0.6) {
692
+ const prev = bestByEntry.get(it.entry);
693
+ if (!prev || bestDelta > prev.valueDelta) {
694
+ bestByEntry.set(it.entry, {
695
+ entry: it.entry,
696
+ targetSlot: bestSlot,
697
+ ...(rolled != null ? { randomPropertyId: rolled } : {}),
698
+ currentEntry: bestCurrent,
699
+ valueDelta: bestDelta,
700
+ scale: bestScale,
701
+ });
702
+ scaleByEntry.set(it.entry, bestScale);
703
+ }
704
+ }
705
+ }
706
+
707
+ // Fallback deltas (quality × 20 + ilvl) are a different unit from spec weights.
708
+ // A spirit chest must not sort above a +str chest for the same slot.
709
+ const specSlots = new Set<EquipSlot>();
710
+ for (const u of bestByEntry.values()) {
711
+ if (scaleByEntry.get(u.entry) === 'spec') specSlots.add(u.targetSlot);
712
+ }
713
+ for (const [entry, u] of [...bestByEntry.entries()]) {
714
+ if (scaleByEntry.get(entry) === 'fallback' && specSlots.has(u.targetSlot)) {
715
+ bestByEntry.delete(entry);
716
+ }
717
+ }
718
+
719
+ for (const h of bestHandLoadout(char, inventory, ds, opts)) {
720
+ const prev = bestByEntry.get(h.entry);
721
+ if (!prev || h.valueDelta > prev.valueDelta) bestByEntry.set(h.entry, h);
722
+ }
723
+
724
+ return [...bestByEntry.values()].sort((a, b) => b.valueDelta - a.valueDelta);
725
+ }
726
+
727
+ /** Convenience: return the single best upgrade (or null). */
728
+ export function bestUpgrade(
729
+ char: Character,
730
+ inventory: Inventory,
731
+ ds: DataStore,
732
+ opts?: EquipOpts,
733
+ ): UpgradeSuggestion | null {
734
+ const ups = findUpgrades(char, inventory, ds, opts);
735
+ return ups.length > 0 ? ups[0] : null;
736
+ }
737
+
738
+ // For the old autopilot empty-slot path. NOT monotonic: with a two-hander worn the off hand IS
739
+ // empty, so equipping it stows the 2H. bestHandLoadout is what stops that cycling.
740
+ export function fillEmptyEquipCandidate(
741
+ state: { char: Character; inventory: Inventory },
742
+ ds: DataStore,
743
+ opts?: EquipOpts,
744
+ ): number | null {
745
+ const up = bestUpgrade(state.char, state.inventory, ds, opts);
746
+ if (!up) return null;
747
+ // Only return if the chosen target was empty (preserve old "fill empty only" contract for autopilot safety)
748
+ const current = state.char.equipped[up.targetSlot];
749
+ return current == null ? up.entry : null;
750
+ }
751
+
752
+ /** Legacy crude score kept for tests that import it directly; delegates for new behavior. */
753
+ export function itemScore(it: ItemDef): number {
754
+ // Fallback numeric that matches old behaviour for existing bot tests.
755
+ // Real recommendations always go through itemValue(..., char, ds).
756
+ let score = it.armor ?? 0;
757
+ for (const s of it.stats ?? []) score += s.value;
758
+ if (it.weapon) score += (it.weapon.dmgMin + it.weapon.dmgMax) / 2;
759
+ return score;
760
+ }
761
+
762
+ /** Re-export slot mapper so callers that did `import { equipTargets }` continue to work. */
763
+ export {
764
+ slotTargets as equipTargets,
765
+ itemSlotTargets,
766
+ equipSlotPickTargets,
767
+ } from './equipment.ts';