azeroth-shell 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1163) hide show
  1. package/README.md +138 -2
  2. package/bin/azsh.mjs +19 -0
  3. package/docs/aifid/eventai-texts.json +4414 -0
  4. package/docs/dungeons/atlas/atlas-rows-dungeons.json +8989 -0
  5. package/docs/dungeons/survey/pack-id-migration.json +2418 -0
  6. package/package.json +26 -4
  7. package/src/autopilot/bossSkip.ts +26 -0
  8. package/src/autopilot/combatRotation.ts +824 -0
  9. package/src/autopilot/config.ts +533 -0
  10. package/src/autopilot/consumables.ts +58 -0
  11. package/src/autopilot/encounterStand.ts +121 -0
  12. package/src/autopilot/objectGatePlan.ts +53 -0
  13. package/src/autopilot/pathEngage.ts +229 -0
  14. package/src/autopilot/plan.ts +1643 -0
  15. package/src/autopilot/questPolicy.ts +274 -0
  16. package/src/autopilot/routeStep.ts +69 -0
  17. package/src/autopilot/sessionReport.ts +88 -0
  18. package/src/autopilot/topOffPower.ts +26 -0
  19. package/src/autopilot/view.ts +476 -0
  20. package/src/cli/bootCheck.mjs +34 -0
  21. package/src/cli/bootData.mjs +57 -0
  22. package/src/cli/combatLogFilter.ts +153 -0
  23. package/src/cli/combatLogFormat.ts +613 -0
  24. package/src/cli/fileRepository.mjs +105 -0
  25. package/src/cli/gzLoader.mjs +31 -0
  26. package/src/cli/liveGauntletEscort.ts +978 -0
  27. package/src/cli/liveStratUndead.ts +305 -0
  28. package/src/cli/macroHostCombat.ts +545 -0
  29. package/src/cli/macroHostWorld.ts +330 -0
  30. package/src/cli/prefs.mjs +31 -0
  31. package/src/cli/register.mjs +4 -0
  32. package/src/cli/repl.mjs +693 -0
  33. package/src/cli/rotationText.mjs +226 -0
  34. package/src/cli/squad.mjs +105 -0
  35. package/src/cli/term.mjs +126 -0
  36. package/src/cli/text.mjs +122 -0
  37. package/src/cli/tui.mjs +626 -0
  38. package/src/cli/tuiArena.mjs +109 -0
  39. package/src/cli/tuiAutopilotSettings.mjs +93 -0
  40. package/src/cli/tuiBags.mjs +180 -0
  41. package/src/cli/tuiBars.mjs +133 -0
  42. package/src/cli/tuiBg.mjs +243 -0
  43. package/src/cli/tuiBulk.mjs +162 -0
  44. package/src/cli/tuiCheck.mjs +1882 -0
  45. package/src/cli/tuiCity.mjs +396 -0
  46. package/src/cli/tuiCompanionKit.mjs +300 -0
  47. package/src/cli/tuiCompanions.mjs +471 -0
  48. package/src/cli/tuiDev.mjs +62 -0
  49. package/src/cli/tuiDungeon.mjs +606 -0
  50. package/src/cli/tuiEnchantTarget.mjs +120 -0
  51. package/src/cli/tuiFight.mjs +577 -0
  52. package/src/cli/tuiFightPanes.mjs +228 -0
  53. package/src/cli/tuiFloor.mjs +506 -0
  54. package/src/cli/tuiGear.mjs +158 -0
  55. package/src/cli/tuiHonor.mjs +74 -0
  56. package/src/cli/tuiLoot.mjs +97 -0
  57. package/src/cli/tuiMacros.mjs +144 -0
  58. package/src/cli/tuiOutfitter.mjs +115 -0
  59. package/src/cli/tuiPet.mjs +116 -0
  60. package/src/cli/tuiProfessions.mjs +800 -0
  61. package/src/cli/tuiRaid.mjs +127 -0
  62. package/src/cli/tuiRep.mjs +65 -0
  63. package/src/cli/tuiSaves.mjs +69 -0
  64. package/src/cli/tuiSearch.mjs +363 -0
  65. package/src/cli/tuiSettings.mjs +151 -0
  66. package/src/cli/tuiSimLab.mjs +80 -0
  67. package/src/cli/tuiTalents.mjs +60 -0
  68. package/src/cli/tuiViews.mjs +1178 -0
  69. package/src/cli/tuiWiki.mjs +181 -0
  70. package/src/cli/tuiWorld.mjs +361 -0
  71. package/src/cli/wikiIndex.ts +259 -0
  72. package/src/cli/wikiSources.ts +355 -0
  73. package/src/data/alteracValley.ts +176 -0
  74. package/src/data/appearanceOptions.ts +534 -0
  75. package/src/data/applyLootChanceSanity.ts +21 -0
  76. package/src/data/createFlavor.ts +96 -0
  77. package/src/data/customItems.ts +33 -0
  78. package/src/data/dataStore.ts +1904 -0
  79. package/src/data/dungeonGameObjects.ts +84 -0
  80. package/src/data/dungeonPlateCover.ts +66 -0
  81. package/src/data/dungeonSpawns.ts +294 -0
  82. package/src/data/dungeons/alterac-valley.ts +135 -0
  83. package/src/data/dungeons/apply-dungeon-rooms.ts +29 -0
  84. package/src/data/dungeons/apply-encounter-outdoors.ts +72 -0
  85. package/src/data/dungeons/apply-instance-geometry.ts +65 -0
  86. package/src/data/dungeons/apply-spawn-placement.ts +171 -0
  87. package/src/data/dungeons/blackfathom-deeps.ts +539 -0
  88. package/src/data/dungeons/blackrock-depths.ts +1410 -0
  89. package/src/data/dungeons/blackwing-lair.ts +129 -0
  90. package/src/data/dungeons/boss-eventai.ts +8 -0
  91. package/src/data/dungeons/deadmines.ts +410 -0
  92. package/src/data/dungeons/dire-maul-east.ts +980 -0
  93. package/src/data/dungeons/dire-maul-north.ts +661 -0
  94. package/src/data/dungeons/dire-maul-west.ts +785 -0
  95. package/src/data/dungeons/dungeon-rooms.json +5479 -0
  96. package/src/data/dungeons/encounter-outdoors.json +359 -0
  97. package/src/data/dungeons/eventai/blackfathom-deeps.ts +308 -0
  98. package/src/data/dungeons/eventai/blackrock-depths.ts +1257 -0
  99. package/src/data/dungeons/eventai/deadmines.ts +264 -0
  100. package/src/data/dungeons/eventai/dire-maul-east.ts +320 -0
  101. package/src/data/dungeons/eventai/gnomeregan.ts +213 -0
  102. package/src/data/dungeons/eventai/helpers.ts +79 -0
  103. package/src/data/dungeons/eventai/index.ts +133 -0
  104. package/src/data/dungeons/eventai/lbrs.ts +372 -0
  105. package/src/data/dungeons/eventai/maraudon.ts +323 -0
  106. package/src/data/dungeons/eventai/ragefire-chasm.ts +108 -0
  107. package/src/data/dungeons/eventai/razorfen-downs.ts +207 -0
  108. package/src/data/dungeons/eventai/razorfen-kraul.ts +326 -0
  109. package/src/data/dungeons/eventai/scholomance.ts +680 -0
  110. package/src/data/dungeons/eventai/shadowfang-keep.ts +230 -0
  111. package/src/data/dungeons/eventai/sm-cathedral.ts +75 -0
  112. package/src/data/dungeons/eventai/sm-graveyard.ts +150 -0
  113. package/src/data/dungeons/eventai/sm-library.ts +55 -0
  114. package/src/data/dungeons/eventai/stratholme-undead.ts +127 -0
  115. package/src/data/dungeons/eventai/sunken-temple.ts +582 -0
  116. package/src/data/dungeons/eventai/the-stockade.ts +228 -0
  117. package/src/data/dungeons/eventai/ubrs.ts +225 -0
  118. package/src/data/dungeons/eventai/uldaman.ts +355 -0
  119. package/src/data/dungeons/eventai/wailing-caverns.ts +396 -0
  120. package/src/data/dungeons/eventai/zul-farrak.ts +591 -0
  121. package/src/data/dungeons/gnomeregan.ts +909 -0
  122. package/src/data/dungeons/index.ts +126 -0
  123. package/src/data/dungeons/instance-geometry.json +5233 -0
  124. package/src/data/dungeons/key-sources.json +169 -0
  125. package/src/data/dungeons/lbrs.ts +996 -0
  126. package/src/data/dungeons/maraudon.ts +786 -0
  127. package/src/data/dungeons/molten-core.ts +194 -0
  128. package/src/data/dungeons/naxxramas.ts +173 -0
  129. package/src/data/dungeons/onyxias-lair.ts +71 -0
  130. package/src/data/dungeons/pack-from-clusters.ts +1256 -0
  131. package/src/data/dungeons/ragefire-chasm.ts +238 -0
  132. package/src/data/dungeons/razorfen-downs.ts +698 -0
  133. package/src/data/dungeons/razorfen-kraul.ts +766 -0
  134. package/src/data/dungeons/ruins-of-ahnqiraj.ts +121 -0
  135. package/src/data/dungeons/scholomance.ts +1076 -0
  136. package/src/data/dungeons/shadowfang-keep.ts +740 -0
  137. package/src/data/dungeons/sm-armory.ts +266 -0
  138. package/src/data/dungeons/sm-cathedral.ts +430 -0
  139. package/src/data/dungeons/sm-graveyard.ts +482 -0
  140. package/src/data/dungeons/sm-library.ts +337 -0
  141. package/src/data/dungeons/stratholme-live.ts +808 -0
  142. package/src/data/dungeons/stratholme-undead.ts +1164 -0
  143. package/src/data/dungeons/sunken-temple.ts +931 -0
  144. package/src/data/dungeons/temple-of-ahnqiraj.ts +119 -0
  145. package/src/data/dungeons/the-stockade.ts +282 -0
  146. package/src/data/dungeons/ubrs.ts +1286 -0
  147. package/src/data/dungeons/uldaman.ts +685 -0
  148. package/src/data/dungeons/wailing-caverns.ts +356 -0
  149. package/src/data/dungeons/zul-farrak.ts +686 -0
  150. package/src/data/dungeons/zul-gurub.ts +142 -0
  151. package/src/data/dungeons.ts +42 -0
  152. package/src/data/fixtures.ts +446 -0
  153. package/src/data/gameobject-data.json.gz +0 -0
  154. package/src/data/item-data.json.gz +0 -0
  155. package/src/data/loot-data.json.gz +0 -0
  156. package/src/data/maps/atlas-approach-maps.json +1425 -0
  157. package/src/data/maps/atlas-landmarks.json +1711 -0
  158. package/src/data/maps/dungeon-viewports.json +392 -0
  159. package/src/data/materializeModDamagePercentTaken.ts +70 -0
  160. package/src/data/materializeModHealthRegen.ts +89 -0
  161. package/src/data/materializeSpellReputation.ts +26 -0
  162. package/src/data/pageTexts.ts +19 -0
  163. package/src/data/profession-data.json.gz +0 -0
  164. package/src/data/raid-plans/blackfathom-deeps.json +86 -0
  165. package/src/data/raid-plans/blackrock-depths.json +419 -0
  166. package/src/data/raid-plans/blackwing-lair.json +328 -0
  167. package/src/data/raid-plans/deadmines.json +55 -0
  168. package/src/data/raid-plans/dire-maul-east.json +94 -0
  169. package/src/data/raid-plans/dire-maul-north.json +70 -0
  170. package/src/data/raid-plans/dire-maul-west.json +75 -0
  171. package/src/data/raid-plans/gnomeregan.json +131 -0
  172. package/src/data/raid-plans/lbrs.json +176 -0
  173. package/src/data/raid-plans/maraudon.json +102 -0
  174. package/src/data/raid-plans/molten-core.json +169 -0
  175. package/src/data/raid-plans/naxxramas.json +354 -0
  176. package/src/data/raid-plans/onyxias-lair.json +18 -0
  177. package/src/data/raid-plans/ragefire-chasm.json +30 -0
  178. package/src/data/raid-plans/razorfen-downs.json +75 -0
  179. package/src/data/raid-plans/razorfen-kraul.json +53 -0
  180. package/src/data/raid-plans/ruins-of-ahnqiraj.json +110 -0
  181. package/src/data/raid-plans/scholomance.json +170 -0
  182. package/src/data/raid-plans/shadowfang-keep.json +87 -0
  183. package/src/data/raid-plans/sm-armory.json +53 -0
  184. package/src/data/raid-plans/sm-cathedral.json +72 -0
  185. package/src/data/raid-plans/sm-graveyard.json +63 -0
  186. package/src/data/raid-plans/sm-library.json +23 -0
  187. package/src/data/raid-plans/stratholme-live.json +129 -0
  188. package/src/data/raid-plans/stratholme-undead.json +73 -0
  189. package/src/data/raid-plans/sunken-temple.json +159 -0
  190. package/src/data/raid-plans/temple-of-ahnqiraj.json +163 -0
  191. package/src/data/raid-plans/the-stockade.json +42 -0
  192. package/src/data/raid-plans/ubrs.json +53 -0
  193. package/src/data/raid-plans/uldaman.json +131 -0
  194. package/src/data/raid-plans/wailing-caverns.json +90 -0
  195. package/src/data/raid-plans/zul-farrak.json +156 -0
  196. package/src/data/raid-plans/zul-gurub.json +307 -0
  197. package/src/data/raidInstanceCreatures.mjs +473 -0
  198. package/src/data/rotations/index.ts +152 -0
  199. package/src/data/rotations/layout.mjs +72 -0
  200. package/src/data/rotations/pve/druid/balance.json +754 -0
  201. package/src/data/rotations/pve/druid/feral-tank.json +2448 -0
  202. package/src/data/rotations/pve/druid/feral.json +2660 -0
  203. package/src/data/rotations/pve/druid/restoration.json +424 -0
  204. package/src/data/rotations/pve/hunter/beast-mastery.json +1288 -0
  205. package/src/data/rotations/pve/hunter/marksmanship.json +1260 -0
  206. package/src/data/rotations/pve/hunter/survival.json +1373 -0
  207. package/src/data/rotations/pve/mage/arcane-leveling.json +1798 -0
  208. package/src/data/rotations/pve/mage/fire-leveling.json +2003 -0
  209. package/src/data/rotations/pve/mage/frost-leveling.json +1912 -0
  210. package/src/data/rotations/pve/paladin/holy.json +755 -0
  211. package/src/data/rotations/pve/paladin/protection.json +962 -0
  212. package/src/data/rotations/pve/paladin/retribution.json +924 -0
  213. package/src/data/rotations/pve/priest/discipline.json +772 -0
  214. package/src/data/rotations/pve/priest/holy.json +707 -0
  215. package/src/data/rotations/pve/priest/shadow.json +787 -0
  216. package/src/data/rotations/pve/rogue/assassination.json +2477 -0
  217. package/src/data/rotations/pve/rogue/combat.json +2483 -0
  218. package/src/data/rotations/pve/rogue/subtlety.json +2523 -0
  219. package/src/data/rotations/pve/shaman/elemental.json +1157 -0
  220. package/src/data/rotations/pve/shaman/enhancement.json +1085 -0
  221. package/src/data/rotations/pve/shaman/restoration.json +592 -0
  222. package/src/data/rotations/pve/warlock/affliction.json +1185 -0
  223. package/src/data/rotations/pve/warlock/demonology.json +1165 -0
  224. package/src/data/rotations/pve/warlock/destruction.json +1177 -0
  225. package/src/data/rotations/pve/warrior/arms.json +3020 -0
  226. package/src/data/rotations/pve/warrior/fury.json +2996 -0
  227. package/src/data/rotations/pve/warrior/protection.json +2509 -0
  228. package/src/data/rotations/pvp/druid/balance.json +593 -0
  229. package/src/data/rotations/pvp/druid/feral.json +3276 -0
  230. package/src/data/rotations/pvp/druid/restoration.json +662 -0
  231. package/src/data/rotations/pvp/hunter/beast-mastery.json +665 -0
  232. package/src/data/rotations/pvp/hunter/marksmanship.json +2406 -0
  233. package/src/data/rotations/pvp/hunter/survival.json +635 -0
  234. package/src/data/rotations/pvp/mage/arcane.json +574 -0
  235. package/src/data/rotations/pvp/mage/fire.json +570 -0
  236. package/src/data/rotations/pvp/mage/frost.json +4048 -0
  237. package/src/data/rotations/pvp/paladin/holy.json +1498 -0
  238. package/src/data/rotations/pvp/paladin/protection.json +567 -0
  239. package/src/data/rotations/pvp/paladin/retribution.json +1110 -0
  240. package/src/data/rotations/pvp/priest/discipline.json +1848 -0
  241. package/src/data/rotations/pvp/priest/holy.json +6340 -0
  242. package/src/data/rotations/pvp/priest/shadow.json +2329 -0
  243. package/src/data/rotations/pvp/rogue/assassination.json +1322 -0
  244. package/src/data/rotations/pvp/rogue/combat.json +5258 -0
  245. package/src/data/rotations/pvp/rogue/subtlety.json +586 -0
  246. package/src/data/rotations/pvp/shaman/elemental.json +1404 -0
  247. package/src/data/rotations/pvp/shaman/enhancement.json +1277 -0
  248. package/src/data/rotations/pvp/shaman/restoration.json +2490 -0
  249. package/src/data/rotations/pvp/warlock/affliction.json +1017 -0
  250. package/src/data/rotations/pvp/warlock/demonology.json +1503 -0
  251. package/src/data/rotations/pvp/warlock/destruction.json +638 -0
  252. package/src/data/rotations/pvp/warrior/arms.json +5665 -0
  253. package/src/data/rotations/pvp/warrior/fury.json +850 -0
  254. package/src/data/rotations/pvp/warrior/protection.json +777 -0
  255. package/src/data/schema/bundle.ts +511 -0
  256. package/src/data/schema/constants.ts +49 -0
  257. package/src/data/schema/creature.ts +454 -0
  258. package/src/data/schema/encounter.ts +155 -0
  259. package/src/data/schema/faction.ts +48 -0
  260. package/src/data/schema/item.ts +297 -0
  261. package/src/data/schema/itemEnchant.ts +105 -0
  262. package/src/data/schema/npc.ts +44 -0
  263. package/src/data/schema/primitives.ts +295 -0
  264. package/src/data/schema/profession.ts +226 -0
  265. package/src/data/schema/quest.ts +154 -0
  266. package/src/data/schema/spell.ts +1149 -0
  267. package/src/data/schema/talent.ts +74 -0
  268. package/src/data/schema/world.ts +124 -0
  269. package/src/data/schema.ts +19 -0
  270. package/src/data/skinNodeGapFill.ts +68 -0
  271. package/src/data/spell-data.json.gz +0 -0
  272. package/src/data/spell-script-targets.json +1 -0
  273. package/src/data/tables/ahItemValues.json.gz +0 -0
  274. package/src/data/tables/alteracValley.json.gz +0 -0
  275. package/src/data/tables/areatriggerTeleports.json.gz +0 -0
  276. package/src/data/tables/botNames.json.gz +0 -0
  277. package/src/data/tables/botPopulation.json.gz +0 -0
  278. package/src/data/tables/botSpecs.json.gz +0 -0
  279. package/src/data/tables/classLevelStats.json.gz +0 -0
  280. package/src/data/tables/combatConditions.json.gz +0 -0
  281. package/src/data/tables/combatSkillMeta.json.gz +0 -0
  282. package/src/data/tables/conditions.json.gz +0 -0
  283. package/src/data/tables/createInfo.json.gz +0 -0
  284. package/src/data/tables/creatureAggroGroups.json.gz +0 -0
  285. package/src/data/tables/creatureClassLevelStats.json.gz +0 -0
  286. package/src/data/tables/creaturePatrolPacks.json.gz +0 -0
  287. package/src/data/tables/creatureWeapons.json.gz +0 -0
  288. package/src/data/tables/creatures.json.gz +0 -0
  289. package/src/data/tables/dbScripts.json.gz +0 -0
  290. package/src/data/tables/dungeonAuthoredRoutes.json.gz +0 -0
  291. package/src/data/tables/dungeonCensus.json.gz +0 -0
  292. package/src/data/tables/dungeonGameObjects.json.gz +0 -0
  293. package/src/data/tables/dungeonPacks.json.gz +0 -0
  294. package/src/data/tables/dungeonPlateCover.json.gz +0 -0
  295. package/src/data/tables/dungeonSpawns.json.gz +0 -0
  296. package/src/data/tables/dungeonSurvey.json.gz +0 -0
  297. package/src/data/tables/durabilityCosts.json.gz +0 -0
  298. package/src/data/tables/durabilityQuality.json.gz +0 -0
  299. package/src/data/tables/enchantApplicators.json.gz +0 -0
  300. package/src/data/tables/entranceYards.json.gz +0 -0
  301. package/src/data/tables/explorationBasexp.json.gz +0 -0
  302. package/src/data/tables/factionTemplates.json.gz +0 -0
  303. package/src/data/tables/factions.json.gz +0 -0
  304. package/src/data/tables/gameEvents.json.gz +0 -0
  305. package/src/data/tables/gameObjects.json.gz +0 -0
  306. package/src/data/tables/gossipMenus.json.gz +0 -0
  307. package/src/data/tables/graveyards.json.gz +0 -0
  308. package/src/data/tables/instanceMaps.json.gz +0 -0
  309. package/src/data/tables/itemEnchantmentTemplates.json.gz +0 -0
  310. package/src/data/tables/itemEnchants.json.gz +0 -0
  311. package/src/data/tables/itemRandomProperties.json.gz +0 -0
  312. package/src/data/tables/itemSets.json.gz +0 -0
  313. package/src/data/tables/items.json.gz +0 -0
  314. package/src/data/tables/levelStats.json.gz +0 -0
  315. package/src/data/tables/locks.json.gz +0 -0
  316. package/src/data/tables/map-pin-overrides.json.gz +0 -0
  317. package/src/data/tables/nonCombatTrash.json.gz +0 -0
  318. package/src/data/tables/npcTexts.json.gz +0 -0
  319. package/src/data/tables/pageTexts.json.gz +0 -0
  320. package/src/data/tables/petAbilityTP.json.gz +0 -0
  321. package/src/data/tables/petGenericSpells.json.gz +0 -0
  322. package/src/data/tables/petLevelStats.json.gz +0 -0
  323. package/src/data/tables/playerbot-weightscales.json.gz +0 -0
  324. package/src/data/tables/pools.json.gz +0 -0
  325. package/src/data/tables/quests.json.gz +0 -0
  326. package/src/data/tables/races.json.gz +0 -0
  327. package/src/data/tables/reputationRanks.json.gz +0 -0
  328. package/src/data/tables/reputationRates.json.gz +0 -0
  329. package/src/data/tables/reputationSpillover.json.gz +0 -0
  330. package/src/data/tables/ridingSpells.json.gz +0 -0
  331. package/src/data/tables/scriptTexts.json.gz +0 -0
  332. package/src/data/tables/soundClipVolume.json.gz +0 -0
  333. package/src/data/tables/spellChain.json.gz +0 -0
  334. package/src/data/tables/spellTeleports.json.gz +0 -0
  335. package/src/data/tables/spells.json.gz +0 -0
  336. package/src/data/tables/talents.json.gz +0 -0
  337. package/src/data/tables/tavernTriggers.json.gz +0 -0
  338. package/src/data/tables/taxiNodes.json.gz +0 -0
  339. package/src/data/tables/taxiRoutes.json.gz +0 -0
  340. package/src/data/tables/trainers.json.gz +0 -0
  341. package/src/data/tables/transports.json.gz +0 -0
  342. package/src/data/tables/travelAnchors.json.gz +0 -0
  343. package/src/data/tables/travelEdges.json.gz +0 -0
  344. package/src/data/tables/unitConditions.json.gz +0 -0
  345. package/src/data/tables/vendors.json.gz +0 -0
  346. package/src/data/tables/weaponEnchantProcs.json.gz +0 -0
  347. package/src/data/tables/xp.json.gz +0 -0
  348. package/src/data/tables/zoneWeather.json.gz +0 -0
  349. package/src/data/tables/zones.json.gz +0 -0
  350. package/src/data/world-data.ts +56 -0
  351. package/src/data/zone-music-sets.json +2751 -0
  352. package/src/dev/etl/lib/loot-chance-sanity.mjs +180 -0
  353. package/src/domain/audioQuality.mjs +145 -0
  354. package/src/domain/bg/ab.ts +433 -0
  355. package/src/domain/bg/arenaComps.ts +644 -0
  356. package/src/domain/bg/arenaLab.ts +695 -0
  357. package/src/domain/bg/arenaPace.ts +31 -0
  358. package/src/domain/bg/arenaRating.ts +110 -0
  359. package/src/domain/bg/av.ts +758 -0
  360. package/src/domain/bg/avEnemyPush.ts +219 -0
  361. package/src/domain/bg/avField.ts +283 -0
  362. package/src/domain/bg/avInstanceNodes.ts +197 -0
  363. package/src/domain/bg/avInstanceScore.ts +123 -0
  364. package/src/domain/bg/avQuestItems.ts +55 -0
  365. package/src/domain/bg/avQuests.ts +210 -0
  366. package/src/domain/bg/avSession.ts +196 -0
  367. package/src/domain/bg/bgConsumes.ts +269 -0
  368. package/src/domain/bg/bgPrebuff.ts +153 -0
  369. package/src/domain/bg/bgRest.ts +91 -0
  370. package/src/domain/bg/bgRoster.ts +305 -0
  371. package/src/domain/bg/bgTier.ts +61 -0
  372. package/src/domain/bg/bgWorld.ts +862 -0
  373. package/src/domain/bg/match.ts +215 -0
  374. package/src/domain/bg/strategies.ts +552 -0
  375. package/src/domain/bg/types.ts +291 -0
  376. package/src/domain/bg/wsg.ts +264 -0
  377. package/src/domain/bots/actionProviderSpec.ts +38 -0
  378. package/src/domain/bots/autoConsumables.ts +285 -0
  379. package/src/domain/bots/betweenPullRest.ts +239 -0
  380. package/src/domain/bots/botGear.ts +248 -0
  381. package/src/domain/bots/botInventory.ts +486 -0
  382. package/src/domain/bots/botPet.ts +535 -0
  383. package/src/domain/bots/botPool.ts +291 -0
  384. package/src/domain/bots/botProfessions.ts +334 -0
  385. package/src/domain/bots/companionActionBar.ts +209 -0
  386. package/src/domain/bots/companionHireCost.ts +236 -0
  387. package/src/domain/bots/companionMissions.ts +582 -0
  388. package/src/domain/bots/companionPrep.ts +254 -0
  389. package/src/domain/bots/companionQuests.ts +270 -0
  390. package/src/domain/bots/companionRep.ts +75 -0
  391. package/src/domain/bots/companionRotation.ts +708 -0
  392. package/src/domain/bots/companionXp.ts +66 -0
  393. package/src/domain/bots/consumableShare.ts +811 -0
  394. package/src/domain/bots/dpsMate.ts +1072 -0
  395. package/src/domain/bots/groupCompReport.ts +132 -0
  396. package/src/domain/bots/healthstoneSupply.ts +198 -0
  397. package/src/domain/bots/outfitter.ts +1056 -0
  398. package/src/domain/bots/paladinPrePull.ts +231 -0
  399. package/src/domain/bots/partyRole.ts +40 -0
  400. package/src/domain/bots/playerbotEquipCache.ts +412 -0
  401. package/src/domain/bots/playerbotItemEligibility.ts +60 -0
  402. package/src/domain/bots/playerbotStatWeight.ts +853 -0
  403. package/src/domain/bots/playerbotUnavailableItems.ts +147 -0
  404. package/src/domain/bots/prePullBuffs.ts +219 -0
  405. package/src/domain/bots/prePullStealth.ts +82 -0
  406. package/src/domain/bots/runSupply.ts +251 -0
  407. package/src/domain/bots/runSupplyPrefs.ts +28 -0
  408. package/src/domain/bots/sendTradeGoods.ts +394 -0
  409. package/src/domain/bots/soulShardCap.ts +35 -0
  410. package/src/domain/bots/squad.ts +842 -0
  411. package/src/domain/bots/squadRun.ts +81 -0
  412. package/src/domain/character/actionbar.ts +346 -0
  413. package/src/domain/character/appearance.ts +165 -0
  414. package/src/domain/character/buildCombatant.ts +1726 -0
  415. package/src/domain/character/character.ts +356 -0
  416. package/src/domain/character/characterName.ts +43 -0
  417. package/src/domain/character/characterRatings.ts +424 -0
  418. package/src/domain/character/characterSpells.ts +282 -0
  419. package/src/domain/character/characterStats.ts +1559 -0
  420. package/src/domain/character/characterTalents.ts +398 -0
  421. package/src/domain/character/combatSkills.ts +994 -0
  422. package/src/domain/character/displayForm.ts +72 -0
  423. package/src/domain/character/formTalentAuras.ts +171 -0
  424. package/src/domain/character/forms.ts +499 -0
  425. package/src/domain/character/races.ts +40 -0
  426. package/src/domain/character/resurrectionSickness.ts +49 -0
  427. package/src/domain/character/spellbook.ts +169 -0
  428. package/src/domain/character/stanceBar.ts +354 -0
  429. package/src/domain/character/stancePrereq.ts +70 -0
  430. package/src/domain/character/talentBuilds.ts +63 -0
  431. package/src/domain/character/talentImport.ts +130 -0
  432. package/src/domain/character/talentLink.ts +123 -0
  433. package/src/domain/character/talents.ts +201 -0
  434. package/src/domain/core/conditionSnapshot.ts +92 -0
  435. package/src/domain/core/hover.ts +14 -0
  436. package/src/domain/core/ids.ts +58 -0
  437. package/src/domain/core/internalNameTags.ts +5 -0
  438. package/src/domain/core/runtimeDataPatches.ts +357 -0
  439. package/src/domain/creature/aiTargeting.ts +588 -0
  440. package/src/domain/creature/combatCondition.ts +157 -0
  441. package/src/domain/creature/creatureAggro.ts +804 -0
  442. package/src/domain/creature/creatureAi.ts +206 -0
  443. package/src/domain/creature/creatureAiConstants.ts +661 -0
  444. package/src/domain/creature/creatureCastList.ts +1007 -0
  445. package/src/domain/creature/creatureEventAi.ts +1409 -0
  446. package/src/domain/creature/creatureGroups.ts +144 -0
  447. package/src/domain/creature/creatureLinking.ts +333 -0
  448. package/src/domain/creature/creatureScaling.ts +320 -0
  449. package/src/domain/creature/creatureTrigger.ts +53 -0
  450. package/src/domain/creature/creatureWander.ts +74 -0
  451. package/src/domain/creature/eventAiTexts.ts +145 -0
  452. package/src/domain/creature/faction.ts +287 -0
  453. package/src/domain/creature/forcedReaction.ts +48 -0
  454. package/src/domain/creature/outdoorHuntable.ts +74 -0
  455. package/src/domain/creature/patrolPacks.ts +210 -0
  456. package/src/domain/creature/reputation.ts +967 -0
  457. package/src/domain/creature/unitFlags.ts +74 -0
  458. package/src/domain/creature/worldBosses.ts +393 -0
  459. package/src/domain/dungeonMusic.mjs +48 -0
  460. package/src/domain/economy/auction.ts +282 -0
  461. package/src/domain/economy/auctionBot.ts +1060 -0
  462. package/src/domain/economy/honorPrice.ts +100 -0
  463. package/src/domain/economy/mail.ts +958 -0
  464. package/src/domain/economy/money.ts +42 -0
  465. package/src/domain/economy/syntheticClassTrainers.ts +62 -0
  466. package/src/domain/economy/trading.ts +296 -0
  467. package/src/domain/economy/vendorSellAll.ts +252 -0
  468. package/src/domain/economy/vendorStock.ts +146 -0
  469. package/src/domain/items/ammo.ts +817 -0
  470. package/src/domain/items/bank.ts +162 -0
  471. package/src/domain/items/consumableFamily.ts +205 -0
  472. package/src/domain/items/craftUpgrades.ts +83 -0
  473. package/src/domain/items/createItem.ts +93 -0
  474. package/src/domain/items/durability.ts +581 -0
  475. package/src/domain/items/equipment.ts +441 -0
  476. package/src/domain/items/equipmentHelper.ts +767 -0
  477. package/src/domain/items/inventory.ts +561 -0
  478. package/src/domain/items/itemBonding.ts +93 -0
  479. package/src/domain/items/itemContainer.ts +245 -0
  480. package/src/domain/items/itemDisplayName.ts +33 -0
  481. package/src/domain/items/itemInstance.ts +181 -0
  482. package/src/domain/items/itemRandomEnchantOutcomes.ts +315 -0
  483. package/src/domain/items/itemRandomProps.ts +77 -0
  484. package/src/domain/items/itemRestrictions.ts +329 -0
  485. package/src/domain/items/itemTeaches.ts +82 -0
  486. package/src/domain/items/itemUseCooldown.ts +52 -0
  487. package/src/domain/items/itemUseTarget.ts +90 -0
  488. package/src/domain/items/junkCategories.ts +174 -0
  489. package/src/domain/items/junkFilter.ts +368 -0
  490. package/src/domain/items/keyring.ts +131 -0
  491. package/src/domain/items/loot.ts +221 -0
  492. package/src/domain/items/mounts.ts +190 -0
  493. package/src/domain/items/onUsePayload.ts +102 -0
  494. package/src/domain/items/pendingLoot.ts +107 -0
  495. package/src/domain/items/relic.ts +105 -0
  496. package/src/domain/items/rocketBoots.ts +36 -0
  497. package/src/domain/items/sortContainer.ts +139 -0
  498. package/src/domain/items/spareContainers.ts +71 -0
  499. package/src/domain/items/spellReagentIndex.ts +131 -0
  500. package/src/domain/items/staleConsumables.ts +66 -0
  501. package/src/domain/items/weaponSpender.ts +110 -0
  502. package/src/domain/listDungeonIds.mjs +28 -0
  503. package/src/domain/macro/compose.ts +239 -0
  504. package/src/domain/macro/conditions.ts +260 -0
  505. package/src/domain/macro/creatureTypes.ts +40 -0
  506. package/src/domain/macro/describe.ts +169 -0
  507. package/src/domain/macro/icon.ts +60 -0
  508. package/src/domain/macro/index.ts +20 -0
  509. package/src/domain/macro/normalize.ts +112 -0
  510. package/src/domain/macro/parse.ts +316 -0
  511. package/src/domain/macro/plan.ts +288 -0
  512. package/src/domain/macro/rotation.ts +590 -0
  513. package/src/domain/macro/rotationEnv.ts +173 -0
  514. package/src/domain/macro/slots.ts +101 -0
  515. package/src/domain/macro/snapshot.ts +114 -0
  516. package/src/domain/macro/templates.ts +446 -0
  517. package/src/domain/macro/types.ts +70 -0
  518. package/src/domain/macro/units.ts +93 -0
  519. package/src/domain/macro/weaponTypes.ts +83 -0
  520. package/src/domain/nav/cityTeleports.ts +10 -0
  521. package/src/domain/nav/mounting.ts +113 -0
  522. package/src/domain/nav/nav.ts +43 -0
  523. package/src/domain/nav/navCollision.ts +606 -0
  524. package/src/domain/nav/navOutdoors.ts +91 -0
  525. package/src/domain/nav/navRegistry.ts +179 -0
  526. package/src/domain/nav/navRoomGraph.ts +302 -0
  527. package/src/domain/nav/navTypes.ts +43 -0
  528. package/src/domain/nav/navmesh.ts +1715 -0
  529. package/src/domain/nav/speed.ts +200 -0
  530. package/src/domain/nav/storey.ts +10 -0
  531. package/src/domain/nav/travel.ts +725 -0
  532. package/src/domain/nav/travelTypes.ts +75 -0
  533. package/src/domain/pet/pet.ts +1150 -0
  534. package/src/domain/pet/petActionBar.ts +180 -0
  535. package/src/domain/pet/petSpellbook.ts +39 -0
  536. package/src/domain/pet/petStable.ts +81 -0
  537. package/src/domain/professions/autoDisenchant.ts +236 -0
  538. package/src/domain/professions/characterEnchants.ts +176 -0
  539. package/src/domain/professions/craftCooldown.ts +52 -0
  540. package/src/domain/professions/enchantApply.ts +62 -0
  541. package/src/domain/professions/enchantTargets.ts +114 -0
  542. package/src/domain/professions/enchanting.ts +236 -0
  543. package/src/domain/professions/gatherFilter.ts +149 -0
  544. package/src/domain/professions/gearEnchant.ts +137 -0
  545. package/src/domain/professions/heldTools.ts +29 -0
  546. package/src/domain/professions/learnAllRecipes.ts +146 -0
  547. package/src/domain/professions/miningHarvest.ts +69 -0
  548. package/src/domain/professions/partyDisenchant.ts +294 -0
  549. package/src/domain/professions/partyWork.ts +83 -0
  550. package/src/domain/professions/pickpocket.ts +172 -0
  551. package/src/domain/professions/poisons.ts +240 -0
  552. package/src/domain/professions/professions.ts +677 -0
  553. package/src/domain/professions/rareNodes.ts +45 -0
  554. package/src/domain/professions/skinLoot.ts +27 -0
  555. package/src/domain/professions/vendorReagents.ts +152 -0
  556. package/src/domain/professions/weaponImbueHand.ts +171 -0
  557. package/src/domain/questFarmFilter.mjs +42 -0
  558. package/src/domain/quests/doQuest.ts +1204 -0
  559. package/src/domain/quests/gossip.ts +308 -0
  560. package/src/domain/quests/gossipTalk.ts +298 -0
  561. package/src/domain/quests/interpreter/canComplete.ts +150 -0
  562. package/src/domain/quests/interpreter/claim.ts +137 -0
  563. package/src/domain/quests/interpreter/dbscript/handlers.ts +1371 -0
  564. package/src/domain/quests/interpreter/dbscript/handlersBatch.ts +1251 -0
  565. package/src/domain/quests/interpreter/dbscript/hooks.ts +331 -0
  566. package/src/domain/quests/interpreter/dbscript/index.ts +212 -0
  567. package/src/domain/quests/interpreter/dbscript/opcodes.ts +257 -0
  568. package/src/domain/quests/interpreter/dbscript/registry.ts +1194 -0
  569. package/src/domain/quests/interpreter/dbscript/registryAreatriggerScripts.ts +539 -0
  570. package/src/domain/quests/interpreter/dbscript/registryAshenvale.ts +553 -0
  571. package/src/domain/quests/interpreter/dbscript/registryAzshara.ts +272 -0
  572. package/src/domain/quests/interpreter/dbscript/registryDarkshore.ts +637 -0
  573. package/src/domain/quests/interpreter/dbscript/registryDesolace.ts +501 -0
  574. package/src/domain/quests/interpreter/dbscript/registryDustwallowMarsh.ts +735 -0
  575. package/src/domain/quests/interpreter/dbscript/registryFelwood.ts +493 -0
  576. package/src/domain/quests/interpreter/dbscript/registryFeralas.ts +485 -0
  577. package/src/domain/quests/interpreter/dbscript/registryGoScripts.ts +203 -0
  578. package/src/domain/quests/interpreter/dbscript/registryMoonglade.ts +288 -0
  579. package/src/domain/quests/interpreter/dbscript/registryNpcProfessions.ts +230 -0
  580. package/src/domain/quests/interpreter/dbscript/registryNpcsSpecial.ts +545 -0
  581. package/src/domain/quests/interpreter/dbscript/registryRazorfenDowns.ts +293 -0
  582. package/src/domain/quests/interpreter/dbscript/registryRazorfenKraul.ts +221 -0
  583. package/src/domain/quests/interpreter/dbscript/registryRedridge.ts +112 -0
  584. package/src/domain/quests/interpreter/dbscript/registrySearingGorge.ts +125 -0
  585. package/src/domain/quests/interpreter/dbscript/registrySiblings.ts +51 -0
  586. package/src/domain/quests/interpreter/dbscript/registrySilverpineForest.ts +172 -0
  587. package/src/domain/quests/interpreter/dbscript/registryStonetalonMountains.ts +180 -0
  588. package/src/domain/quests/interpreter/dbscript/registryStormwindCity.ts +369 -0
  589. package/src/domain/quests/interpreter/dbscript/registryStranglethornVale.ts +115 -0
  590. package/src/domain/quests/interpreter/dbscript/registryStratholme.ts +146 -0
  591. package/src/domain/quests/interpreter/dbscript/registrySunkenTemple.ts +149 -0
  592. package/src/domain/quests/interpreter/dbscript/registrySwampOfSorrows.ts +163 -0
  593. package/src/domain/quests/interpreter/dbscript/registryTanaris.ts +318 -0
  594. package/src/domain/quests/interpreter/dbscript/registryTeldrassil.ts +120 -0
  595. package/src/domain/quests/interpreter/dbscript/registryTheBarrens.ts +603 -0
  596. package/src/domain/quests/interpreter/dbscript/registryThousandNeedles.ts +499 -0
  597. package/src/domain/quests/interpreter/dbscript/registryTirisfalGlades.ts +222 -0
  598. package/src/domain/quests/interpreter/dbscript/registryUngoroCrater.ts +291 -0
  599. package/src/domain/quests/interpreter/dbscript/registryWarEffort.ts +773 -0
  600. package/src/domain/quests/interpreter/dbscript/registryWesternPlaguelands.ts +206 -0
  601. package/src/domain/quests/interpreter/dbscript/registryWestfall.ts +190 -0
  602. package/src/domain/quests/interpreter/dbscript/registryWetlands.ts +186 -0
  603. package/src/domain/quests/interpreter/dbscript/registryWinterspring.ts +235 -0
  604. package/src/domain/quests/interpreter/dbscript/types.ts +817 -0
  605. package/src/domain/quests/interpreter/dbscript/vm.ts +171 -0
  606. package/src/domain/quests/interpreter/diff.ts +349 -0
  607. package/src/domain/quests/interpreter/fixtures/oracle-questlog-qi2.json +2417 -0
  608. package/src/domain/quests/interpreter/flags.ts +101 -0
  609. package/src/domain/quests/interpreter/index.ts +113 -0
  610. package/src/domain/quests/interpreter/live.ts +178 -0
  611. package/src/domain/quests/interpreter/types.ts +81 -0
  612. package/src/domain/quests/interpreter/updaters.ts +412 -0
  613. package/src/domain/quests/questCorpseUse.ts +155 -0
  614. package/src/domain/quests/questDialog.ts +43 -0
  615. package/src/domain/quests/questFight.ts +34 -0
  616. package/src/domain/quests/questObjectiveLabel.ts +39 -0
  617. package/src/domain/quests/questRewardChoice.ts +85 -0
  618. package/src/domain/quests/questScriptCredit.ts +26 -0
  619. package/src/domain/quests/questScriptItemUse.ts +74 -0
  620. package/src/domain/quests/questTameRods.ts +79 -0
  621. package/src/domain/quests/questlog.ts +1545 -0
  622. package/src/domain/quests/talkDeliver.ts +170 -0
  623. package/src/domain/raid/globalActionBar.ts +195 -0
  624. package/src/domain/raid/instanceRoster.ts +194 -0
  625. package/src/domain/raid/partySummon.ts +198 -0
  626. package/src/domain/raid/partyVault.ts +320 -0
  627. package/src/domain/raid/raidBossAbilities.ts +268 -0
  628. package/src/domain/raid/raidComp.ts +335 -0
  629. package/src/domain/raid/raidCustomRows.ts +453 -0
  630. package/src/domain/raid/raidEncounterGear.ts +298 -0
  631. package/src/domain/raid/raidEncounterTactics.ts +412 -0
  632. package/src/domain/raid/raidPlan.ts +509 -0
  633. package/src/domain/raid/raidPlanEdits.ts +98 -0
  634. package/src/domain/raid/raidPlanPacks.ts +480 -0
  635. package/src/domain/raid/raidRecovery.ts +183 -0
  636. package/src/domain/raid/raidRosterTemplate.ts +138 -0
  637. package/src/domain/rotation/auraSide.ts +68 -0
  638. package/src/domain/rotation/build.ts +3031 -0
  639. package/src/domain/rotation/classes/druid.ts +58 -0
  640. package/src/domain/rotation/classes/hooks.ts +59 -0
  641. package/src/domain/rotation/classes/hunter.ts +156 -0
  642. package/src/domain/rotation/classes/index.ts +104 -0
  643. package/src/domain/rotation/classes/mage.ts +99 -0
  644. package/src/domain/rotation/classes/paladin.ts +296 -0
  645. package/src/domain/rotation/classes/priest.ts +94 -0
  646. package/src/domain/rotation/classes/pullOpener.ts +92 -0
  647. package/src/domain/rotation/classes/rogue.ts +69 -0
  648. package/src/domain/rotation/classes/shaman.ts +29 -0
  649. package/src/domain/rotation/classes/supportSpec.ts +94 -0
  650. package/src/domain/rotation/classes/warlock.ts +81 -0
  651. package/src/domain/rotation/classes/warrior.ts +402 -0
  652. package/src/domain/rotation/classify.ts +1381 -0
  653. package/src/domain/rotation/condMetricPicker.ts +379 -0
  654. package/src/domain/rotation/consumables.ts +242 -0
  655. package/src/domain/rotation/evaluate.ts +1115 -0
  656. package/src/domain/rotation/finisherLadder.ts +145 -0
  657. package/src/domain/rotation/invent.ts +938 -0
  658. package/src/domain/rotation/killOrder.ts +30 -0
  659. package/src/domain/rotation/openerForm.ts +22 -0
  660. package/src/domain/rotation/paladinBuffs.ts +568 -0
  661. package/src/domain/rotation/prebuff.ts +283 -0
  662. package/src/domain/rotation/raidRowTuning.ts +34 -0
  663. package/src/domain/rotation/rotation.ts +11 -0
  664. package/src/domain/rotation/rotationProfiles.ts +180 -0
  665. package/src/domain/rotation/rotationSuggestions.ts +851 -0
  666. package/src/domain/rotation/ruleAfterChain.ts +49 -0
  667. package/src/domain/rotation/spec.ts +70 -0
  668. package/src/domain/rotation/spellPicker.ts +140 -0
  669. package/src/domain/rotation/stand.ts +143 -0
  670. package/src/domain/rotation/types.ts +718 -0
  671. package/src/domain/run/battlegroundRun.ts +111 -0
  672. package/src/domain/run/canEnterContext.ts +32 -0
  673. package/src/domain/run/death.ts +561 -0
  674. package/src/domain/run/deathRecovery.ts +289 -0
  675. package/src/domain/run/duel.ts +141 -0
  676. package/src/domain/run/dungeonRun.ts +344 -0
  677. package/src/domain/run/floorRest.ts +159 -0
  678. package/src/domain/run/honor.ts +557 -0
  679. package/src/domain/run/honorWeek.ts +180 -0
  680. package/src/domain/run/whenMap.ts +977 -0
  681. package/src/domain/scriptdev/arathiHighlands.ts +445 -0
  682. package/src/domain/scriptdev/ashenvale.ts +635 -0
  683. package/src/domain/scriptdev/ashenvaleHelpers.ts +1215 -0
  684. package/src/domain/scriptdev/azshara.ts +892 -0
  685. package/src/domain/scriptdev/blackfathomDeeps.ts +212 -0
  686. package/src/domain/scriptdev/blackrockDepths.ts +1434 -0
  687. package/src/domain/scriptdev/blackrockSpire.ts +730 -0
  688. package/src/domain/scriptdev/blackwingLair.ts +521 -0
  689. package/src/domain/scriptdev/burningSteppes.ts +62 -0
  690. package/src/domain/scriptdev/classFilter.ts +43 -0
  691. package/src/domain/scriptdev/darkshore.ts +817 -0
  692. package/src/domain/scriptdev/darkshoreHelpers.ts +853 -0
  693. package/src/domain/scriptdev/deadmines.ts +331 -0
  694. package/src/domain/scriptdev/desolace.ts +1239 -0
  695. package/src/domain/scriptdev/direMaul.ts +859 -0
  696. package/src/domain/scriptdev/durotar.ts +532 -0
  697. package/src/domain/scriptdev/dustwallowMarsh.ts +758 -0
  698. package/src/domain/scriptdev/dustwallowMarshHelpers.ts +994 -0
  699. package/src/domain/scriptdev/easternPlaguelands.ts +21 -0
  700. package/src/domain/scriptdev/felwood.ts +1055 -0
  701. package/src/domain/scriptdev/feralas.ts +571 -0
  702. package/src/domain/scriptdev/feralasHelpers.ts +838 -0
  703. package/src/domain/scriptdev/gnomeregan.ts +466 -0
  704. package/src/domain/scriptdev/guards.ts +616 -0
  705. package/src/domain/scriptdev/hinterlands.ts +693 -0
  706. package/src/domain/scriptdev/host.ts +1134 -0
  707. package/src/domain/scriptdev/index.ts +123 -0
  708. package/src/domain/scriptdev/instanceRaids.ts +136 -0
  709. package/src/domain/scriptdev/itemScripts.ts +37 -0
  710. package/src/domain/scriptdev/lochModan.ts +283 -0
  711. package/src/domain/scriptdev/maraudon.ts +232 -0
  712. package/src/domain/scriptdev/moltenCore.ts +831 -0
  713. package/src/domain/scriptdev/moonglade.ts +659 -0
  714. package/src/domain/scriptdev/moongladeHelpers.ts +933 -0
  715. package/src/domain/scriptdev/naxxramas.ts +577 -0
  716. package/src/domain/scriptdev/naxxramasConstruct.ts +364 -0
  717. package/src/domain/scriptdev/naxxramasFrostwyrm.ts +378 -0
  718. package/src/domain/scriptdev/naxxramasMilitary.ts +276 -0
  719. package/src/domain/scriptdev/npcProfessions.ts +1025 -0
  720. package/src/domain/scriptdev/npcsSpecial.ts +1379 -0
  721. package/src/domain/scriptdev/onyxiasLair.ts +313 -0
  722. package/src/domain/scriptdev/orgrimmar.ts +147 -0
  723. package/src/domain/scriptdev/professionSpecConsumer.ts +481 -0
  724. package/src/domain/scriptdev/razorfenDowns.ts +468 -0
  725. package/src/domain/scriptdev/razorfenKraul.ts +410 -0
  726. package/src/domain/scriptdev/redridgeMountains.ts +163 -0
  727. package/src/domain/scriptdev/registry.ts +945 -0
  728. package/src/domain/scriptdev/ruinsOfAhnqiraj.ts +356 -0
  729. package/src/domain/scriptdev/scarletMonastery.ts +713 -0
  730. package/src/domain/scriptdev/scholomance.ts +682 -0
  731. package/src/domain/scriptdev/searingGorge.ts +295 -0
  732. package/src/domain/scriptdev/shadowfangKeep.ts +181 -0
  733. package/src/domain/scriptdev/silithus.ts +71 -0
  734. package/src/domain/scriptdev/silverpineForest.ts +662 -0
  735. package/src/domain/scriptdev/stonetalonMountains.ts +493 -0
  736. package/src/domain/scriptdev/stormwindCity.ts +1192 -0
  737. package/src/domain/scriptdev/stranglethornVale.ts +402 -0
  738. package/src/domain/scriptdev/stratholme.ts +650 -0
  739. package/src/domain/scriptdev/stratholmeScripts.ts +505 -0
  740. package/src/domain/scriptdev/sunkenTemple.ts +736 -0
  741. package/src/domain/scriptdev/swampOfSorrows.ts +22 -0
  742. package/src/domain/scriptdev/tanaris.ts +391 -0
  743. package/src/domain/scriptdev/tanarisHelpers.ts +661 -0
  744. package/src/domain/scriptdev/teldrassil.ts +143 -0
  745. package/src/domain/scriptdev/templeOfAhnqiraj.ts +1013 -0
  746. package/src/domain/scriptdev/theBarrens.ts +709 -0
  747. package/src/domain/scriptdev/theBarrensHelpers.ts +1026 -0
  748. package/src/domain/scriptdev/thousandNeedles.ts +426 -0
  749. package/src/domain/scriptdev/thousandNeedlesHelpers.ts +566 -0
  750. package/src/domain/scriptdev/tirisfalGlades.ts +533 -0
  751. package/src/domain/scriptdev/types.ts +1026 -0
  752. package/src/domain/scriptdev/uldaman.ts +437 -0
  753. package/src/domain/scriptdev/ungoroCrater.ts +549 -0
  754. package/src/domain/scriptdev/ungoroCraterHelpers.ts +1006 -0
  755. package/src/domain/scriptdev/wailingCaverns.ts +700 -0
  756. package/src/domain/scriptdev/warEffort.ts +371 -0
  757. package/src/domain/scriptdev/westernPlaguelands.ts +952 -0
  758. package/src/domain/scriptdev/westfall.ts +767 -0
  759. package/src/domain/scriptdev/wetlands.ts +660 -0
  760. package/src/domain/scriptdev/winterspring.ts +482 -0
  761. package/src/domain/scriptdev/winterspringHelpers.ts +801 -0
  762. package/src/domain/scriptdev/worldBosses.ts +605 -0
  763. package/src/domain/scriptdev/zulfarrak.ts +478 -0
  764. package/src/domain/scriptdev/zulgurub.ts +1152 -0
  765. package/src/domain/sim/dummySim.ts +408 -0
  766. package/src/domain/sim/targetDummy.ts +29 -0
  767. package/src/domain/social/guild.ts +148 -0
  768. package/src/domain/spells/areaAuraMembership.ts +93 -0
  769. package/src/domain/spells/breakableStunCc.ts +166 -0
  770. package/src/domain/spells/cancelAura.ts +80 -0
  771. package/src/domain/spells/diminishing.ts +167 -0
  772. package/src/domain/spells/dispel.ts +149 -0
  773. package/src/domain/spells/dispelMechanic.ts +105 -0
  774. package/src/domain/spells/equipSpells.ts +247 -0
  775. package/src/domain/spells/learnOnTargets.ts +260 -0
  776. package/src/domain/spells/mergeSchoolImmunityFromRaw.ts +66 -0
  777. package/src/domain/spells/resurrectSpell.ts +124 -0
  778. package/src/domain/spells/spellPushback.ts +39 -0
  779. package/src/domain/spells/spellReflect.ts +43 -0
  780. package/src/domain/spells/stealth.ts +183 -0
  781. package/src/domain/spells/totem.ts +394 -0
  782. package/src/domain/spells/worldCast.ts +187 -0
  783. package/src/domain/world/areaTriggerLocks.ts +177 -0
  784. package/src/domain/world/dungeonMusic.ts +108 -0
  785. package/src/domain/world/gameEvents.ts +119 -0
  786. package/src/domain/world/gameObjects.ts +1030 -0
  787. package/src/domain/world/goEventFire.ts +234 -0
  788. package/src/domain/world/goMoTransport.ts +74 -0
  789. package/src/domain/world/goTransport.ts +81 -0
  790. package/src/domain/world/hazards.ts +459 -0
  791. package/src/domain/world/openLock.ts +398 -0
  792. package/src/domain/world/pools.ts +470 -0
  793. package/src/domain/world/restArea.ts +37 -0
  794. package/src/domain/world/weather.ts +201 -0
  795. package/src/domain/zoneAmbience.mjs +87 -0
  796. package/src/domain/zoneMusic.mjs +62 -0
  797. package/src/domain/zoneMusicQueue.mjs +7 -0
  798. package/src/engine/combat/activeSeal.ts +39 -0
  799. package/src/engine/combat/aiTargetResolve.ts +64 -0
  800. package/src/engine/combat/aoeCast.ts +289 -0
  801. package/src/engine/combat/applyConsumeAura.ts +74 -0
  802. package/src/engine/combat/applyDemonicSacrifice.ts +70 -0
  803. package/src/engine/combat/applyDispelMechanic.ts +30 -0
  804. package/src/engine/combat/applyHealEffect.ts +301 -0
  805. package/src/engine/combat/applySchoolAbsorb.ts +114 -0
  806. package/src/engine/combat/applySpell.ts +3169 -0
  807. package/src/engine/combat/applySpellLate.ts +2026 -0
  808. package/src/engine/combat/applySpellLateBag.ts +144 -0
  809. package/src/engine/combat/areaAura.ts +283 -0
  810. package/src/engine/combat/attackTable.ts +508 -0
  811. package/src/engine/combat/battleRez.ts +87 -0
  812. package/src/engine/combat/castAction.ts +36 -0
  813. package/src/engine/combat/castTargetGates.ts +75 -0
  814. package/src/engine/combat/castableKit.ts +68 -0
  815. package/src/engine/combat/ccMirrorUpgrade.ts +39 -0
  816. package/src/engine/combat/chainFan.ts +210 -0
  817. package/src/engine/combat/channel.ts +423 -0
  818. package/src/engine/combat/chaseCloseness.ts +95 -0
  819. package/src/engine/combat/cmangosCastGates.ts +129 -0
  820. package/src/engine/combat/combatFlag.ts +77 -0
  821. package/src/engine/combat/combatGeometry.ts +1329 -0
  822. package/src/engine/combat/combustion.ts +68 -0
  823. package/src/engine/combat/context.ts +730 -0
  824. package/src/engine/combat/createSession.ts +1165 -0
  825. package/src/engine/combat/creatureLeash.ts +38 -0
  826. package/src/engine/combat/crowdControl.ts +1259 -0
  827. package/src/engine/combat/dispelDuty.ts +54 -0
  828. package/src/engine/combat/dispelReflect.ts +609 -0
  829. package/src/engine/combat/displaceFloor.ts +113 -0
  830. package/src/engine/combat/duelBounds.ts +47 -0
  831. package/src/engine/combat/equippedItemGate.ts +297 -0
  832. package/src/engine/combat/evadeLifecycle.ts +63 -0
  833. package/src/engine/combat/eventAi.ts +2220 -0
  834. package/src/engine/combat/facing.ts +74 -0
  835. package/src/engine/combat/fearFlee.ts +137 -0
  836. package/src/engine/combat/fighterFactory.ts +1144 -0
  837. package/src/engine/combat/forceDespawnAction.ts +51 -0
  838. package/src/engine/combat/formulas.ts +807 -0
  839. package/src/engine/combat/friendlyFan.ts +55 -0
  840. package/src/engine/combat/groundPoolTick.ts +210 -0
  841. package/src/engine/combat/hazards.ts +114 -0
  842. package/src/engine/combat/healTargets.ts +226 -0
  843. package/src/engine/combat/heartbeatResist.ts +49 -0
  844. package/src/engine/combat/hostileItemUse.ts +75 -0
  845. package/src/engine/combat/interruptAuras.ts +66 -0
  846. package/src/engine/combat/itemRescue.ts +49 -0
  847. package/src/engine/combat/itemUse.ts +260 -0
  848. package/src/engine/combat/kitById.ts +23 -0
  849. package/src/engine/combat/knockBack.ts +201 -0
  850. package/src/engine/combat/leap.ts +89 -0
  851. package/src/engine/combat/mitigation.ts +587 -0
  852. package/src/engine/combat/modTaunt.ts +43 -0
  853. package/src/engine/combat/motionClaim.ts +268 -0
  854. package/src/engine/combat/motionGate.ts +150 -0
  855. package/src/engine/combat/motionGenerator.ts +27 -0
  856. package/src/engine/combat/navSight.ts +138 -0
  857. package/src/engine/combat/perfSink.ts +28 -0
  858. package/src/engine/combat/periodicDue.ts +55 -0
  859. package/src/engine/combat/petAuras.ts +86 -0
  860. package/src/engine/combat/pickAction.ts +3449 -0
  861. package/src/engine/combat/powerForm.ts +735 -0
  862. package/src/engine/combat/powerPools.ts +49 -0
  863. package/src/engine/combat/predicates.ts +538 -0
  864. package/src/engine/combat/procsDamage.ts +1823 -0
  865. package/src/engine/combat/reactiveGates.ts +135 -0
  866. package/src/engine/combat/roles.ts +389 -0
  867. package/src/engine/combat/rotationSubject.ts +78 -0
  868. package/src/engine/combat/ruleAfter.ts +106 -0
  869. package/src/engine/combat/seedDisplayAuras.ts +203 -0
  870. package/src/engine/combat/seedOocEffects.ts +317 -0
  871. package/src/engine/combat/seedSchoolImmunities.ts +45 -0
  872. package/src/engine/combat/session-types.ts +458 -0
  873. package/src/engine/combat/sessionApi.ts +1785 -0
  874. package/src/engine/combat/sessionCharge.ts +124 -0
  875. package/src/engine/combat/sessionChase.ts +869 -0
  876. package/src/engine/combat/sessionDeaths.ts +469 -0
  877. package/src/engine/combat/sessionFocus.ts +506 -0
  878. package/src/engine/combat/sessionFollow.ts +167 -0
  879. package/src/engine/combat/sessionGeometry.ts +188 -0
  880. package/src/engine/combat/sessionHome.ts +75 -0
  881. package/src/engine/combat/sessionInject.ts +719 -0
  882. package/src/engine/combat/sessionMechanicMove.ts +555 -0
  883. package/src/engine/combat/sessionMotion.ts +1553 -0
  884. package/src/engine/combat/sessionMotionKit.ts +247 -0
  885. package/src/engine/combat/sessionMoveIntent.ts +49 -0
  886. package/src/engine/combat/sessionMoveOrder.ts +200 -0
  887. package/src/engine/combat/sessionPathTo.ts +657 -0
  888. package/src/engine/combat/sessionPools.ts +688 -0
  889. package/src/engine/combat/sessionSteer.ts +144 -0
  890. package/src/engine/combat/sessionStepBack.ts +151 -0
  891. package/src/engine/combat/sessionStepWrap.ts +116 -0
  892. package/src/engine/combat/sessionView.ts +442 -0
  893. package/src/engine/combat/simEffects.ts +32 -0
  894. package/src/engine/combat/simFacade.ts +620 -0
  895. package/src/engine/combat/simPump.ts +264 -0
  896. package/src/engine/combat/simSnapshot.ts +165 -0
  897. package/src/engine/combat/simThreadPool.ts +35 -0
  898. package/src/engine/combat/skeramImages.ts +57 -0
  899. package/src/engine/combat/slowUpdate.ts +178 -0
  900. package/src/engine/combat/snapToFloor.ts +42 -0
  901. package/src/engine/combat/speedAura.ts +29 -0
  902. package/src/engine/combat/spellReagents.ts +71 -0
  903. package/src/engine/combat/stealthDetect.ts +93 -0
  904. package/src/engine/combat/stepBackMotion.ts +171 -0
  905. package/src/engine/combat/stepSession.ts +3102 -0
  906. package/src/engine/combat/summonCast.ts +243 -0
  907. package/src/engine/combat/thaddiusPolarity.ts +97 -0
  908. package/src/engine/combat/threat.ts +388 -0
  909. package/src/engine/combat/threatOps.ts +272 -0
  910. package/src/engine/combat/tickWorkerBody.ts +211 -0
  911. package/src/engine/combat/totemAuras.ts +122 -0
  912. package/src/engine/combat/triggerPayload.ts +42 -0
  913. package/src/engine/combat/triggeredCompanion.ts +63 -0
  914. package/src/engine/combat/types.ts +1897 -0
  915. package/src/engine/combat/useObjectTrap.ts +140 -0
  916. package/src/engine/combat/walkSurface.ts +54 -0
  917. package/src/engine/combat/weapon.ts +1248 -0
  918. package/src/engine/combat/worldFrame.ts +43 -0
  919. package/src/engine/combat.solo-golden.json +2242 -0
  920. package/src/engine/combat.ts +84 -0
  921. package/src/engine/core/detMath.ts +289 -0
  922. package/src/engine/core/events.ts +357 -0
  923. package/src/engine/core/rng.ts +36 -0
  924. package/src/engine/game/actionBars.ts +124 -0
  925. package/src/engine/game/activateObjectFromSpell.ts +320 -0
  926. package/src/engine/game/applyActiveObjectFromDbScript.ts +98 -0
  927. package/src/engine/game/applyDeathAndSpellScripts.ts +268 -0
  928. package/src/engine/game/applyDoorFromDbScript.ts +388 -0
  929. package/src/engine/game/applyEscortFromDbScript.ts +290 -0
  930. package/src/engine/game/applyGoSpellcasterCast.ts +40 -0
  931. package/src/engine/game/applyHoverFromDbScript.ts +110 -0
  932. package/src/engine/game/applyOocResurrect.ts +71 -0
  933. package/src/engine/game/applySpellDurability.ts +115 -0
  934. package/src/engine/game/applyTailFromDbScript.ts +478 -0
  935. package/src/engine/game/applyTerminateFromDbScript.ts +95 -0
  936. package/src/engine/game/auctionMail.ts +269 -0
  937. package/src/engine/game/bagOverflow.ts +130 -0
  938. package/src/engine/game/bank.ts +110 -0
  939. package/src/engine/game/barAutofill.ts +26 -0
  940. package/src/engine/game/battleground.ts +369 -0
  941. package/src/engine/game/combatEnemySpec.ts +216 -0
  942. package/src/engine/game/combatObjectTraps.ts +167 -0
  943. package/src/engine/game/combatSeed.ts +320 -0
  944. package/src/engine/game/combatSession.ts +3241 -0
  945. package/src/engine/game/combatSessionClock.ts +62 -0
  946. package/src/engine/game/companionQuestActions.ts +242 -0
  947. package/src/engine/game/companionTraining.ts +40 -0
  948. package/src/engine/game/consumables.ts +624 -0
  949. package/src/engine/game/context.ts +53 -0
  950. package/src/engine/game/createHealthstone.ts +45 -0
  951. package/src/engine/game/deathFlow.ts +127 -0
  952. package/src/engine/game/devGrant.ts +117 -0
  953. package/src/engine/game/dynamicObject.ts +365 -0
  954. package/src/engine/game/enchantItem.ts +177 -0
  955. package/src/engine/game/equipmentHelper.ts +806 -0
  956. package/src/engine/game/factionState.ts +108 -0
  957. package/src/engine/game/garmentsOoc.ts +69 -0
  958. package/src/engine/game/globalActionBar.ts +179 -0
  959. package/src/engine/game/goInteractQuestCredit.ts +51 -0
  960. package/src/engine/game/goMoTransportUse.ts +61 -0
  961. package/src/engine/game/goTransportUse.ts +60 -0
  962. package/src/engine/game/healthstoneUpkeep.ts +59 -0
  963. package/src/engine/game/killSkin.ts +124 -0
  964. package/src/engine/game/learnFromItem.ts +118 -0
  965. package/src/engine/game/loadReconcile.ts +551 -0
  966. package/src/engine/game/loot.ts +294 -0
  967. package/src/engine/game/macros.ts +125 -0
  968. package/src/engine/game/mail.ts +293 -0
  969. package/src/engine/game/meetingStoneQueue.ts +75 -0
  970. package/src/engine/game/meetingStoneUse.ts +54 -0
  971. package/src/engine/game/newGameState.ts +363 -0
  972. package/src/engine/game/oocAuraInterrupt.ts +92 -0
  973. package/src/engine/game/oocCast.ts +241 -0
  974. package/src/engine/game/oocCastEffects.ts +803 -0
  975. package/src/engine/game/oocCastMethods.ts +1077 -0
  976. package/src/engine/game/openLockFromSpell.ts +174 -0
  977. package/src/engine/game/outdoorPvp.ts +187 -0
  978. package/src/engine/game/outfitter.ts +644 -0
  979. package/src/engine/game/paladinBoard.ts +393 -0
  980. package/src/engine/game/partyAuras.ts +121 -0
  981. package/src/engine/game/persistCombatAuras.ts +91 -0
  982. package/src/engine/game/pets.ts +459 -0
  983. package/src/engine/game/prePullHealthstones.ts +154 -0
  984. package/src/engine/game/professions.ts +2227 -0
  985. package/src/engine/game/pruneStaleRuntime.ts +39 -0
  986. package/src/engine/game/questFightCredit.ts +36 -0
  987. package/src/engine/game/questItemOnCorpse.ts +166 -0
  988. package/src/engine/game/questItemOnCreature.ts +103 -0
  989. package/src/engine/game/questLog.ts +879 -0
  990. package/src/engine/game/questSpellComplete.ts +21 -0
  991. package/src/engine/game/questTurnIn.ts +598 -0
  992. package/src/engine/game/raidParty.ts +32 -0
  993. package/src/engine/game/reagentBuyIn.ts +39 -0
  994. package/src/engine/game/regenRest.ts +186 -0
  995. package/src/engine/game/rotation.ts +425 -0
  996. package/src/engine/game/runFullDungeon.ts +611 -0
  997. package/src/engine/game/runSupply.ts +80 -0
  998. package/src/engine/game/sanitizeDriftedItems.ts +135 -0
  999. package/src/engine/game/scriptDevGoUse.ts +397 -0
  1000. package/src/engine/game/scriptDevInnkeeper.ts +150 -0
  1001. package/src/engine/game/scriptDevProfessionSpec.ts +99 -0
  1002. package/src/engine/game/sendEventFromSpell.ts +87 -0
  1003. package/src/engine/game/sortContainers.ts +85 -0
  1004. package/src/engine/game/spellReputation.ts +69 -0
  1005. package/src/engine/game/squad/squadDungeonSeating.ts +197 -0
  1006. package/src/engine/game/squadDungeon.ts +4222 -0
  1007. package/src/engine/game/squadQuestShare.ts +260 -0
  1008. package/src/engine/game/summonObjectSlot.ts +69 -0
  1009. package/src/engine/game/summonObjectWild.ts +73 -0
  1010. package/src/engine/game/summoningRitualUse.ts +141 -0
  1011. package/src/engine/game/talents.ts +356 -0
  1012. package/src/engine/game/tamingRodUse.ts +66 -0
  1013. package/src/engine/game/tempSpawnCreature.ts +136 -0
  1014. package/src/engine/game/tickDungeonPatrolScripts.ts +205 -0
  1015. package/src/engine/game/tickTimedQuests.ts +28 -0
  1016. package/src/engine/game/trade.ts +586 -0
  1017. package/src/engine/game/travel.ts +1155 -0
  1018. package/src/engine/game/types.ts +1855 -0
  1019. package/src/engine/game/vendorOffers.ts +244 -0
  1020. package/src/engine/game/weaponImbueItem.ts +281 -0
  1021. package/src/engine/game/worldSession.ts +183 -0
  1022. package/src/engine/game/worldState.ts +166 -0
  1023. package/src/engine/game.ts +968 -0
  1024. package/src/engine/spells/GAP.md +67 -0
  1025. package/src/engine/spells/absorbs.ts +376 -0
  1026. package/src/engine/spells/addTargetTrigger.ts +53 -0
  1027. package/src/engine/spells/auraPerSecondCost.ts +50 -0
  1028. package/src/engine/spells/auraStacking.ts +497 -0
  1029. package/src/engine/spells/cmangos-special-cases-combustion.ts +13 -0
  1030. package/src/engine/spells/cmangos-special-cases-s18.ts +445 -0
  1031. package/src/engine/spells/cmangos-special-cases-s19.ts +324 -0
  1032. package/src/engine/spells/cmangos-special-cases-s20.ts +385 -0
  1033. package/src/engine/spells/cmangos-special-cases-s21.ts +116 -0
  1034. package/src/engine/spells/cmangos-special-cases-s22.ts +24 -0
  1035. package/src/engine/spells/cmangos-special-cases-s23.ts +52 -0
  1036. package/src/engine/spells/cmangos-special-cases.ts +1570 -0
  1037. package/src/engine/spells/conditions.ts +718 -0
  1038. package/src/engine/spells/effects.ts +203 -0
  1039. package/src/engine/spells/fixtures/oracle-effects-lock9a.json +1 -0
  1040. package/src/engine/spells/immunity.ts +942 -0
  1041. package/src/engine/spells/intentEffects.ts +351 -0
  1042. package/src/engine/spells/interpreter/GAPS.md +21 -0
  1043. package/src/engine/spells/interpreter/amount.ts +109 -0
  1044. package/src/engine/spells/interpreter/class-scripts-kit.ts +478 -0
  1045. package/src/engine/spells/interpreter/diff.ts +246 -0
  1046. package/src/engine/spells/interpreter/duration.ts +90 -0
  1047. package/src/engine/spells/interpreter/form-attrs.json +1 -0
  1048. package/src/engine/spells/interpreter/form-attrs.ts +95 -0
  1049. package/src/engine/spells/interpreter/handlers/aura-remove.ts +113 -0
  1050. package/src/engine/spells/interpreter/handlers/auras-control.ts +1547 -0
  1051. package/src/engine/spells/interpreter/handlers/auras-core.ts +1583 -0
  1052. package/src/engine/spells/interpreter/handlers/auras-misc.ts +1774 -0
  1053. package/src/engine/spells/interpreter/handlers/effect-disenchant.ts +17 -0
  1054. package/src/engine/spells/interpreter/handlers/effect-skinning.ts +20 -0
  1055. package/src/engine/spells/interpreter/handlers/effects-action-utility.ts +1455 -0
  1056. package/src/engine/spells/interpreter/handlers/effects-core.ts +432 -0
  1057. package/src/engine/spells/interpreter/handlers/effects-remainder.ts +105 -0
  1058. package/src/engine/spells/interpreter/handlers/effects-summon-item.ts +687 -0
  1059. package/src/engine/spells/interpreter/handlers/mod-increase-energy-percent.ts +36 -0
  1060. package/src/engine/spells/interpreter/handlers/mod-increase-energy.ts +36 -0
  1061. package/src/engine/spells/interpreter/handlers/periodic-trigger-zero.ts +327 -0
  1062. package/src/engine/spells/interpreter/handlers/procs.ts +131 -0
  1063. package/src/engine/spells/interpreter/handlers/registry.ts +975 -0
  1064. package/src/engine/spells/interpreter/handlers/shared.ts +667 -0
  1065. package/src/engine/spells/interpreter/handlers.ts +9 -0
  1066. package/src/engine/spells/interpreter/hunter-kit.ts +202 -0
  1067. package/src/engine/spells/interpreter/index.ts +525 -0
  1068. package/src/engine/spells/interpreter/item-triggers.ts +1121 -0
  1069. package/src/engine/spells/interpreter/lift-consume-energy.ts +37 -0
  1070. package/src/engine/spells/interpreter/mage-portals.ts +37 -0
  1071. package/src/engine/spells/interpreter/materialize-charm.ts +88 -0
  1072. package/src/engine/spells/interpreter/materialize-dispel-mechanic.ts +25 -0
  1073. package/src/engine/spells/interpreter/materialize-rating-buffs.ts +81 -0
  1074. package/src/engine/spells/interpreter/materialize-speed.ts +109 -0
  1075. package/src/engine/spells/interpreter/materialize-spell-magnet.ts +22 -0
  1076. package/src/engine/spells/interpreter/opcodes.ts +789 -0
  1077. package/src/engine/spells/interpreter/paladin-kit.ts +95 -0
  1078. package/src/engine/spells/interpreter/paladin-seals.ts +499 -0
  1079. package/src/engine/spells/interpreter/priest-warlock-kit.ts +135 -0
  1080. package/src/engine/spells/interpreter/proc.ts +443 -0
  1081. package/src/engine/spells/interpreter/registry/helpers.ts +16 -0
  1082. package/src/engine/spells/interpreter/registry/index.ts +216 -0
  1083. package/src/engine/spells/interpreter/registry/packs/class-abilities.ts +304 -0
  1084. package/src/engine/spells/interpreter/registry/packs/dire-maul.ts +44 -0
  1085. package/src/engine/spells/interpreter/registry/packs/dummy-script-tail.ts +1065 -0
  1086. package/src/engine/spells/interpreter/registry/packs/ex-wave-m.ts +70 -0
  1087. package/src/engine/spells/interpreter/registry/packs/life-tap.ts +107 -0
  1088. package/src/engine/spells/interpreter/registry/packs/paladin.ts +246 -0
  1089. package/src/engine/spells/interpreter/registry/packs/raid-script-summons.ts +26 -0
  1090. package/src/engine/spells/interpreter/registry/packs/raid-threat-wipe.ts +22 -0
  1091. package/src/engine/spells/interpreter/registry/packs/shaman.ts +214 -0
  1092. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-a.ts +269 -0
  1093. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-b.ts +370 -0
  1094. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-c.ts +172 -0
  1095. package/src/engine/spells/interpreter/registry/packs/si4-dummy-hunter.ts +60 -0
  1096. package/src/engine/spells/interpreter/registry/packs/si4-dummy-warrior.ts +31 -0
  1097. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-a.ts +114 -0
  1098. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-b.ts +249 -0
  1099. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-c.ts +233 -0
  1100. package/src/engine/spells/interpreter/registry/types.ts +48 -0
  1101. package/src/engine/spells/interpreter/talent-scripted.ts +329 -0
  1102. package/src/engine/spells/interpreter/targeting.ts +90 -0
  1103. package/src/engine/spells/interpreter/types-intent.ts +1501 -0
  1104. package/src/engine/spells/interpreter/types.ts +419 -0
  1105. package/src/engine/spells/interpreter/warrior-druid-kit.ts +314 -0
  1106. package/src/engine/spells/interpreter/weapon-imbue-kit.ts +384 -0
  1107. package/src/engine/spells/interrupt.ts +217 -0
  1108. package/src/engine/spells/meleeAttackReset.ts +60 -0
  1109. package/src/engine/spells/oocTriggerSpell.ts +49 -0
  1110. package/src/engine/spells/overrideClassScripts.ts +319 -0
  1111. package/src/engine/spells/parryHaste.ts +20 -0
  1112. package/src/engine/spells/procs.ts +300 -0
  1113. package/src/engine/spells/recovery.ts +203 -0
  1114. package/src/engine/spells/scriptTargetDest.ts +76 -0
  1115. package/src/engine/spells/scriptTargets.ts +85 -0
  1116. package/src/engine/spells/singleTargetAura.ts +82 -0
  1117. package/src/engine/spells/specialCasePayloads.ts +57 -0
  1118. package/src/engine/spells/spellAttributes.ts +249 -0
  1119. package/src/engine/spells/spellBonus.ts +143 -0
  1120. package/src/engine/spells/spellModIntents.ts +419 -0
  1121. package/src/engine/spells/spellMods.ts +283 -0
  1122. package/src/engine/spells/spellRadius.ts +15 -0
  1123. package/src/engine/spells/trapObjects.ts +26 -0
  1124. package/src/json.d.ts +7 -0
  1125. package/src/persistence/memoryRepository.ts +23 -0
  1126. package/src/persistence/saveBackups.ts +162 -0
  1127. package/src/persistence/saveFile.ts +68 -0
  1128. package/src/persistence/saveRepository.ts +11 -0
  1129. package/src/persistence/saveShape.ts +668 -0
  1130. package/src/progression/leveling.ts +89 -0
  1131. package/src/progression/rest.ts +1434 -0
  1132. package/src/progression/training.ts +226 -0
  1133. package/src/progression/xpGain.ts +369 -0
  1134. package/src/quests/quests.ts +1580 -0
  1135. package/src/world/aoePull.ts +198 -0
  1136. package/src/world/areaTableDbc.ts +39 -0
  1137. package/src/world/areaTableMapIdPairs.ts +141 -0
  1138. package/src/world/bakeSlug.ts +43 -0
  1139. package/src/world/continuousDungeon.ts +1250 -0
  1140. package/src/world/dungeonBakeProjection.ts +190 -0
  1141. package/src/world/dungeonMapDensity.ts +342 -0
  1142. package/src/world/dungeonMapProjection.ts +135 -0
  1143. package/src/world/dungeonNav.ts +904 -0
  1144. package/src/world/dungeonNpcSim.ts +147 -0
  1145. package/src/world/dungeonObjectives.ts +234 -0
  1146. package/src/world/dungeonPreset.ts +35 -0
  1147. package/src/world/dungeonRoute.ts +311 -0
  1148. package/src/world/dungeonRouteGeometry.ts +732 -0
  1149. package/src/world/dungeonRouteOrder.ts +1037 -0
  1150. package/src/world/dungeonWingRooms.ts +426 -0
  1151. package/src/world/escort.ts +296 -0
  1152. package/src/world/goPoolRoll.ts +75 -0
  1153. package/src/world/instanceObjects.ts +785 -0
  1154. package/src/world/instances.ts +1572 -0
  1155. package/src/world/meetingStones.ts +56 -0
  1156. package/src/world/navmeshFloors.ts +145 -0
  1157. package/src/world/nearGrid.ts +167 -0
  1158. package/src/world/packBudget.ts +613 -0
  1159. package/src/world/rareRoll.ts +335 -0
  1160. package/src/world/routeAuthoring.ts +132 -0
  1161. package/src/world/routeEdit.ts +209 -0
  1162. package/src/world/world.ts +812 -0
  1163. package/src/world/zoneHazards.ts +47 -0
@@ -0,0 +1,1060 @@
1
+ // Auction-house market maker, a CMaNGOS AHBot fidelity port (AuctionHouseBot.cpp; ahbot.conf).
2
+ // Pure and deterministic: prices from item data, randomness from an injected Rng, `now` passed in.
3
+
4
+ import type { Rng } from '../../engine/core/rng.ts';
5
+ import type { ItemDef, CompactLoot, LootTuple, LootEntryDef, RandomPropertyDef } from '../../data/schema.ts';
6
+ import type { Auction, AuctionHouseState } from './auction.ts';
7
+ import { minNextBid, auctionCut } from './auction.ts';
8
+ import { rollLootDeep } from '../items/loot.ts';
9
+ import { createItemInstance, type CreateItemData, type CreateItemOpts } from '../items/createItem.ts';
10
+ import { hasIdentity, identityCapable } from '../items/itemInstance.ts';
11
+ import { randomPropPowerPoints } from '../items/itemRandomProps.ts';
12
+ import ahItemValuesJson from '../../data/tables/ahItemValues.json' with { type: 'json' };
13
+
14
+ // ---- sourced constants (ahbot.conf.dist.in / AuctionHouseBot.cpp) -----------
15
+
16
+ /** ITEM_QUALITY_* — matrix row index. */
17
+ export const ITEM_QUALITY_POOR = 0;
18
+ export const ITEM_QUALITY_NORMAL = 1;
19
+ export const ITEM_QUALITY_UNCOMMON = 2;
20
+ export const ITEM_QUALITY_RARE = 3;
21
+ export const ITEM_QUALITY_EPIC = 4;
22
+ export const ITEM_QUALITY_LEGENDARY = 5;
23
+ export const ITEM_QUALITY_ARTIFACT = 6;
24
+
25
+ // item_template.class (ItemPrototype.h ITEM_CLASS_*). Full bake stamps itemClass on every item;
26
+ // inferItemClass remains for fixtures and any row that still lacks the field.
27
+ export const ITEM_CLASS_WEAPON = 2;
28
+ export const ITEM_CLASS_ARMOR = 4;
29
+ /** Default inferred class for non-weapon/armor tradeables (Trade Goods). */
30
+ export const ITEM_CLASS_TRADE_GOODS = 7;
31
+
32
+ /** BIND_WHEN_PICKED_UP / BIND_QUEST_ITEM — sell-side exclusions. */
33
+ const BIND_WHEN_PICKED_UP = 1;
34
+ const BIND_QUEST_ITEM = 4;
35
+
36
+ // Quality×class PERCENT matrix from ahbot.conf.dist.in (rows quality 0–6, cols class 0–16), used
37
+ // after the BuyPrice or SellPrice×4/5 anchor. Poor, Legendary and Artifact are 0 — never traded.
38
+ export const QUALITY_CLASS_PERCENT: readonly (readonly number[])[] = [
39
+ // Poor
40
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
41
+ // Normal
42
+ [100, 100, 0, 100, 0, 100, 100, 100, 0, 100, 0, 100, 100, 100, 0, 100, 100],
43
+ // Uncommon
44
+ [200, 200, 200, 200, 200, 200, 200, 200, 0, 200, 0, 200, 200, 200, 0, 200, 200],
45
+ // Rare
46
+ [400, 400, 400, 400, 400, 400, 400, 400, 0, 400, 0, 400, 400, 400, 0, 400, 400],
47
+ // Epic
48
+ [800, 800, 800, 800, 800, 800, 800, 800, 0, 800, 0, 800, 800, 800, 0, 800, 800],
49
+ // Legendary
50
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
51
+ // Artifact
52
+ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
53
+ ] as const;
54
+
55
+ /** AuctionHouseBot.Value.Variance default (conf:168). */
56
+ export const DEFAULT_VALUE_VARIANCE = 10;
57
+ /** AuctionHouseBot.Bid.Min / Max (conf:176–177). */
58
+ export const BID_MIN_PCT = 75;
59
+ export const BID_MAX_PCT = 90;
60
+ /** AuctionHouseBot.Time.Min / Max hours (conf:185–186). */
61
+ export const AUCTION_TIME_MIN_H = 2;
62
+ export const AUCTION_TIME_MAX_H = 24;
63
+ /** AuctionHouseBot.Chance.Buy default 10 → 0.10 action gate. */
64
+ export const DEFAULT_BUY_CHANCE = 0.10;
65
+ /** AuctionHouseBot.Level.MaxRequired static cap (conf:110). */
66
+ export const MAX_REQUIRED_LEVEL = 60;
67
+
68
+ const HOUR_MS = 60 * 60 * 1000;
69
+ const DEFAULT_SELLER = 'Auctioneer-Bot';
70
+
71
+ // ---- class for quality×class matrix -----------------------------------------
72
+
73
+ // item_template.class for the AHBot matrix: explicit itemClass, else weapon 2, armor 4, else
74
+ // Trade Goods 7 — chosen over Misc 15 so the fallback stays a tradeable at 100%.
75
+ export function inferItemClass(it: ItemDef): number {
76
+ if (it.itemClass != null) return it.itemClass;
77
+ if (it.weapon != null || it.weaponSubclass != null) return ITEM_CLASS_WEAPON;
78
+ if (it.armor != null || it.armorSubclass != null) return ITEM_CLASS_ARMOR;
79
+ if (it.slot && it.slot !== 'bag') {
80
+ if (it.slot === 'mainhand' || it.slot === 'twohand' || it.slot === 'ranged') {
81
+ return ITEM_CLASS_WEAPON;
82
+ }
83
+ // offhand can be shield (armor) or weapon; without weapon fields treat as armor
84
+ return ITEM_CLASS_ARMOR;
85
+ }
86
+ return ITEM_CLASS_TRADE_GOODS;
87
+ }
88
+
89
+ /** Prefer baked `bonding`, fall back to legacy `binding`. */
90
+ export function itemBonding(it: ItemDef): number {
91
+ return it.bonding ?? it.binding ?? 0;
92
+ }
93
+
94
+ export function qualityClassPercent(quality: number, itemClass: number): number {
95
+ const row = QUALITY_CLASS_PERCENT[quality];
96
+ if (!row) return 0;
97
+ if (itemClass < 0 || itemClass >= row.length) return 0;
98
+ return row[itemClass]!;
99
+ }
100
+
101
+ // ---- pricing (CalculateBuyoutPrice + ValueWithVariance) ---------------------
102
+
103
+ /** Player.cpp:17516 — BuyCount is the vendor bundle size BuyPrice pays for. */
104
+ export function itemBuyCount(it: Pick<ItemDef, 'buyCount'>): number {
105
+ return Math.max(1, it.buyCount ?? 1);
106
+ }
107
+
108
+ // Vendor copper for `quantity` units. BuyPrice is a BuyCount bundle, not a unit. Cite: Player.cpp:17516
109
+ // `totalCount = BuyCount * count`; :17551 `price = BuyPrice * count`.
110
+ export function vendorBundleCopper(it: Pick<ItemDef, 'buyPrice' | 'buyCount'>, quantity: number): number {
111
+ const buy = it.buyPrice | 0;
112
+ const qty = quantity | 0;
113
+ if (buy <= 0 || qty < 1) return 0;
114
+ return Math.floor((buy * qty) / itemBuyCount(it));
115
+ }
116
+
117
+ export const LIST_VENDOR_CAP_REASON = 'Vendors sell this for less';
118
+
119
+ // CalculateBuyoutPrice for `quantity` units. BuyPrice is a BuyCount BUNDLE, so unpack it first:
120
+ // treating it as a unit priced Solid Shot x200 at 6g when the vendor pack is 3s. Cite: cpp:613.
121
+ export function stackBuyoutPrice(
122
+ it: ItemDef,
123
+ quantity: number,
124
+ vendorItems?: ReadonlySet<number>,
125
+ ): number {
126
+ const qty = Math.max(1, quantity | 0);
127
+ const buyCount = itemBuyCount(it);
128
+ const buy = it.buyPrice | 0;
129
+ const sell = it.sellPrice | 0;
130
+ const unitBuy = buyCount > 1 ? Math.floor(buy / buyCount) : buy;
131
+ // buy==0 → SellPrice fallback. Do not treat floor(pack/BuyCount)==0 as "no buy
132
+ // price" (Rough Arrow 10c/200). Ratio uses per-unit buy, not the pack.
133
+ const useSellFallback = buy === 0 || (sell > 0 && Math.floor(unitBuy / sell) > 5);
134
+ const unit = useSellFallback
135
+ ? sell * (it.quality <= ITEM_QUALITY_NORMAL ? 4 : 5)
136
+ : unitBuy;
137
+ const pct = vendorItems?.has(it.entry)
138
+ ? 100
139
+ : qualityClassPercent(it.quality, inferItemClass(it));
140
+ if (!useSellFallback && buyCount > 1 && buy > 0) {
141
+ // Keep pack totals: Solid Shot 300c for 200, not floor(300/200)*200 = 200.
142
+ return Math.floor((buy * qty * pct) / (buyCount * 100));
143
+ }
144
+ return Math.floor((unit * qty * pct) / 100);
145
+ }
146
+
147
+ /** Unit copper — stack of 1. Cite: AuctionHouseBot.cpp:613. */
148
+ export function calculateBuyoutPrice(it: ItemDef, vendorItems?: ReadonlySet<number>): number {
149
+ return stackBuyoutPrice(it, 1, vendorItems);
150
+ }
151
+
152
+ // AuctionHouseBot.h ValueWithVariance: itemValue + (urand(0, variance*2+1) - variance) *
153
+ // (itemValue / 100). Variance 0 leaves it unchanged; callers passing an rng default to 10.
154
+ export function valueWithVariance(baseValue: number, variance: number, rng: Rng): number {
155
+ if (variance <= 0 || baseValue <= 0) return baseValue;
156
+ // urand inclusive both ends → rng.int(0, variance*2+1)
157
+ const roll = rng.int(0, variance * 2 + 1);
158
+ const delta = roll - variance;
159
+ const stepped = Math.floor(baseValue / 100);
160
+ const out = baseValue + delta * stepped;
161
+ return out < 0 ? 0 : out;
162
+ }
163
+
164
+ // Optional identity for AH unit valuation (Wave Q P5). Prefer `randomProp` when the caller already resolved
165
+ // the def; otherwise `randomPropertyId` + `propLookup`. Id 0 / missing / failed lookup → no premium.
166
+ export interface ItemValueOpts {
167
+ variance?: number;
168
+ rng?: Rng;
169
+ randomPropertyId?: number;
170
+ /** Resolved prop — prefer this when caller already looked up. */
171
+ randomProp?: RandomPropertyDef;
172
+ propLookup?: (id: number) => RandomPropertyDef | undefined;
173
+ /** Infinite-stock npc_vendor (maxcount 0) → matrix 100% + listing cap. */
174
+ vendorItems?: ReadonlySet<number>;
175
+ /** Per-unit craft-cost floor from buildCraftFloor — raises a craft to its reagents. */
176
+ craftFloor?: ReadonlyMap<number, number>;
177
+ /** ahbot_items value overrides; defaults to the shipped table. */
178
+ valueOverrides?: ReadonlyMap<number, number>;
179
+ }
180
+
181
+ // Resolve a RandomPropertyDef for valuation without requiring a DataStore API. Prefer explicit
182
+ // `randomProp`; else lookup by id when propLookup is provided.
183
+ function resolveValueProp(opts?: ItemValueOpts): RandomPropertyDef | undefined {
184
+ if (opts?.randomProp) return opts.randomProp;
185
+ const id = opts?.randomPropertyId;
186
+ if (id == null || id <= 0) return undefined;
187
+ return opts?.propLookup?.(id);
188
+ }
189
+
190
+ // Phonecraft AH random-prop premium — CMaNGOS prices item_template only. About 2% of template AH
191
+ // unit value per power point. A documented heuristic; vendor sell price stays template-only.
192
+ export function randomPropPremiumCopper(baseBuyout: number, prop: RandomPropertyDef | undefined): number {
193
+ if (!prop) return 0;
194
+ const points = randomPropPowerPoints(prop);
195
+ if (points <= 0) return 0;
196
+ const base = baseBuyout | 0;
197
+ if (base < 0) return 0;
198
+ const copperPerPoint = Math.max(1, Math.floor(base * 0.02));
199
+ return points * copperPerPoint;
200
+ }
201
+
202
+ // characters.ahbot_items value override (cpp:138-155). Replaces CalculateBuyoutPrice outright
203
+ // (cpp:242, :275); 0 blacklists the item both ways (cpp:229-231, :271-273). Ships empty like upstream.
204
+ export const AH_ITEM_VALUES: ReadonlyMap<number, number> = new Map(
205
+ (ahItemValuesJson.items as Array<{ item: number; value: number }>)
206
+ .filter((r) => (r.item | 0) > 0)
207
+ .map((r) => [r.item | 0, Math.max(0, r.value | 0)]),
208
+ );
209
+
210
+ /** Override copper for one item, or undefined when the table has no row. */
211
+ export function ahItemValueOverride(
212
+ entry: number,
213
+ overrides: ReadonlyMap<number, number> = AH_ITEM_VALUES,
214
+ ): number | undefined {
215
+ return overrides.get(entry | 0);
216
+ }
217
+
218
+ /** A recipe as the craft floor reads it — matches profession-data rows and ds.recipes(). */
219
+ export interface CraftFloorRecipe {
220
+ product: { item: number; count?: number };
221
+ reagents?: ReadonlyArray<{ item: number; count: number }>;
222
+ }
223
+
224
+ /** Chain depth ore -> bar -> arcanite -> rod -> weapon; passes stop early once stable. */
225
+ const CRAFT_FLOOR_PASSES = 8;
226
+
227
+ // Per-unit floor for crafted items: 326 of 1024 recipes listed under their own reagents, Flask of
228
+ // the Titans at 2g against 4.35g of mats. Raises only, like randomPropPremiumCopper above.
229
+ export function buildCraftFloor(
230
+ recipes: Iterable<CraftFloorRecipe>,
231
+ itemOf: (id: number) => ItemDef | undefined,
232
+ vendorItems?: ReadonlySet<number>,
233
+ ): Map<number, number> {
234
+ const rows = [...recipes].filter((r) => (r.reagents?.length ?? 0) > 0 && (r.product?.item | 0) > 0);
235
+ const floor = new Map<number, number>();
236
+ if (rows.length === 0) return floor;
237
+ // Template unit value, already clamped for infinite-stock vendor rows so a vendor mat cannot
238
+ // push a craft above what the vendor charges for the same goods.
239
+ const unitOf = (id: number): number | null => {
240
+ const it = itemOf(id);
241
+ if (!it) return null;
242
+ const ov = ahItemValueOverride(id);
243
+ if (ov != null) return ov;
244
+ const v = stackBuyoutPrice(it, 1, vendorItems);
245
+ const cap = vendorItems?.has(id) ? vendorBundleCopper(it, 1) : 0;
246
+ return cap > 0 && v > cap ? cap : v;
247
+ };
248
+ const valueOf = (id: number): number | null => floor.get(id) ?? unitOf(id);
249
+ for (let pass = 0; pass < CRAFT_FLOOR_PASSES; pass++) {
250
+ let changed = false;
251
+ for (const r of rows) {
252
+ const product = r.product.item | 0;
253
+ // A vendor-stocked craft stays at the vendor price (conf:150-159 Value.Vendor).
254
+ if (vendorItems?.has(product)) continue;
255
+ let mats = 0;
256
+ let known = true;
257
+ for (const rg of r.reagents!) {
258
+ const v = valueOf(rg.item | 0);
259
+ if (v == null) { known = false; break; }
260
+ mats += v * Math.max(1, rg.count | 0);
261
+ }
262
+ if (!known || mats <= 0) continue;
263
+ const per = Math.floor(mats / Math.max(1, r.product.count | 0 || 1));
264
+ if (per > (valueOf(product) ?? 0)) {
265
+ floor.set(product, per);
266
+ changed = true;
267
+ }
268
+ }
269
+ if (!changed) break;
270
+ }
271
+ return floor;
272
+ }
273
+
274
+ // AH copper for `quantity` units, with variance applied only at the final listing step and a
275
+ // deterministic prop premium before it. Infinite-stock vendor items clamp to the bundle price.
276
+ export function itemStackValue(
277
+ it: ItemDef,
278
+ quantity: number,
279
+ opts?: ItemValueOpts,
280
+ ): number {
281
+ const qty = Math.max(1, quantity | 0);
282
+ // cpp:242 — an ahbot_items row replaces CalculateBuyoutPrice, so the template and the floor
283
+ // are both skipped. Value 0 means blacklisted and prices to nothing.
284
+ const override = ahItemValueOverride(it.entry, opts?.valueOverrides);
285
+ if (override != null) {
286
+ if (override === 0) return 0;
287
+ const capped = opts?.vendorItems?.has(it.entry) ? vendorBundleCopper(it, qty) : 0;
288
+ const out0 = opts?.rng ? valueWithVariance(override * qty, opts.variance ?? DEFAULT_VALUE_VARIANCE, opts.rng) : override * qty;
289
+ return capped > 0 && out0 > capped ? capped : out0;
290
+ }
291
+ const craftUnit = opts?.craftFloor?.get(it.entry) ?? 0;
292
+ const base = Math.max(stackBuyoutPrice(it, qty, opts?.vendorItems), craftUnit * qty);
293
+ const unit = Math.max(stackBuyoutPrice(it, 1, opts?.vendorItems), craftUnit);
294
+ const prop = resolveValueProp(opts);
295
+ const withPremium = base + randomPropPremiumCopper(unit, prop) * qty;
296
+ let out = withPremium;
297
+ if (opts?.rng) {
298
+ const variance = opts.variance ?? DEFAULT_VALUE_VARIANCE;
299
+ out = valueWithVariance(withPremium, variance, opts.rng);
300
+ }
301
+ const cap = opts?.vendorItems?.has(it.entry) ? vendorBundleCopper(it, qty) : 0;
302
+ if (cap > 0 && out > cap) return cap;
303
+ return out;
304
+ }
305
+
306
+ /** Unit copper — `itemStackValue(it, 1, opts)`. */
307
+ export function itemValue(
308
+ it: ItemDef,
309
+ opts?: ItemValueOpts,
310
+ ): number {
311
+ return itemStackValue(it, 1, opts);
312
+ }
313
+
314
+ // ---- sell-side filters ------------------------------------------------------
315
+
316
+ // Whether AHBot may list this item (cpp:224–240 + value≠0 at list time). Excludes BoP, quest-bound,
317
+ // questItem flag, matrix 0, computed value 0. Does not apply loot-container flag (GAP — flags not baked).
318
+ export function canBotListItem(it: ItemDef, maxRequiredLevel: number = MAX_REQUIRED_LEVEL): boolean {
319
+ if (ahItemValueOverride(it.entry) === 0) return false; // cpp:229-231 blacklist
320
+ const bonding = itemBonding(it);
321
+ if (bonding === BIND_WHEN_PICKED_UP || bonding === BIND_QUEST_ITEM) return false;
322
+ if (it.questItem) return false;
323
+ if ((it.requiredLevel | 0) > maxRequiredLevel) return false;
324
+ if (qualityClassPercent(it.quality, inferItemClass(it)) === 0) return false;
325
+ // Pack value: Rough Arrow unit floors to 0c but the 200-bundle is 10c.
326
+ if (stackBuyoutPrice(it, itemBuyCount(it)) === 0) return false;
327
+ return true;
328
+ }
329
+
330
+ /** ahbot.conf.dist.in 4-tuple: minSources, maxSources, minLootings, maxLootings. */
331
+ export type AhBotLootConfig = readonly [number, number, number, number];
332
+
333
+ /** Cite: ahbot.conf.dist.in:45–54. */
334
+ export const AHBOT_LOOT: {
335
+ creatureNormal: AhBotLootConfig;
336
+ creatureRare: AhBotLootConfig;
337
+ creatureElite: AhBotLootConfig;
338
+ creatureRareElite: AhBotLootConfig;
339
+ creatureWorldBoss: AhBotLootConfig;
340
+ disenchant: AhBotLootConfig;
341
+ fishing: AhBotLootConfig;
342
+ gameobject: AhBotLootConfig;
343
+ skinning: AhBotLootConfig;
344
+ } = {
345
+ creatureNormal: [30, 35, 8, 12],
346
+ creatureRare: [0, 10, 1, 1],
347
+ creatureElite: [30, 34, 1, 2],
348
+ creatureRareElite: [-10, 2, 1, 1],
349
+ creatureWorldBoss: [-20, 1, 1, 1],
350
+ disenchant: [10, 12, 1, 1],
351
+ fishing: [3, 5, 30, 40],
352
+ gameobject: [13, 16, 7, 11],
353
+ skinning: [3, 5, 50, 50],
354
+ };
355
+
356
+ /** Profession 4-tuple: min items, max items, min % stack, max % stack. Cite: conf:70. */
357
+ export const AHBOT_PROFESSION: AhBotLootConfig = [80, 90, 0, 50];
358
+
359
+ /** One house sell+buy cycle. Cite: World.cpp:1363; 6-state round-robin → 120s. */
360
+ export const AHBOT_TICK_MS = 120_000;
361
+ /** Catch-up slices on visit (16 min). More than this hitch the UI on a loot sell pass. */
362
+ export const AHBOT_CATCHUP_MAX = 8;
363
+ /** Empty-house first paint. Cite: AuctionHouseBot.cpp Rebuild, bounded vs ~1170. */
364
+ export const AHBOT_WARM_SELL_PASSES = 3;
365
+ /** Keep selling to this many live lots. Measured: 0 cloth-wrist @ 552, 20 @ 7142. */
366
+ export const AHBOT_STOCK_FLOOR = 10_000;
367
+ /** Sell passes per refill while below the floor. */
368
+ export const AHBOT_FILL_PASSES = 3;
369
+
370
+ // ---- loot-template supply ---------------------------------------------------
371
+
372
+ export type LootTableGet = (id: number | string) => readonly LootTuple[] | readonly LootEntryDef[] | undefined;
373
+ export type LootTablesInput =
374
+ | CompactLoot
375
+ | Map<number | string, readonly LootTuple[] | readonly LootEntryDef[]>
376
+ | LootTableGet;
377
+
378
+ function isLootEntryDef(e: LootTuple | LootEntryDef): e is LootEntryDef {
379
+ return typeof e === 'object' && e !== null && 'item' in e && !Array.isArray(e);
380
+ }
381
+
382
+ function decodeLootTuple(t: LootTuple): LootEntryDef {
383
+ const ent: LootEntryDef = {
384
+ item: t[0],
385
+ chance: t[1],
386
+ groupId: t[2],
387
+ minCount: t.length >= 5 ? t[3]! : 1,
388
+ maxCount: t.length >= 5 ? t[4]! : 1,
389
+ };
390
+ if (t.length >= 6 && ((t[5] as number) | 0) !== 0) ent.conditionId = (t[5] as number) | 0;
391
+ return ent;
392
+ }
393
+
394
+ function lootMapKey(id: number | string): number | string {
395
+ if (typeof id === 'number') return id;
396
+ if (/^\d+$/.test(id)) return Number(id);
397
+ return id;
398
+ }
399
+
400
+ function decodeRows(rows: readonly (LootTuple | LootEntryDef)[]): LootEntryDef[] {
401
+ return rows.map((r) => (isLootEntryDef(r) ? r : decodeLootTuple(r)));
402
+ }
403
+
404
+ /** Decode only tables that a roll actually touches — never the whole loot store. */
405
+ function asTableGet(lootTables: LootTablesInput): (id: number | string) => LootEntryDef[] | undefined {
406
+ const cache = new Map<number | string, LootEntryDef[]>();
407
+ return (id) => {
408
+ const key = lootMapKey(id);
409
+ const hit = cache.get(key);
410
+ if (hit) return hit.length ? hit : undefined;
411
+ let rows: readonly (LootTuple | LootEntryDef)[] | undefined;
412
+ if (typeof lootTables === 'function') {
413
+ rows = lootTables(id);
414
+ if ((!rows || rows.length === 0) && id !== key) rows = lootTables(key);
415
+ } else if (lootTables instanceof Map) {
416
+ rows = lootTables.get(key) ?? lootTables.get(id);
417
+ } else {
418
+ const obj = lootTables;
419
+ rows = obj[key as string] ?? obj[String(id)];
420
+ }
421
+ const decoded = rows && rows.length ? decodeRows(rows) : [];
422
+ cache.set(key, decoded);
423
+ return decoded.length ? decoded : undefined;
424
+ };
425
+ }
426
+
427
+ // Simplified AddLootToItemMap (cpp:582–611): pick N template ids and process each
428
+ // urand(minLootings,maxLootings) times. C++: min<0 → urand(0, max-min)+min, else urand(min,max).
429
+ export function rollLootSourceCount(minSources: number, maxSources: number, rng: Rng): number {
430
+ if (maxSources <= 0) return 0;
431
+ if (minSources < 0) return rng.int(0, maxSources - minSources) + minSources;
432
+ return rng.int(minSources, maxSources);
433
+ }
434
+
435
+ export function addLootToItemMap(
436
+ templateIds: readonly (number | string)[],
437
+ tables: LootTablesInput,
438
+ rng: Rng,
439
+ opts: {
440
+ minSources?: number;
441
+ maxSources?: number;
442
+ minLootings?: number;
443
+ maxLootings?: number;
444
+ itemOf?: (itemId: number) => ItemDef | undefined;
445
+ maxRequiredLevel?: number;
446
+ maxItemLevel?: number;
447
+ } = {},
448
+ ): Map<number, number> {
449
+ const itemMap = new Map<number, number>();
450
+ if (templateIds.length === 0) return itemMap;
451
+ const minSources = opts.minSources ?? 1;
452
+ const maxSources = opts.maxSources ?? Math.min(3, templateIds.length);
453
+ const minLootings = opts.minLootings ?? 1;
454
+ const maxLootings = opts.maxLootings ?? 1;
455
+ if (maxLootings <= 0) return itemMap;
456
+ const maxTemplates = rollLootSourceCount(minSources, maxSources, rng);
457
+ if (maxTemplates <= 0) return itemMap;
458
+ const maxReq = opts.maxRequiredLevel ?? MAX_REQUIRED_LEVEL;
459
+ const maxIlvl = opts.maxItemLevel ?? (maxReq >= 60 ? 255 : maxReq + 5);
460
+ const get = asTableGet(tables);
461
+ for (let t = 0; t < maxTemplates; t++) {
462
+ const tid = templateIds[rng.int(0, templateIds.length - 1)]!;
463
+ const entries = get(tid);
464
+ if (!entries || entries.length === 0) continue;
465
+ const repeats = rng.int(Math.min(minLootings, maxLootings), Math.max(minLootings, maxLootings));
466
+ for (let r = 0; r < repeats; r++) {
467
+ for (const drop of rollLootDeep(entries, (refId) => get(refId), rng)) {
468
+ if (opts.itemOf) {
469
+ const it = opts.itemOf(drop.item);
470
+ if (it && ((it.requiredLevel | 0) > maxReq || (it.itemLevel ?? 0) > maxIlvl)) continue;
471
+ }
472
+ itemMap.set(drop.item, (itemMap.get(drop.item) ?? 0) + drop.count);
473
+ }
474
+ }
475
+ }
476
+ return itemMap;
477
+ }
478
+
479
+ // ---- market making (sell) ---------------------------------------------------
480
+
481
+ export interface SeedOptions {
482
+ count: number;
483
+ startId: number;
484
+ nowMs: number;
485
+ /** Fixed duration; when omitted, urand(2,24) hours (AHBot Time.Min/Max). */
486
+ durationMs?: number;
487
+ seller?: string;
488
+ /** ValueWithVariance percent band; default 10. Pass 0 for exact prices. */
489
+ variance?: number;
490
+ maxRequiredLevel?: number;
491
+ /** When set with itemLookup, supply is loot-template drawn (not uniform pool). */
492
+ lootTables?: LootTablesInput;
493
+ itemLookup?: (itemId: number) => ItemDef | undefined;
494
+ /** Template ids to sample; default = keys of lootTables. */
495
+ templateIds?: number[];
496
+ minSources?: number;
497
+ maxSources?: number;
498
+ minLootings?: number;
499
+ maxLootings?: number;
500
+ // Wave Q P2/P5: when set, each listing of an identity-capable / randomProperty item mints `instance` with
501
+ // a rolled `randomPropertyId` and prices via itemValue + prop premium.
502
+ createDs?: CreateItemData;
503
+ lookupProp?: CreateItemOpts['lookupProp'];
504
+ }
505
+
506
+ function listingDurationMs(rng: Rng, durationMs?: number): number {
507
+ if (durationMs != null) return durationMs;
508
+ return rng.int(AUCTION_TIME_MIN_H, AUCTION_TIME_MAX_H) * HOUR_MS;
509
+ }
510
+
511
+ function priceListing(
512
+ it: ItemDef,
513
+ quantity: number,
514
+ rng: Rng,
515
+ variance: number,
516
+ valueOpts?: Pick<ItemValueOpts, 'randomPropertyId' | 'randomProp' | 'propLookup' | 'vendorItems' | 'craftFloor'>,
517
+ ): { buyoutCopper: number; bidCopper: number } | null {
518
+ const buyoutCopper = itemStackValue(it, quantity, { variance, rng, ...valueOpts });
519
+ if (buyoutCopper <= 0) return null;
520
+ const bidPct = rng.int(BID_MIN_PCT, BID_MAX_PCT);
521
+ const bidCopper = Math.max(1, Math.floor((buyoutCopper * bidPct) / 100));
522
+ return { buyoutCopper, bidCopper };
523
+ }
524
+
525
+ function pushListing(
526
+ out: Auction[],
527
+ it: ItemDef,
528
+ quantity: number,
529
+ rng: Rng,
530
+ opts: {
531
+ startId: number;
532
+ nowMs: number;
533
+ durationMs?: number;
534
+ seller: string;
535
+ variance: number;
536
+ createDs?: CreateItemData;
537
+ lookupProp?: CreateItemOpts['lookupProp'];
538
+ vendorItems?: ReadonlySet<number>;
539
+ craftFloor?: ReadonlyMap<number, number>;
540
+ pickSeller?: () => string;
541
+ },
542
+ ): void {
543
+ // Wave Q P2: mint instance first so Q P5 can price the rolled randomPropertyId.
544
+ let instance: Auction['instance'];
545
+ if (opts.createDs && (identityCapable(it) || (it.randomProperty != null && it.randomProperty > 0))) {
546
+ const inst = createItemInstance(it.entry, quantity, opts.createDs, rng, {
547
+ lookupProp: opts.lookupProp,
548
+ });
549
+ if (hasIdentity(inst) || identityCapable(it)) instance = inst;
550
+ }
551
+ const priced = priceListing(it, quantity, rng, opts.variance, {
552
+ randomPropertyId: instance?.randomPropertyId,
553
+ propLookup: opts.lookupProp,
554
+ vendorItems: opts.vendorItems,
555
+ craftFloor: opts.craftFloor,
556
+ });
557
+ if (!priced) return;
558
+ const duration = listingDurationMs(rng, opts.durationMs);
559
+ out.push({
560
+ id: opts.startId + out.length,
561
+ item: it.entry,
562
+ quantity,
563
+ bidCopper: priced.bidCopper,
564
+ highBidder: null,
565
+ buyoutCopper: priced.buyoutCopper,
566
+ seller: opts.pickSeller ? opts.pickSeller() : opts.seller,
567
+ bot: true,
568
+ expiresAt: opts.nowMs + duration,
569
+ ...(instance ? { instance } : {}),
570
+ });
571
+ }
572
+
573
+ // Generate auctions from a pool of listable items: CalculateBuyoutPrice × ValueWithVariance,
574
+ // opening bid 75–90% of buyout, duration 2–24h. With lootTables, supply is drawn from loot.
575
+ export function seedAuctions(pool: ItemDef[], rng: Rng, opts: SeedOptions): Auction[] {
576
+ if (opts.count <= 0) return [];
577
+ const variance = opts.variance ?? DEFAULT_VALUE_VARIANCE;
578
+ const seller = opts.seller ?? DEFAULT_SELLER;
579
+ const maxReq = opts.maxRequiredLevel ?? MAX_REQUIRED_LEVEL;
580
+ const listOpts = {
581
+ startId: opts.startId,
582
+ nowMs: opts.nowMs,
583
+ durationMs: opts.durationMs,
584
+ seller,
585
+ variance,
586
+ createDs: opts.createDs,
587
+ lookupProp: opts.lookupProp,
588
+ };
589
+
590
+ if (opts.lootTables && opts.itemLookup) {
591
+ return seedAuctionsFromLoot(opts.lootTables, opts.itemLookup, rng, opts);
592
+ }
593
+
594
+ const sellable = pool.filter((it) => canBotListItem(it, maxReq));
595
+ if (sellable.length === 0) return [];
596
+ const out: Auction[] = [];
597
+ for (let i = 0; i < opts.count && out.length < opts.count; i++) {
598
+ const it = sellable[rng.int(0, sellable.length - 1)]!;
599
+ const quantity = it.stackable > 1 ? rng.int(1, Math.min(5, it.stackable)) : 1;
600
+ pushListing(out, it, quantity, rng, listOpts);
601
+ }
602
+ return out;
603
+ }
604
+
605
+ // AHBot sell-side supply: roll loot templates into an item multiset, then list filtered items
606
+ // (BoP/quest/matrix-0 excluded). Stacks split by max stack size.
607
+ export function seedAuctionsFromLoot(
608
+ lootTables: LootTablesInput,
609
+ itemOf: (itemId: number) => ItemDef | undefined,
610
+ rng: Rng,
611
+ opts: SeedOptions,
612
+ ): Auction[] {
613
+ if (opts.count <= 0) return [];
614
+ const templateIds = opts.templateIds ?? (
615
+ typeof lootTables === 'function' ? []
616
+ : lootTables instanceof Map ? [...lootTables.keys()]
617
+ : Object.keys(lootTables)
618
+ );
619
+ if (templateIds.length === 0) return [];
620
+
621
+ const variance = opts.variance ?? DEFAULT_VALUE_VARIANCE;
622
+ const seller = opts.seller ?? DEFAULT_SELLER;
623
+ const maxReq = opts.maxRequiredLevel ?? MAX_REQUIRED_LEVEL;
624
+ const listOpts = {
625
+ startId: opts.startId,
626
+ nowMs: opts.nowMs,
627
+ durationMs: opts.durationMs,
628
+ seller,
629
+ variance,
630
+ createDs: opts.createDs,
631
+ lookupProp: opts.lookupProp,
632
+ };
633
+
634
+ // Enough loot runs to fill `count` listings (may overshoot map, then take first N stacks).
635
+ const itemMap = addLootToItemMap(templateIds, lootTables, rng, {
636
+ minSources: opts.minSources ?? Math.min(1, templateIds.length),
637
+ maxSources: opts.maxSources ?? Math.min(templateIds.length, Math.max(1, opts.count)),
638
+ minLootings: opts.minLootings ?? 1,
639
+ maxLootings: opts.maxLootings ?? Math.max(1, opts.count),
640
+ });
641
+
642
+ const out: Auction[] = [];
643
+ for (const [itemId, totalCount] of itemMap) {
644
+ if (out.length >= opts.count) break;
645
+ const it = itemOf(itemId);
646
+ if (!it || !canBotListItem(it, maxReq)) continue;
647
+ const maxStack = Math.max(1, it.stackable | 0);
648
+ for (let stacked = 0; stacked < totalCount && out.length < opts.count; stacked += maxStack) {
649
+ const quantity = Math.min(maxStack, totalCount - stacked);
650
+ pushListing(out, it, quantity, rng, listOpts);
651
+ }
652
+ }
653
+ return out;
654
+ }
655
+
656
+ // Top the AH up to `target` live listings. Ids minted from `nextId`. Optional lootTables/itemLookup switch
657
+ // supply to loot-derived path.
658
+ export function refillAuctionHouse(
659
+ ah: AuctionHouseState,
660
+ pool: ItemDef[],
661
+ rng: Rng,
662
+ opts: {
663
+ target: number;
664
+ nowMs: number;
665
+ durationMs?: number;
666
+ seller?: string;
667
+ variance?: number;
668
+ maxRequiredLevel?: number;
669
+ lootTables?: LootTablesInput;
670
+ itemLookup?: (itemId: number) => ItemDef | undefined;
671
+ templateIds?: number[];
672
+ minSources?: number;
673
+ maxSources?: number;
674
+ minLootings?: number;
675
+ maxLootings?: number;
676
+ createDs?: CreateItemData;
677
+ lookupProp?: CreateItemOpts['lookupProp'];
678
+ },
679
+ ): { ah: AuctionHouseState; added: Auction[] } {
680
+ const need = Math.max(0, opts.target - ah.auctions.length);
681
+ const added = seedAuctions(pool, rng, {
682
+ count: need,
683
+ startId: ah.nextId,
684
+ nowMs: opts.nowMs,
685
+ durationMs: opts.durationMs,
686
+ seller: opts.seller,
687
+ variance: opts.variance,
688
+ maxRequiredLevel: opts.maxRequiredLevel,
689
+ lootTables: opts.lootTables,
690
+ itemLookup: opts.itemLookup,
691
+ templateIds: opts.templateIds,
692
+ minSources: opts.minSources,
693
+ maxSources: opts.maxSources,
694
+ minLootings: opts.minLootings,
695
+ maxLootings: opts.maxLootings,
696
+ createDs: opts.createDs,
697
+ lookupProp: opts.lookupProp,
698
+ });
699
+ return {
700
+ ah: { ...ah, auctions: [...ah.auctions, ...added], nextId: ah.nextId + added.length },
701
+ added,
702
+ };
703
+ }
704
+
705
+ // ---- buy side ---------------------------------------------------------------
706
+
707
+ // Standalone deal finder (unwired): flags listings whose stack value strictly exceeds buyout, the
708
+ // CMaNGOS buyout condition. Prefer botMarketPass for live trading — variance, chance, escrow.
709
+ export function botBuyPolicy(
710
+ ah: AuctionHouseState,
711
+ valueOf: (item: number, quantity?: number) => number,
712
+ /** @deprecated Unused — CMaNGOS does not use a 0.9 deal threshold; kept for call-site compat. */
713
+ _dealThreshold = 0.9,
714
+ ): number[] {
715
+ return ah.auctions
716
+ .filter((a) => a.buyoutCopper > 0 && valueOf(a.item, a.quantity) > a.buyoutCopper)
717
+ .map((a) => a.id);
718
+ }
719
+
720
+ export interface MarketEvent {
721
+ kind: 'sold' | 'outbid';
722
+ item: number;
723
+ quantity: number;
724
+ amount: number;
725
+ }
726
+
727
+ export interface MarketPassResult {
728
+ ah: AuctionHouseState;
729
+ playerProceeds: number;
730
+ playerRefund: number;
731
+ events: MarketEvent[];
732
+ }
733
+
734
+ export interface MarketPassOptions {
735
+ /** Stack copper for (item, quantity). Variance applied inside. */
736
+ valueOf: (item: number, quantity?: number) => number;
737
+ player: string;
738
+ nowMs: number;
739
+ // Chance to *run* this pass. Default **0.10** (AuctionHouseBot.Chance.Buy = 10). Applied once per call —
740
+ // then every live auction is scanned (cpp:255–287). Callers that already gated Chance.Buy should pass 1.
741
+ buyChance?: number;
742
+ // Optional extra gate on bid-only path. When omitted, any auction that passes buyChance and fails buyout
743
+ // but meets bid threshold is bid (CMaNGOS style).
744
+ bidChance?: number;
745
+ botName?: string;
746
+ /** ValueWithVariance percent; default 10. Pass 0 for exact willingness. */
747
+ variance?: number;
748
+ }
749
+
750
+ // One round of bot demand (buy pass, cpp:255–287): skip the bot's own unbid listings, buy out when
751
+ // willingness beats buyout, else bid the minimum legal. Pays the player buyout minus the cut.
752
+ export function botMarketPass(ah: AuctionHouseState, rng: Rng, opts: MarketPassOptions): MarketPassResult {
753
+ const { valueOf, player, nowMs } = opts;
754
+ const buyChance = opts.buyChance ?? DEFAULT_BUY_CHANCE;
755
+ const botName = opts.botName ?? DEFAULT_SELLER;
756
+ const variance = opts.variance ?? DEFAULT_VALUE_VARIANCE;
757
+ const events: MarketEvent[] = [];
758
+ let playerProceeds = 0;
759
+ let playerRefund = 0;
760
+ // cpp:255 — Chance.Buy once per house pass, then scan every lot.
761
+ if (buyChance < 1 && rng.next() >= buyChance) {
762
+ return { ah, playerProceeds: 0, playerRefund: 0, events };
763
+ }
764
+ const remaining: Auction[] = [];
765
+
766
+ for (const a of ah.auctions) {
767
+ if (a.expiresAt <= nowMs) {
768
+ remaining.push(a);
769
+ continue;
770
+ }
771
+ // cpp:263 — ignore AHBot listings (owner==0 / a.bot) with no player bid yet
772
+ if ((a.bot || a.seller === botName) && a.highBidder == null) {
773
+ remaining.push(a);
774
+ continue;
775
+ }
776
+
777
+ const fair = valueOf(a.item, a.quantity);
778
+ const willingness = valueWithVariance(fair, variance, rng);
779
+
780
+ // Buyout when value > buyout (cpp:280)
781
+ if (a.buyoutCopper > 0 && willingness > a.buyoutCopper) {
782
+ if (a.seller === player) {
783
+ const proceeds = a.buyoutCopper - auctionCut(a.buyoutCopper);
784
+ playerProceeds += proceeds;
785
+ events.push({ kind: 'sold', item: a.item, quantity: a.quantity, amount: proceeds });
786
+ }
787
+ if (a.highBidder === player) {
788
+ playerRefund += a.bidCopper;
789
+ events.push({ kind: 'outbid', item: a.item, quantity: a.quantity, amount: a.bidCopper });
790
+ }
791
+ continue; // removed
792
+ }
793
+
794
+ // Else minimum-increment bid when value > next bid (cpp:277–283)
795
+ const next = minNextBid(a);
796
+ if (a.highBidder !== botName && willingness > next) {
797
+ if (opts.bidChance !== undefined && rng.next() >= opts.bidChance) {
798
+ remaining.push(a);
799
+ continue;
800
+ }
801
+ if (a.highBidder === player) {
802
+ playerRefund += a.bidCopper;
803
+ events.push({ kind: 'outbid', item: a.item, quantity: a.quantity, amount: a.bidCopper });
804
+ }
805
+ remaining.push({ ...a, bidCopper: next, highBidder: botName });
806
+ continue;
807
+ }
808
+ remaining.push(a);
809
+ }
810
+
811
+ return { ah: { ...ah, auctions: remaining }, playerProceeds, playerRefund, events };
812
+ }
813
+
814
+ /** Ike3-style named sellers. Empty pool → Auctioneer-Bot. */
815
+ export function pickBotSeller(rng: Rng, names?: { male?: readonly string[]; female?: readonly string[] }): string {
816
+ const pool = [...(names?.male ?? []), ...(names?.female ?? [])].filter((n) => n.length > 0);
817
+ if (pool.length === 0) return DEFAULT_SELLER;
818
+ return pool[rng.int(0, pool.length - 1)]!;
819
+ }
820
+
821
+ export interface AhBotSources {
822
+ creatureNormal: Array<number | string>;
823
+ creatureRare: Array<number | string>;
824
+ creatureElite: Array<number | string>;
825
+ creatureRareElite: Array<number | string>;
826
+ creatureWorldBoss: Array<number | string>;
827
+ disenchant: Array<number | string>;
828
+ fishing: Array<number | string>;
829
+ gameobject: Array<number | string>;
830
+ skinning: Array<number | string>;
831
+ professionItems: number[];
832
+ vendorItems: Set<number>;
833
+ /** npc_vendor maxcount 0 on at least one vendor — buy infinitely. */
834
+ infiniteVendorItems: Set<number>;
835
+ /** Per-unit craft-cost floor; empty when the caller passed no itemOf. */
836
+ craftFloor: Map<number, number>;
837
+ }
838
+
839
+ const RANK_NORMAL = 0;
840
+ const RANK_ELITE = 1;
841
+ const RANK_RAREELITE = 2;
842
+ const RANK_WORLDBOSS = 3;
843
+ const RANK_RARE = 4;
844
+
845
+ function prefixIds(lootIds: Iterable<number | string>, prefix: string): Array<number | string> {
846
+ const out: Array<number | string> = [];
847
+ for (const id of lootIds) {
848
+ if (typeof id === 'string' && id.startsWith(prefix)) out.push(id);
849
+ }
850
+ return out;
851
+ }
852
+
853
+ // Build AHBot template lists from bake data. Creature buckets use lootId grouped by scaling.rank
854
+ // (CREATURE_ELITE_*). Namespaced loot keys match loot-chunk-port prefixes.
855
+ export function collectAhBotSources(input: {
856
+ creatures: Iterable<{ lootId?: number; scaling?: { rank?: number } }>;
857
+ lootHas: (id: number | string) => boolean;
858
+ lootIds: Iterable<number | string>;
859
+ recipes: Iterable<CraftFloorRecipe>;
860
+ vendors: Iterable<{ items: number[]; stock?: Array<{ item: number }> }>;
861
+ /** Supplied → craft-cost floor is built; omitted (fixtures) → empty floor. */
862
+ itemOf?: (id: number) => ItemDef | undefined;
863
+ }): AhBotSources {
864
+ const creatureNormal: Array<number | string> = [];
865
+ const creatureRare: Array<number | string> = [];
866
+ const creatureElite: Array<number | string> = [];
867
+ const creatureRareElite: Array<number | string> = [];
868
+ const creatureWorldBoss: Array<number | string> = [];
869
+ const seen = new Set<string>();
870
+ const pushUnique = (bucket: Array<number | string>, id: number) => {
871
+ const k = String(id);
872
+ if (seen.has(k) || id <= 0 || !input.lootHas(id)) return;
873
+ seen.add(k);
874
+ bucket.push(id);
875
+ };
876
+ for (const c of input.creatures) {
877
+ const lootId = (c.lootId ?? 0) | 0;
878
+ const rank = (c.scaling?.rank ?? 0) | 0;
879
+ if (rank === RANK_ELITE) pushUnique(creatureElite, lootId);
880
+ else if (rank === RANK_RAREELITE) pushUnique(creatureRareElite, lootId);
881
+ else if (rank === RANK_WORLDBOSS) pushUnique(creatureWorldBoss, lootId);
882
+ else if (rank === RANK_RARE) pushUnique(creatureRare, lootId);
883
+ else if (rank === RANK_NORMAL) pushUnique(creatureNormal, lootId);
884
+ }
885
+ const professionItems: number[] = [];
886
+ const profSeen = new Set<number>();
887
+ for (const r of input.recipes) {
888
+ const item = r.product.item | 0;
889
+ if (item > 0 && !profSeen.has(item)) {
890
+ profSeen.add(item);
891
+ professionItems.push(item);
892
+ }
893
+ }
894
+ const { vendorItems, infiniteVendorItems } = infiniteVendorItemsOf(input.vendors);
895
+ const craftFloor = input.itemOf
896
+ ? buildCraftFloor(input.recipes, input.itemOf, infiniteVendorItems)
897
+ : new Map<number, number>();
898
+ return {
899
+ creatureNormal,
900
+ creatureRare,
901
+ creatureElite,
902
+ creatureRareElite,
903
+ creatureWorldBoss,
904
+ disenchant: prefixIds(input.lootIds, 'disenchant:'),
905
+ fishing: prefixIds(input.lootIds, 'fishing:'),
906
+ gameobject: prefixIds(input.lootIds, 'go:'),
907
+ skinning: prefixIds(input.lootIds, 'skinning:'),
908
+ professionItems,
909
+ vendorItems,
910
+ infiniteVendorItems,
911
+ craftFloor,
912
+ };
913
+ }
914
+
915
+ // Vendor ids plus the infinite-stock subset — npc_vendor maxcount 0, since VendorDef.stock records
916
+ // only limited rows. An item limited on one vendor and unlimited on another is infinite.
917
+ export function infiniteVendorItemsOf(
918
+ vendors: Iterable<{ items: number[]; stock?: Array<{ item: number }> }>,
919
+ ): { vendorItems: Set<number>; infiniteVendorItems: Set<number> } {
920
+ const vendorItems = new Set<number>();
921
+ const infiniteVendorItems = new Set<number>();
922
+ for (const v of vendors) {
923
+ const limited = new Set((v.stock ?? []).map((s) => s.item | 0));
924
+ for (const raw of v.items) {
925
+ const item = raw | 0;
926
+ if (item <= 0) continue;
927
+ vendorItems.add(item);
928
+ if (!limited.has(item)) infiniteVendorItems.add(item);
929
+ }
930
+ }
931
+ return { vendorItems, infiniteVendorItems };
932
+ }
933
+
934
+ function mergeItemMap(into: Map<number, number>, add: Map<number, number>): void {
935
+ for (const [item, count] of add) into.set(item, (into.get(item) ?? 0) + count);
936
+ }
937
+
938
+ function addConfiguredLoot(
939
+ itemMap: Map<number, number>,
940
+ templateIds: readonly (number | string)[],
941
+ tables: LootTablesInput,
942
+ rng: Rng,
943
+ cfg: AhBotLootConfig,
944
+ itemOf: (itemId: number) => ItemDef | undefined,
945
+ maxRequiredLevel: number,
946
+ maxItemLevel: number,
947
+ ): void {
948
+ if (cfg[1] <= 0 || cfg[3] <= 0 || templateIds.length === 0) return;
949
+ mergeItemMap(itemMap, addLootToItemMap(templateIds, tables, rng, {
950
+ minSources: cfg[0],
951
+ maxSources: cfg[1],
952
+ minLootings: cfg[2],
953
+ maxLootings: cfg[3],
954
+ itemOf,
955
+ maxRequiredLevel,
956
+ maxItemLevel,
957
+ }));
958
+ }
959
+
960
+ export interface AhBotSellOpts {
961
+ nowMs: number;
962
+ startId: number;
963
+ variance?: number;
964
+ maxRequiredLevel?: number;
965
+ createDs?: CreateItemData;
966
+ lookupProp?: CreateItemOpts['lookupProp'];
967
+ names?: { male?: readonly string[]; female?: readonly string[] };
968
+ /** Fixture/smoke path when loot sources are empty. Not CMaNGOS. Called only then. */
969
+ catalog?: ItemDef[] | (() => ItemDef[]);
970
+ }
971
+
972
+ // One AHBot sell pass (AuctionHouseBot.cpp:179–254): loot sources + profession crafts, then list every
973
+ // resulting stack. No listing cap.
974
+ export function ahBotSellPass(
975
+ sources: AhBotSources,
976
+ lootTables: LootTablesInput,
977
+ itemOf: (itemId: number) => ItemDef | undefined,
978
+ rng: Rng,
979
+ opts: AhBotSellOpts,
980
+ ): Auction[] {
981
+ const maxReq = opts.maxRequiredLevel ?? MAX_REQUIRED_LEVEL;
982
+ const maxIlvl = maxReq >= 60 ? 255 : maxReq + 5;
983
+ const itemMap = new Map<number, number>();
984
+ addConfiguredLoot(itemMap, sources.creatureNormal, lootTables, rng, AHBOT_LOOT.creatureNormal, itemOf, maxReq, maxIlvl);
985
+ addConfiguredLoot(itemMap, sources.creatureRare, lootTables, rng, AHBOT_LOOT.creatureRare, itemOf, maxReq, maxIlvl);
986
+ addConfiguredLoot(itemMap, sources.creatureElite, lootTables, rng, AHBOT_LOOT.creatureElite, itemOf, maxReq, maxIlvl);
987
+ addConfiguredLoot(itemMap, sources.creatureRareElite, lootTables, rng, AHBOT_LOOT.creatureRareElite, itemOf, maxReq, maxIlvl);
988
+ addConfiguredLoot(itemMap, sources.creatureWorldBoss, lootTables, rng, AHBOT_LOOT.creatureWorldBoss, itemOf, maxReq, maxIlvl);
989
+ addConfiguredLoot(itemMap, sources.disenchant, lootTables, rng, AHBOT_LOOT.disenchant, itemOf, maxReq, maxIlvl);
990
+ addConfiguredLoot(itemMap, sources.fishing, lootTables, rng, AHBOT_LOOT.fishing, itemOf, maxReq, maxIlvl);
991
+ addConfiguredLoot(itemMap, sources.gameobject, lootTables, rng, AHBOT_LOOT.gameobject, itemOf, maxReq, maxIlvl);
992
+ addConfiguredLoot(itemMap, sources.skinning, lootTables, rng, AHBOT_LOOT.skinning, itemOf, maxReq, maxIlvl);
993
+
994
+ const prof = AHBOT_PROFESSION;
995
+ if (prof[1] > 0 && prof[3] >= 0 && sources.professionItems.length > 0) {
996
+ const maxTemplates = rollLootSourceCount(prof[0], prof[1], rng);
997
+ for (let i = 0; i < maxTemplates; i++) {
998
+ const itemId = sources.professionItems[rng.int(0, sources.professionItems.length - 1)]!;
999
+ const it = itemOf(itemId);
1000
+ if (!it) continue;
1001
+ if ((it.requiredLevel | 0) > maxReq || (it.itemLevel ?? 0) > maxIlvl) continue;
1002
+ if (it.quality === 0 || rng.int(0, (1 << (it.quality - 1)) - 1) > 0) continue;
1003
+ const pct = rng.int(prof[2], prof[3]);
1004
+ const count = Math.max(1, Math.round(Math.max(1, it.stackable | 0) * pct / 100));
1005
+ itemMap.set(itemId, (itemMap.get(itemId) ?? 0) + count);
1006
+ }
1007
+ }
1008
+
1009
+ if (itemMap.size === 0 && opts.catalog) {
1010
+ const catalog = typeof opts.catalog === 'function' ? opts.catalog() : opts.catalog;
1011
+ if (catalog && catalog.length > 0) {
1012
+ const sellable = catalog.filter((it) => canBotListItem(it, maxReq));
1013
+ if (sellable.length > 0) {
1014
+ const n = Math.min(80, sellable.length);
1015
+ for (let i = 0; i < n; i++) {
1016
+ const it = sellable[rng.int(0, sellable.length - 1)]!;
1017
+ const qty = it.stackable > 1 ? rng.int(1, Math.min(5, it.stackable)) : 1;
1018
+ itemMap.set(it.entry, (itemMap.get(it.entry) ?? 0) + qty);
1019
+ }
1020
+ }
1021
+ }
1022
+ }
1023
+
1024
+ const variance = opts.variance ?? DEFAULT_VALUE_VARIANCE;
1025
+ const listOpts = {
1026
+ startId: opts.startId,
1027
+ nowMs: opts.nowMs,
1028
+ seller: DEFAULT_SELLER,
1029
+ variance,
1030
+ createDs: opts.createDs,
1031
+ lookupProp: opts.lookupProp,
1032
+ vendorItems: sources.infiniteVendorItems,
1033
+ craftFloor: sources.craftFloor,
1034
+ pickSeller: () => pickBotSeller(rng, opts.names),
1035
+ };
1036
+ const out: Auction[] = [];
1037
+ for (const [itemId, totalCount] of itemMap) {
1038
+ const it = itemOf(itemId);
1039
+ if (!it || !canBotListItem(it, maxReq)) continue;
1040
+ if ((it.itemLevel ?? 0) > maxIlvl) continue;
1041
+ const maxStack = Math.max(1, it.stackable | 0);
1042
+ for (let stacked = 0; stacked < totalCount; stacked += maxStack) {
1043
+ const quantity = Math.min(maxStack, totalCount - stacked);
1044
+ pushListing(out, it, quantity, rng, listOpts);
1045
+ }
1046
+ }
1047
+ return out;
1048
+ }
1049
+
1050
+ export function appendSellPass(
1051
+ ah: AuctionHouseState,
1052
+ added: Auction[],
1053
+ ): AuctionHouseState {
1054
+ if (added.length === 0) return ah;
1055
+ return {
1056
+ ...ah,
1057
+ auctions: [...ah.auctions, ...added],
1058
+ nextId: ah.nextId + added.length,
1059
+ };
1060
+ }