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,644 @@
1
+ // Named team compositions: what an arena bracket puts across from you. A seat is a class plus a
2
+ // NAME PREFIX into that class's baked premade list, so it refers to a build the tree ships.
3
+
4
+ import { CLASS } from '../../data/schema/constants.ts';
5
+ import type { SkillLine } from '../../data/schema.ts';
6
+ import type { GearProfile } from '../bots/botGear.ts';
7
+ import { BG_TIERS, BG_TIER_ORDER, type BgTierId } from './bgTier.ts';
8
+
9
+ /** 1 is the duel / gauntlet ladder (plan P4.2, P4.4); 2, 3 and 5 are the arena brackets. */
10
+ export type ArenaBracket = 1 | 2 | 3 | 5;
11
+
12
+ export interface ArenaCompSeat {
13
+ cls: number;
14
+ // Case-insensitive PREFIX of a row in `ds.botSpecs(cls)`. Always a `pvp ` row here — the premades this
15
+ // table exists to point at.
16
+ spec: string;
17
+ role: 'tank' | 'healer' | 'dps';
18
+ // A pvp band VARIANT name (rotationSuggestions selectBand). Absent = the class's default pvp
19
+ // band, which is what every build but the four promoted ones runs.
20
+ rotation?: string;
21
+ /**
22
+ * G11's dirty axis: gear for THIS SEAT, overriding the comp's. Absent = `comp.gear`, which is
23
+ * what every shipped comp uses and the only thing an honorable round allows - the cell owns
24
+ * tier and gear there, so a win is about the list.
25
+ *
26
+ * A dirty round is where this earns its keep: one contender brings twink kit to a field cell,
27
+ * declares it, and the round file stamps the asymmetry. `bgRoster.ts:198` is the single place a
28
+ * seat's profile reaches the body, so this rides through there and nowhere else.
29
+ */
30
+ gear?: GearProfile;
31
+ /** G11: entries this seat carries on top of the loadout rule. `applyNamedItemList`, one stack each. */
32
+ items?: readonly number[];
33
+ /** G11: a pool filter — `generateCompBots` seats a body of this class that rolled the skill, or none. */
34
+ profession?: SkillLine;
35
+ }
36
+
37
+ export interface ArenaComp {
38
+ id: string;
39
+ /** What the player reads. Classes and builds, not a story. */
40
+ name: string;
41
+ bracket: ArenaBracket;
42
+ /** Where it sits on the shipped skill axis (bgTier.ts:23-63). */
43
+ tier: BgTierId;
44
+ /** Gear the whole comp wears. One of GEAR_PROFILES (botGear.ts:55-63). */
45
+ gear: GearProfile;
46
+ seats: readonly ArenaCompSeat[];
47
+ /**
48
+ * G9: a DIFFICULTY is a list as well as a gear profile. A tier named here makes every seat of
49
+ * that rung run the variant named, so the Freemade warrior and the Apes warrior can fight
50
+ * differently and not only hit harder. A tier absent keeps the seat's own `rotation` - which is
51
+ * the class default for the shipped nine - so the ladder is unchanged until a variant is
52
+ * authored for a rung.
53
+ *
54
+ * Per CLASS and not per tier on purpose: a convention like `<class>-<tier>` cannot say "these
55
+ * two tiers share a list", and a field on `BG_TIERS` would force all nine classes to move
56
+ * together.
57
+ */
58
+ variantByTier?: Partial<Record<BgTierId, string>>;
59
+ }
60
+
61
+ const D = (cls: number, spec: string): ArenaCompSeat => ({ cls, spec, role: 'dps' });
62
+ const H = (cls: number, spec: string): ArenaCompSeat => ({ cls, spec, role: 'healer' });
63
+
64
+ // P4.2, the 1v1 matrix: one duelist per class on a real `pvp *` premade, plus the four promoted
65
+ // variants. POOL_BUILDS and TRADE_BUILDS below join them into DUELIST_BUILDS.
66
+ const CORE_BUILDS: readonly ArenaComp[] = [
67
+ { id: 'duel-warrior-arms', name: 'Warrior, arms', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.WARRIOR, 'pvp arms')] },
68
+ // The seat names `ret-duel-v1` because the ret premade RESOLVES Holy below level 40
69
+ // (`scripts/pvp/band-coverage.mjs`), and Holy is also the tree a paladin HEALER's role override
70
+ // asks for (`companionRotation.ts:57`) - so the sub-60 duel list has to be a named variant or
71
+ // every pvp healer paladin would be handed it. At 49, 59 and 60 the seat resolves Retribution,
72
+ // no `ret-duel-v1` band covers that tree, and `selectBand` falls to the variant-less pvp pool,
73
+ // which is `Retribution@60` - the same list this rung fought before.
74
+ { id: 'duel-paladin-ret', name: 'Paladin, retribution', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.PALADIN, 'pvp dps ret'), rotation: 'ret-duel-v1' }] },
75
+ { id: 'duel-hunter-mm', name: 'Hunter, marksmanship', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.HUNTER, 'pvp dps mm')] },
76
+ { id: 'duel-rogue-combat', name: 'Rogue, combat swords', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.ROGUE, 'pvp dps combat (swords)')] },
77
+ {
78
+ id: 'duel-priest-shadow',
79
+ name: 'Priest, shadow',
80
+ bracket: 1, tier: 'normal', gear: 'field',
81
+ seats: [D(CLASS.PRIEST, 'pvp dps shadow')],
82
+ // G9's first use was `variantByTier: { skilled: 'pressure-v1', apes: 'pressure-v1' }`, on the
83
+ // strength of r6's 29% vs 21%. That round was fought NAKED (duel plan §1b), and re-priced armed
84
+ // in 2026-08-29-r14 the same pair reads 29% vs 31% - the variant is WORSE than this build. The
85
+ // rungs go back to the shipped list; `variantByTier` itself is unchanged and unused.
86
+ },
87
+ { id: 'duel-shaman-enhance', name: 'Shaman, two-hand enhancement', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.SHAMAN, 'pvp dps enhan (2hand)')] },
88
+ { id: 'duel-mage-frost', name: 'Mage, frost', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.MAGE, 'pvp dps frost')] },
89
+ { id: 'duel-warlock-sl', name: 'Warlock, soul link', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.WARLOCK, 'pvp dps demo (sl)')] },
90
+ { id: 'duel-druid-feral', name: 'Druid, feral', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.DRUID, 'pvp dps feral')] },
91
+ // PROMOTED off round 2026-08-28-r6 by the §G5 rule (`scripts/pvp/duel-promote.mjs`). Each beat
92
+ // its class's shipped build over 10 duels in BOTH directions AND leads it on the full cell, so
93
+ // none of the three is the seat edge: arms 10-0 (100%/100% by seat) and 67% vs 47% full-cell,
94
+ // soul link 8-2 (80%/80%) and 69% vs 62%, shadow 7-2-1 (80%/60%) and 35% vs 21%. Each carries
95
+ // its own authored band on the seat, so all five of its rungs fight that list.
96
+ { id: 'duel-warrior-arms-duel', name: 'Warrior, arms (duel list)', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'arms-duel-v1' }] },
97
+ { id: 'duel-warlock-sl-demo', name: 'Warlock, demonology soul link', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.WARLOCK, 'pvp dps demo (sl)'), rotation: 'sl-v1' }] },
98
+ { id: 'duel-priest-shadow-grok2', name: 'Priest, shadow (leech and blast)', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.PRIEST, 'pvp dps shadow'), rotation: 'g-shadow-v2' }] },
99
+ // PROMOTED off round 2026-08-29-r11, the FIRST round fought by armed bodies - r1..r10 ran on a
100
+ // bench that never attached the item catalog, so every seat was naked and every weapon ability was
101
+ // refused. This variant read 50% h2h and LOST the cell in r10; armed it reads 9-0-1, 100%/80% by
102
+ // seat - it clears both seats, so it is not the seat edge - and 72% vs 62% on the full cell.
103
+ { id: 'duel-hunter-mm-deadzone', name: 'Hunter, marksmanship (dead zone)', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.HUNTER, 'pvp dps mm'), rotation: 'dead-zone-v1' }] },
104
+ ];
105
+
106
+ // Seat kits, ALL unslotted: a slotted entry overwrites the Insignia once the paperdoll is full
107
+ // (bgConsumes.ts:134). Reflectors ride equipEngineerTrinket, which refuses to (bgConsumes.ts:158).
108
+ const SAPPER = [10646, 18641, 4390]; // Goblin Sapper Charge, Dense Dynamite, Iron Grenade
109
+ const FRAG = [15993, 10514, 4395]; // Thorium Grenade, Mithril Frag Bomb, Goblin Land Mine
110
+ const ORDNANCE = [10586, 4384, 4390]; // The Big One, Explosive Sheep, Iron Grenade
111
+ const ARCANE_ORDNANCE = [16040, 16005, 18641]; // Arcane Bomb, Dark Iron Bomb, Dense Dynamite
112
+ const HEAVY_ORDNANCE = [16005, 10646, 4390]; // Dark Iron Bomb, Goblin Sapper Charge, Iron Grenade
113
+ // No profession gate, so these ride at EVERY rung — the tier's own kit starts at twink (bgRoster.ts:84).
114
+ const RAGE_KIT = [13442, 3387, 13455, 5634]; // Mighty Rage, Limited Invuln, Stoneshield, Free Action
115
+ const SHADOW_KIT = [9172, 5634, 9030, 13452]; // Invisibility, Free Action, Restorative, Mongoose
116
+ const MANA_KIT = [13444, 9030, 3387, 20008]; // Major Mana, Restorative, Limited Invuln, Living Action
117
+ const RUNE_KIT = [12662, 9030, 5634]; // Demonic Rune, Restorative, Free Action
118
+ const JUJU_KIT = [12459, 5634, 13453]; // Juju Escape, Free Action, Elixir of Brute Force
119
+
120
+ // Premades the tree bakes and the gauntlet never seated: 9 of the 34 `pvp *` rows were in use.
121
+ const POOL_BUILDS: readonly ArenaComp[] = [
122
+ { id: 'duel-warrior-fury', name: 'Warrior, fury', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.WARRIOR, 'pvp fury')] },
123
+ { id: 'duel-paladin-reck', name: 'Paladin, reckoning bomb', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.PALADIN, 'pvp dps ret (Loaded Reck Bomb)')] },
124
+ { id: 'duel-hunter-surv', name: 'Hunter, survival', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.HUNTER, 'pvp dps surv')] },
125
+ { id: 'duel-hunter-bm', name: 'Hunter, beast mastery', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.HUNTER, 'pvp dps bm')] },
126
+ { id: 'duel-rogue-daggers', name: 'Rogue, combat daggers', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.ROGUE, 'pvp dps combat (daggers)')] },
127
+ { id: 'duel-shaman-elem', name: 'Shaman, elemental', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.SHAMAN, "pvp dps elem (nature's swiftness)")] },
128
+ { id: 'duel-mage-arcane', name: 'Mage, arcane', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.MAGE, 'pvp dps arcane (venruki)')] },
129
+ { id: 'duel-warlock-affli', name: 'Warlock, affliction', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.WARLOCK, 'pvp dps affli (sm/ruin)')] },
130
+ { id: 'duel-warlock-destro', name: 'Warlock, destruction', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.WARLOCK, 'pvp dps destro (conflagrate)')] },
131
+ { id: 'duel-warlock-sl-nightfall', name: 'Warlock, soul link nightfall', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.WARLOCK, 'pvp dps demo (soul link/ nightfall)')] },
132
+ { id: 'duel-druid-balance', name: 'Druid, balance', bracket: 1, tier: 'normal', gear: 'field', seats: [D(CLASS.DRUID, 'pvp dps balance (boomkin)')] },
133
+ ];
134
+
135
+ // Bodies with a TRADE behind them: `profession` filters the pool, `items` stocks the bags. Rank rides
136
+ // the gear profile (squad.ts:348), so a Freemade tinker throws cheap and only raid rungs reach Thorium.
137
+ const TRADE_BUILDS: readonly ArenaComp[] = [
138
+ { id: 'duel-warrior-sapper', name: 'Warrior, arms sapper', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.WARRIOR, 'pvp arms'), profession: 'engineering', items: SAPPER }] },
139
+ { id: 'duel-rogue-bomber', name: 'Rogue, daggers bomber', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.ROGUE, 'pvp dps combat (daggers)'), profession: 'engineering', items: FRAG }] },
140
+ { id: 'duel-hunter-tinker', name: 'Hunter, survival tinker', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.HUNTER, 'pvp dps surv'), profession: 'engineering', items: ORDNANCE }] },
141
+ { id: 'duel-mage-bomber', name: 'Mage, frost bomber', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.MAGE, 'pvp dps frost'), profession: 'engineering', items: ARCANE_ORDNANCE }] },
142
+ { id: 'duel-shaman-bomber', name: 'Shaman, enhancement bomber', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.SHAMAN, 'pvp dps enhan (2hand)'), profession: 'engineering', items: HEAVY_ORDNANCE }] },
143
+ { id: 'duel-warrior-potions', name: 'Warrior, arms consumables', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.WARRIOR, 'pvp arms'), items: RAGE_KIT }] },
144
+ { id: 'duel-rogue-potions', name: 'Rogue, swords consumables', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), items: SHADOW_KIT }] },
145
+ { id: 'duel-priest-potions', name: 'Priest, shadow consumables', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.PRIEST, 'pvp dps shadow'), items: MANA_KIT }] },
146
+ { id: 'duel-warlock-runes', name: 'Warlock, affliction runes', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.WARLOCK, 'pvp dps affli (sm/ruin)'), items: RUNE_KIT }] },
147
+ { id: 'duel-druid-juju', name: 'Druid, feral juju', bracket: 1, tier: 'normal', gear: 'field', seats: [{ ...D(CLASS.DRUID, 'pvp dps feral'), items: JUJU_KIT }] },
148
+ ];
149
+
150
+ const DUELIST_BUILDS: readonly ArenaComp[] = [...CORE_BUILDS, ...POOL_BUILDS, ...TRADE_BUILDS];
151
+
152
+
153
+ // Every build at every tier — P4.4's gauntlet ladder as data, Freemade at the bottom. DERIVED,
154
+ // because a tier is a gear profile plus a cadence and changes nothing about which premade runs.
155
+ function perTier(builds: readonly ArenaComp[]): readonly ArenaComp[] {
156
+ return BG_TIER_ORDER.flatMap((tier) =>
157
+ builds.map((b): ArenaComp => ({
158
+ ...b,
159
+ id: `${b.id}-${tier}`,
160
+ name: `${BG_TIERS[tier].name} ${b.name.charAt(0).toLowerCase()}${b.name.slice(1)}`,
161
+ tier,
162
+ gear: BG_TIERS[tier].enemyGear,
163
+ // G9: the rung derives its own LIST here, exactly where it already derives id, name and gear.
164
+ // `variantByTier` names one per tier; a tier it does not name keeps the seat's own rotation,
165
+ // which is the class default for the shipped builds.
166
+ seats: b.variantByTier?.[tier]
167
+ ? b.seats.map((s) => ({ ...s, rotation: b.variantByTier![tier]! }))
168
+ : b.seats,
169
+ })));
170
+ }
171
+
172
+ const DUELISTS: readonly ArenaComp[] = perTier(DUELIST_BUILDS);
173
+
174
+ // Tiers the CLIMB uses. `freemade` is a battleground filler - "a thrown-together pug in shabby kit"
175
+ // (bgTier.ts:25) - and with 34 builds it was 34 duels in grey before the ladder reached quest gear.
176
+ // Its rungs still exist for the bench and for `pickArenaComp`; they are just not part of the climb.
177
+ const GAUNTLET_TIERS: readonly BgTierId[] = BG_TIER_ORDER.filter((t) => t !== 'freemade');
178
+
179
+ /** The gauntlet: every duelist, weakest rung first. Cite: BG_TIER_ORDER (bgTier.ts:23). */
180
+ export function gauntletLadder(): ArenaComp[] {
181
+ return GAUNTLET_TIERS.flatMap((tier) => DUELISTS.filter((c) => c.tier === tier));
182
+ }
183
+
184
+ // The comp a 1v1 arena seats: the rung after the highest one beaten. Null once the ladder is
185
+ // cleared, and the caller then falls back to the seeded `pickArenaComp`.
186
+ export function gauntletNextComp(rungsBeaten: number): ArenaComp | null {
187
+ const ladder = gauntletLadder();
188
+ const i = Math.max(0, Math.trunc(rungsBeaten || 0));
189
+ return i < ladder.length ? ladder[i]! : null;
190
+ }
191
+
192
+ // The rung count after a 1v1 result: the HIGHEST rung beaten, so it is a trophy rather than a
193
+ // queue. Only a WIN moves it and it never decreases. It stopped being "the next rung" when rating
194
+ // took over seating (arenaRating.ts) - a rating picks any rung near you, so a strict +1 on the very
195
+ // next one would have frozen the count for good. A comp off the ladder (freemade, or a team
196
+ // bracket) is not a rung and moves nothing.
197
+ export function gauntletRungAfter(
198
+ rungsBeaten: number,
199
+ facedCompId: string | null,
200
+ won: boolean,
201
+ ): number {
202
+ const cur = Math.max(0, Math.trunc(rungsBeaten || 0));
203
+ if (!won || facedCompId == null) return cur;
204
+ const i = gauntletLadder().findIndex((c) => c.id === facedCompId);
205
+ return i < 0 ? cur : Math.max(cur, i + 1);
206
+ }
207
+
208
+ /** Total rungs, for the surface line. */
209
+ export function gauntletLength(): number {
210
+ return gauntletLadder().length;
211
+ }
212
+
213
+ // P4.3, first 2v2 pairings. Three, not forty: the plan is explicit that the lab (P7) says which comps are
214
+ // worth cloning, and authoring a wall of them first is guessing.
215
+ const PAIR_BUILDS: readonly ArenaComp[] = [
216
+ {
217
+ id: 'arena2-warrior-priest',
218
+ name: 'Warrior and priest',
219
+ bracket: 2, tier: 'normal', gear: 'field',
220
+ seats: [D(CLASS.WARRIOR, 'pvp arms'), H(CLASS.PRIEST, 'pvp heal holy')],
221
+ },
222
+ {
223
+ id: 'arena2-rogue-priest',
224
+ name: 'Rogue and priest',
225
+ bracket: 2, tier: 'normal', gear: 'field',
226
+ seats: [D(CLASS.ROGUE, 'pvp dps combat (daggers)'), H(CLASS.PRIEST, 'pvp heal holy')],
227
+ },
228
+ // Four more off the SAME premade rows the duelist pool seats, so no prefix is new here either.
229
+ // One carries the sapper kit, which is the 2v2 case of the trade seats above.
230
+ {
231
+ id: 'arena2-hunter-priest',
232
+ name: 'Hunter and priest',
233
+ bracket: 2, tier: 'normal', gear: 'field',
234
+ seats: [D(CLASS.HUNTER, 'pvp dps surv'), H(CLASS.PRIEST, 'pvp heal holy')],
235
+ },
236
+ {
237
+ id: 'arena2-mage-shaman',
238
+ name: 'Mage and shaman',
239
+ bracket: 2, tier: 'normal', gear: 'field',
240
+ seats: [D(CLASS.MAGE, 'pvp dps frost'), H(CLASS.SHAMAN, 'pvp heal resto')],
241
+ },
242
+ {
243
+ id: 'arena2-warlock-paladin',
244
+ name: 'Warlock and paladin',
245
+ bracket: 2, tier: 'normal', gear: 'field',
246
+ seats: [D(CLASS.WARLOCK, 'pvp dps destro (conflagrate)'), H(CLASS.PALADIN, 'pvp heal holy')],
247
+ },
248
+ {
249
+ id: 'arena2-sapper-druid',
250
+ name: 'Warrior sapper and druid',
251
+ bracket: 2, tier: 'normal', gear: 'field',
252
+ seats: [
253
+ { ...D(CLASS.WARRIOR, 'pvp arms'), profession: 'engineering', items: SAPPER },
254
+ H(CLASS.DRUID, 'pvp dps resto'),
255
+ ],
256
+ },
257
+ // PROMOTED off round 2026-09-10-w9, the first 2v2 promotion this program has produced: 76% both
258
+ // seats (chal 88 / targ 65, seatGap +23) over the best incumbent's 71%, and it won the war 6-4
259
+ // with 60% on BOTH seats. Same classes as `arena2-rogue-priest` above and it beats that row on
260
+ // lists alone — Kick plus Gouge as a second interrupt, and Holy Nova so a kick cannot eat the
261
+ // heal. Its rogue seat casts every one of its 17 built combat rows. Left CONTENDER_COMPS here.
262
+ {
263
+ id: 'arena2-rogue-priest-nova',
264
+ name: 'Combat swords rogue and holy priest (Nova triage)',
265
+ bracket: 2, tier: 'normal', gear: 'field',
266
+ seats: [
267
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w9a-kick-gouge' },
268
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w9a-nova-triage' },
269
+ ],
270
+ },
271
+ // PROMOTED off round 2026-09-10-w13. Both authors again picked the promoted comp's own classes
272
+ // and both keyed a PEEL. b took the higher full-cell (69%, chal 84 / targ 53) but LOST the war
273
+ // 3-7; a tied the best incumbent at 67% with an identical chal 78 / targ 56 / gap 22 split, which
274
+ // "not below the best incumbent" (plan §5) admits. Both beat `arena2-warrior-priest` - the comp
275
+ // that had beaten every rogue-priest before - 70% and 80%. Holy Nova cast 111 and 102 times here
276
+ // against ZERO in every round before §W12 fixed it.
277
+ {
278
+ id: 'arena2-rogue-priest-peel',
279
+ name: 'Combat swords rogue and holy priest (peel Blind, disc Nova)',
280
+ bracket: 2, tier: 'normal', gear: 'field',
281
+ seats: [
282
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w13a-kick-peel' },
283
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w13a-nova-disc' },
284
+ ],
285
+ },
286
+ {
287
+ id: 'arena2-rogue-priest-novastay',
288
+ name: 'Combat swords rogue and holy priest (Nova stay)',
289
+ bracket: 2, tier: 'normal', gear: 'field',
290
+ seats: [
291
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w13b-kick-gouge' },
292
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w13b-nova-stay' },
293
+ ],
294
+ },
295
+ ];
296
+
297
+ /** P4.3, one 3v3 to start: the shape a bracket-3 arena seats. */
298
+ const TRIO_BUILDS: readonly ArenaComp[] = [
299
+ {
300
+ id: 'arena3-warrior-mage-priest',
301
+ name: 'Warrior, mage and priest',
302
+ bracket: 3, tier: 'normal', gear: 'field',
303
+ seats: [
304
+ D(CLASS.WARRIOR, 'pvp arms'),
305
+ D(CLASS.MAGE, 'pvp dps frost'),
306
+ H(CLASS.PRIEST, 'pvp heal holy'),
307
+ ],
308
+ },
309
+ {
310
+ id: 'arena3-rogue-warlock-druid',
311
+ name: 'Rogue, warlock and druid',
312
+ bracket: 3, tier: 'normal', gear: 'field',
313
+ seats: [
314
+ D(CLASS.ROGUE, 'pvp dps combat (daggers)'),
315
+ D(CLASS.WARLOCK, 'pvp dps affli (sm/ruin)'),
316
+ H(CLASS.DRUID, 'pvp dps resto'),
317
+ ],
318
+ },
319
+ // HORDE, and it has to be one side: paladin is Alliance-only and shaman Horde-only, so the
320
+ // paladin healer this trio shipped with made it unseatable by either (`arenaLab.ts:96`).
321
+ {
322
+ id: 'arena3-hunter-shaman-priest',
323
+ name: 'Hunter, shaman and priest',
324
+ bracket: 3, tier: 'normal', gear: 'field',
325
+ seats: [
326
+ D(CLASS.HUNTER, 'pvp dps bm'),
327
+ D(CLASS.SHAMAN, "pvp dps elem (nature's swiftness)"),
328
+ H(CLASS.PRIEST, 'pvp heal holy'),
329
+ ],
330
+ },
331
+ // PROMOTED off round 2026-09-10-w12, the first war round at bracket 3 and the first round to
332
+ // promote BOTH authors: b at 83% (chal 80 / targ 85) and a at 68% (65 / 70) against the best
333
+ // incumbent's 35%, seat gap -5 each. Blind, both replaced the mage that collapses as the enemy
334
+ // seat with a second melee, so two bodies dump Mortal Strike and Kidney on the healer.
335
+ {
336
+ id: 'arena3-warrior-rogue-priest-nova',
337
+ name: 'Arms warrior, combat rogue and holy priest (nova stack)',
338
+ bracket: 3, tier: 'normal', gear: 'field',
339
+ seats: [
340
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w12b-ms-pummel' },
341
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w12b-kick-blind' },
342
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w12b-nova-stack' },
343
+ ],
344
+ },
345
+ {
346
+ id: 'arena3-warrior-rogue-priest-peel',
347
+ name: 'Arms warrior, combat swords rogue and holy priest (peel)',
348
+ bracket: 3, tier: 'normal', gear: 'field',
349
+ seats: [
350
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w12a-ms-healer' },
351
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w12a-kick-blind' },
352
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w12a-party-nova' },
353
+ ],
354
+ },
355
+ ];
356
+
357
+ /**
358
+ * G6, the first 5v5. Bracket 5 had nothing at all, so `pickArenaComp(5, ...)` returned null and
359
+ * the bracket could not seat.
360
+ *
361
+ * ONE, and every seat copied rather than invented (CLAUDE.md §5): the three dps are the TRIO's
362
+ * own warrior and mage plus the `arena2-rogue-priest` rogue, and the two healers are the holy
363
+ * priest both PAIRS use and the resto druid `arena2-warlock-druid` already seats as its healer.
364
+ * So no premade prefix and no build appears here for the first time. Which comps are worth
365
+ * cloning is the lab's answer, not this table's (P4.3's restraint, and duel plan §G6).
366
+ */
367
+ const FIVE_BUILDS: readonly ArenaComp[] = [
368
+ {
369
+ id: 'arena5-warrior-rogue-mage-priest-druid',
370
+ name: 'Warrior, rogue, mage, priest and druid',
371
+ bracket: 5, tier: 'normal', gear: 'field',
372
+ seats: [
373
+ D(CLASS.WARRIOR, 'pvp arms'),
374
+ D(CLASS.ROGUE, 'pvp dps combat (daggers)'),
375
+ D(CLASS.MAGE, 'pvp dps frost'),
376
+ H(CLASS.PRIEST, 'pvp heal holy'),
377
+ H(CLASS.DRUID, 'pvp dps resto'),
378
+ ],
379
+ },
380
+ // PROMOTED off round 2026-09-10-w8, the first war round at this bracket: 75% both seats
381
+ // (chal 90 / targ 60, seatGap +30) against this table's other comp at 40%, and it won the war
382
+ // 8-2. Two healers where the row above runs one, and swords rather than daggers because a
383
+ // dagger rogue cannot get behind (KI-1073). It left CONTENDER_COMPS as it joined here.
384
+ {
385
+ id: 'arena5-warrior-rogue-mage-priest-shaman',
386
+ name: 'Warrior, rogue, mage, priest and shaman',
387
+ bracket: 5, tier: 'normal', gear: 'field',
388
+ seats: [
389
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w8b-ms-pummel' },
390
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w8b-kick-blind' },
391
+ { ...D(CLASS.MAGE, 'pvp dps frost'), rotation: 'w8b-poly-offheal' },
392
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w8b-party-triage' },
393
+ { ...H(CLASS.SHAMAN, 'pvp heal resto'), rotation: 'w8b-ground-chain' },
394
+ ],
395
+ },
396
+ // PROMOTED off round 2026-09-10-w14 at 67% both seats against the best incumbent's 47%, winning
397
+ // the war 6-4. Read the seat gap before trusting the headline: this one is **+40** (chal 87 /
398
+ // targ 47) where the author b setup it beat sits at +13 - so the promoted comp is the MORE
399
+ // seat-dependent of the two, the opposite of round w12 where both promoted at -5.
400
+ {
401
+ id: 'arena5-wrmps-peel',
402
+ name: 'Arms warrior, swords rogue, frost mage, holy priest, resto shaman (peel)',
403
+ bracket: 5, tier: 'normal', gear: 'field',
404
+ seats: [
405
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w14a-ms-pummel' },
406
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w14a-kick-peel' },
407
+ { ...D(CLASS.MAGE, 'pvp dps frost'), rotation: 'w14a-poly-sheep' },
408
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w14a-nova-triage' },
409
+ { ...H(CLASS.SHAMAN, 'pvp heal resto'), rotation: 'w14a-ground-lhw' },
410
+ ],
411
+ },
412
+ ];
413
+
414
+ // The team brackets ride the SAME derivation the duelists do. Before this they existed only at
415
+ // `normal`/`field`, and `generateCompBots` takes gear from `seat.gear ?? comp.gear`
416
+ // (`bgRoster.ts:213`) - so a named 2v2/3v3/5v5 wore quest kit at every tier and the difficulty
417
+ // picker moved nothing but the consumes flag. Rating is the caller that needs the range.
418
+ const PAIRS: readonly ArenaComp[] = perTier(PAIR_BUILDS);
419
+ const TRIOS: readonly ArenaComp[] = perTier(TRIO_BUILDS);
420
+ const FIVES: readonly ArenaComp[] = perTier(FIVE_BUILDS);
421
+
422
+ export const ARENA_COMPS: readonly ArenaComp[] = [...DUELISTS, ...PAIRS, ...TRIOS, ...FIVES];
423
+
424
+ // Fighters UNDER TEST the duel lab benches. Absent from ARENA_COMPS is the gate — a promoted
425
+ // contender leaves this list as it joins DUELIST_BUILDS, or it shadows its own promotion.
426
+ export const CONTENDER_COMPS: readonly ArenaComp[] = [
427
+ // RELEGATED off round 26, five rounds after a9f147c84 promoted it: 1554 and ABOVE the bracket 2
428
+ // median 1544, but seat-dependent at gap3 60 against a shipped field sitting at 31 to 47. The
429
+ // player meets a comp as the TARGET side, where a gap that size means it underperforms its
430
+ // rating. Its author keeps it here and the ladder keeps rating it.
431
+ {
432
+ id: 'arena2-warrior-priest-w10b',
433
+ name: 'Arms warrior and holy priest (Execute MS, Nova dispel)',
434
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
435
+ seats: [
436
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w10b-execute-ms' },
437
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w10b-nova-dispel' },
438
+ ],
439
+ },
440
+ // RELEGATED off round 16: 1297 over 8 rounds, 247 under the bracket 2 median, and no class
441
+ // leaves the field with it (`ladder.mjs pool --bracket 2`). It stays here so the ladder can still
442
+ // rate it and an author can still re-author it; it is only out of the pool the player faces.
443
+ {
444
+ id: 'arena2-warlock-druid',
445
+ name: 'Warlock and druid',
446
+ bracket: 2, tier: 'normal', gear: 'field',
447
+ seats: [D(CLASS.WARLOCK, 'pvp dps affli'), H(CLASS.DRUID, 'pvp dps resto')],
448
+ },
449
+ {
450
+ id: 'duel-mage-frost-shatter-normal',
451
+ name: 'Mage, frost (nova opener)',
452
+ // Tier in the id and gear off the tier, exactly as DUELISTS derives a rung: a challenger
453
+ // has to wear what the rung it is challenging wears, or the bench is measuring the gear.
454
+ bracket: 1, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
455
+ seats: [{ ...D(CLASS.MAGE, 'pvp dps frost'), rotation: 'shatter-v1' }],
456
+ },
457
+ {
458
+ id: 'duel-priest-shadow-pressure-normal',
459
+ name: 'Priest, shadow (fear first)',
460
+ bracket: 1, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
461
+ seats: [{ ...D(CLASS.PRIEST, 'pvp dps shadow'), rotation: 'pressure-v1' }],
462
+ },
463
+ {
464
+ id: 'duel-priest-shadow-grok-normal',
465
+ name: 'Priest, shadow (scream disc)',
466
+ bracket: 1, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
467
+ seats: [{ ...D(CLASS.PRIEST, 'pvp dps shadow'), rotation: 'g-shadow-v1' }],
468
+ },
469
+ // `dead-zone-v1` was here until it was PROMOTED off r11 and became a DUELIST_BUILD above. A
470
+ // promoted list leaves this table, the same way arms-duel-v1, sl-v1 and g-shadow-v2 did - it is an
471
+ // incumbent now, and leaving it would bench one list twice under two ids in the same cell.
472
+ {
473
+ id: 'duel-druid-feral-bearcat-normal',
474
+ name: 'Druid, feral (bear swap)',
475
+ bracket: 1, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
476
+ seats: [{ ...D(CLASS.DRUID, 'pvp dps feral'), rotation: 'bearcat-v1' }],
477
+ },
478
+ // Round 2026-09-10-w2, the first WAR round: two blind authors, one bracket (arena-setup-wars.md
479
+ // §2). Registered here by the orchestrator from each report's JSON block, never by the author.
480
+ {
481
+ id: 'arena2-warrior-priest-w2a',
482
+ name: 'Warrior arms and holy priest',
483
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
484
+ seats: [
485
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w2a-ms-healer' },
486
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w2a-ally-triage' },
487
+ ],
488
+ },
489
+ {
490
+ id: 'arena2-mage-priest-w2b',
491
+ name: 'Mage frost and priest holy',
492
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
493
+ seats: [
494
+ { ...D(CLASS.MAGE, 'pvp dps frost'), rotation: 'w2b-poly-shatter' },
495
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w2b-shield-peel' },
496
+ ],
497
+ },
498
+ // Round 2026-09-10-w6, the second war round: both authors read their OWN w2 debrief and both
499
+ // answered it with a warrior plus a healer, blind, differing only in the healer.
500
+ {
501
+ id: 'arena2-warrior-shaman-w6a',
502
+ name: 'Warrior arms and resto shaman',
503
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
504
+ seats: [
505
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w6a-ms-healer' },
506
+ { ...H(CLASS.SHAMAN, 'pvp heal resto'), rotation: 'w6a-ground-purge' },
507
+ ],
508
+ },
509
+ {
510
+ id: 'arena2-warrior-paladin-w6b',
511
+ name: 'Warrior arms and holy paladin',
512
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
513
+ seats: [
514
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w6b-ms-pummel' },
515
+ { ...H(CLASS.PALADIN, 'pvp heal holy'), rotation: 'w6b-bop-peel' },
516
+ ],
517
+ },
518
+ // Round 2026-09-10-w7. Both authors answered their own w6 debrief: a's warrior stopped dancing
519
+ // stances, b's dropped the paladin that died 56/80 for the priest the cell's top two already use.
520
+ {
521
+ id: 'arena2-warrior-priest-w7a',
522
+ name: 'Warrior arms and holy priest (berserker)',
523
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
524
+ seats: [
525
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w7a-zerk-stick' },
526
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w7a-self-bubble' },
527
+ ],
528
+ },
529
+ {
530
+ id: 'arena2-rogue-priest-w7b',
531
+ name: 'Combat swords rogue and holy priest',
532
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
533
+ seats: [
534
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w7b-kick-kidney' },
535
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w7b-self-shield' },
536
+ ],
537
+ },
538
+ // Round 2026-09-10-w9. Both authors blind-picked the INCUMBENT's own classes (swords rogue and
539
+ // holy priest, the 73% row) and tried to play it better, differing only in the lists.
540
+ // `arena2-rogue-priest-w9a` was here until it was PROMOTED off w9 and became a PAIR_BUILD —
541
+ // the same rule `dead-zone-v1` and the w8 five-man left this table under.
542
+ {
543
+ id: 'arena2-rogue-priest-w9b',
544
+ name: 'Combat swords rogue and holy priest (self triage)',
545
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
546
+ seats: [
547
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w9b-kick-blind' },
548
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w9b-self-triage' },
549
+ ],
550
+ },
551
+ // Round 2026-09-10-w8, the FIRST war round at bracket 5. Both authors ran two healers against
552
+ // the single incumbent's one, and both dropped its dagger rogue; blind, they differ in the
553
+ // third dps (hunter against rogue). Horde on both: shaman is Horde-only.
554
+ {
555
+ id: 'arena5-warrior-hunter-mage-priest-shaman-w8a',
556
+ name: 'Warrior, hunter, mage, priest and shaman',
557
+ bracket: 5, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
558
+ seats: [
559
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w8a-ms-healer' },
560
+ { ...D(CLASS.HUNTER, 'pvp dps mm'), rotation: 'w8a-viper-healer' },
561
+ { ...D(CLASS.MAGE, 'pvp dps frost'), rotation: 'w8a-poly-offheal' },
562
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w8a-party-triage' },
563
+ { ...H(CLASS.SHAMAN, 'pvp heal resto'), rotation: 'w8a-chain-ground' },
564
+ ],
565
+ },
566
+ // `arena5-warrior-rogue-mage-priest-shaman-w8b` was here until it was PROMOTED off w8 and became
567
+ // a FIVE_BUILD above — the same rule `dead-zone-v1` left this table under. Leaving it would
568
+ // bench one setup twice under two ids in the same cell.
569
+ // Round 2026-09-10-w10. Blind, the authors SPLIT: a iterated the promoted rogue-priest (Nova
570
+ // above the hurt-shield spam), b seated the arms warrior that beat it 8-2 and copied its priest.
571
+ {
572
+ id: 'arena2-rogue-priest-w10a',
573
+ name: 'Combat swords rogue and holy priest (Nova melee)',
574
+ bracket: 2, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
575
+ seats: [
576
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w10a-kidney-half' },
577
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w10a-nova-melee' },
578
+ ],
579
+ },
580
+ // Round 2026-09-10-w12, the FIRST war round at bracket 3 - openable only after §W11's gate stopped
581
+ // measuring potion-carrying bodies. Blind, BOTH authors picked the same class trio and both
582
+ // dropped the incumbent's mage, which the 3v3 debriefs had shown collapsing as the enemy seat.
583
+ // Both w12 contenders were here until they PROMOTED off that round and became TRIO_BUILDS above -
584
+ // the same rule dead-zone-v1 and the w8 five-man left this table under.
585
+ // Round 2026-09-10-w13 at bracket 2. Blind, both authors again picked the promoted comp's own
586
+ // classes and both keyed a PEEL - a's through a new `allyHasAggro` condition, b's in the engine's
587
+ // target picker. b's engine hunks were REVERTED at review (they cost the mirror; see
588
+ // repro-duel-peel-low-ally.mjs, red on purpose); both authors' BANDS stand.
589
+ // Both w13 contenders were here until they PROMOTED off that round and became PAIR_BUILDS
590
+ // above - the same rule dead-zone-v1 and the w8 five-man left this table under.
591
+ // Round 2026-09-10-w14 at bracket 5. Blind, both authors picked the SAME five classes as the
592
+ // promoted incumbent and differ only in the lists - the third round running where they converge.
593
+ // `arena5-wrmps-w14a` was here until it PROMOTED off w14 and became a FIVE_BUILD above.
594
+ // `arena5-wrmps-w14b` stays: it HELD at 53%, under the 60% floor, so it is still a contender.
595
+ {
596
+ id: 'arena5-wrmps-w14b',
597
+ name: 'Arms warrior, swords rogue, frost mage, holy priest, resto shaman (shoot)',
598
+ bracket: 5, tier: 'normal', gear: BG_TIERS.normal.enemyGear,
599
+ seats: [
600
+ { ...D(CLASS.WARRIOR, 'pvp arms'), rotation: 'w14b-ms-pummel' },
601
+ { ...D(CLASS.ROGUE, 'pvp dps combat (swords)'), rotation: 'w14b-kick-peel' },
602
+ { ...D(CLASS.MAGE, 'pvp dps frost'), rotation: 'w14b-poly-shoot' },
603
+ { ...H(CLASS.PRIEST, 'pvp heal holy'), rotation: 'w14b-nova-stack' },
604
+ { ...H(CLASS.SHAMAN, 'pvp heal resto'), rotation: 'w14b-ground-lhw' },
605
+ ],
606
+ },
607
+ ];
608
+
609
+ /** A comp by id, incumbent or contender. The bench names either; the game only seats the first. */
610
+ export function compById(id: string): ArenaComp | null {
611
+ return ARENA_COMPS.find((c) => c.id === id) ?? CONTENDER_COMPS.find((c) => c.id === id) ?? null;
612
+ }
613
+
614
+ /** Every comp that fits `bracket`, in table order. */
615
+ export function compsForBracket(bracket: ArenaBracket): ArenaComp[] {
616
+ return ARENA_COMPS.filter((c) => c.bracket === bracket);
617
+ }
618
+
619
+ // A comp for this bracket, chosen deterministically off the match seed, preferring this tier and
620
+ // falling back to any comp of the bracket. Null when none is authored, so the caller runs bots.
621
+ export function pickArenaComp(
622
+ bracket: ArenaBracket,
623
+ seed: number,
624
+ tier?: BgTierId,
625
+ ): ArenaComp | null {
626
+ const all = compsForBracket(bracket);
627
+ if (!all.length) return null;
628
+ const atTier = tier ? all.filter((c) => c.tier === tier) : [];
629
+ const pool = atTier.length ? atTier : all;
630
+ return pool[Math.abs(seed | 0) % pool.length] ?? null;
631
+ }
632
+
633
+ // Resolve a seat's spec PREFIX against the class's baked premade list. Returns the index into
634
+ // `ds.botSpecs(cls)`, or -1 when nothing matches — never a guess.
635
+ export function resolveCompSpecIdx(
636
+ specs: readonly { name: string; role: string }[],
637
+ seat: ArenaCompSeat,
638
+ ): number {
639
+ const want = seat.spec.toLowerCase();
640
+ for (let i = 0; i < specs.length; i++) {
641
+ if ((specs[i]?.name ?? '').toLowerCase().startsWith(want)) return i;
642
+ }
643
+ return -1;
644
+ }