azeroth-shell 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1163) hide show
  1. package/README.md +138 -2
  2. package/bin/azsh.mjs +19 -0
  3. package/docs/aifid/eventai-texts.json +4414 -0
  4. package/docs/dungeons/atlas/atlas-rows-dungeons.json +8989 -0
  5. package/docs/dungeons/survey/pack-id-migration.json +2418 -0
  6. package/package.json +35 -4
  7. package/src/autopilot/bossSkip.ts +26 -0
  8. package/src/autopilot/combatRotation.ts +824 -0
  9. package/src/autopilot/config.ts +533 -0
  10. package/src/autopilot/consumables.ts +58 -0
  11. package/src/autopilot/encounterStand.ts +121 -0
  12. package/src/autopilot/objectGatePlan.ts +53 -0
  13. package/src/autopilot/pathEngage.ts +229 -0
  14. package/src/autopilot/plan.ts +1643 -0
  15. package/src/autopilot/questPolicy.ts +274 -0
  16. package/src/autopilot/routeStep.ts +69 -0
  17. package/src/autopilot/sessionReport.ts +88 -0
  18. package/src/autopilot/topOffPower.ts +26 -0
  19. package/src/autopilot/view.ts +476 -0
  20. package/src/cli/bootCheck.mjs +34 -0
  21. package/src/cli/bootData.mjs +57 -0
  22. package/src/cli/combatLogFilter.ts +153 -0
  23. package/src/cli/combatLogFormat.ts +613 -0
  24. package/src/cli/fileRepository.mjs +105 -0
  25. package/src/cli/gzLoader.mjs +31 -0
  26. package/src/cli/liveGauntletEscort.ts +978 -0
  27. package/src/cli/liveStratUndead.ts +305 -0
  28. package/src/cli/macroHostCombat.ts +545 -0
  29. package/src/cli/macroHostWorld.ts +330 -0
  30. package/src/cli/prefs.mjs +31 -0
  31. package/src/cli/register.mjs +4 -0
  32. package/src/cli/repl.mjs +693 -0
  33. package/src/cli/rotationText.mjs +226 -0
  34. package/src/cli/squad.mjs +105 -0
  35. package/src/cli/term.mjs +144 -0
  36. package/src/cli/text.mjs +122 -0
  37. package/src/cli/tui.mjs +626 -0
  38. package/src/cli/tuiArena.mjs +109 -0
  39. package/src/cli/tuiAutopilotSettings.mjs +93 -0
  40. package/src/cli/tuiBags.mjs +180 -0
  41. package/src/cli/tuiBars.mjs +133 -0
  42. package/src/cli/tuiBg.mjs +243 -0
  43. package/src/cli/tuiBulk.mjs +162 -0
  44. package/src/cli/tuiCheck.mjs +1882 -0
  45. package/src/cli/tuiCity.mjs +396 -0
  46. package/src/cli/tuiCompanionKit.mjs +300 -0
  47. package/src/cli/tuiCompanions.mjs +471 -0
  48. package/src/cli/tuiDev.mjs +62 -0
  49. package/src/cli/tuiDungeon.mjs +606 -0
  50. package/src/cli/tuiEnchantTarget.mjs +120 -0
  51. package/src/cli/tuiFight.mjs +577 -0
  52. package/src/cli/tuiFightPanes.mjs +228 -0
  53. package/src/cli/tuiFloor.mjs +506 -0
  54. package/src/cli/tuiGear.mjs +158 -0
  55. package/src/cli/tuiHonor.mjs +74 -0
  56. package/src/cli/tuiLoot.mjs +97 -0
  57. package/src/cli/tuiMacros.mjs +144 -0
  58. package/src/cli/tuiOutfitter.mjs +115 -0
  59. package/src/cli/tuiPet.mjs +116 -0
  60. package/src/cli/tuiProfessions.mjs +800 -0
  61. package/src/cli/tuiRaid.mjs +127 -0
  62. package/src/cli/tuiRep.mjs +65 -0
  63. package/src/cli/tuiSaves.mjs +69 -0
  64. package/src/cli/tuiSearch.mjs +363 -0
  65. package/src/cli/tuiSettings.mjs +151 -0
  66. package/src/cli/tuiSimLab.mjs +80 -0
  67. package/src/cli/tuiTalents.mjs +60 -0
  68. package/src/cli/tuiViews.mjs +1178 -0
  69. package/src/cli/tuiWiki.mjs +181 -0
  70. package/src/cli/tuiWorld.mjs +361 -0
  71. package/src/cli/wikiIndex.ts +259 -0
  72. package/src/cli/wikiSources.ts +355 -0
  73. package/src/data/alteracValley.ts +176 -0
  74. package/src/data/appearanceOptions.ts +534 -0
  75. package/src/data/applyLootChanceSanity.ts +21 -0
  76. package/src/data/createFlavor.ts +96 -0
  77. package/src/data/customItems.ts +33 -0
  78. package/src/data/dataStore.ts +1904 -0
  79. package/src/data/dungeonGameObjects.ts +84 -0
  80. package/src/data/dungeonPlateCover.ts +66 -0
  81. package/src/data/dungeonSpawns.ts +294 -0
  82. package/src/data/dungeons/alterac-valley.ts +135 -0
  83. package/src/data/dungeons/apply-dungeon-rooms.ts +29 -0
  84. package/src/data/dungeons/apply-encounter-outdoors.ts +72 -0
  85. package/src/data/dungeons/apply-instance-geometry.ts +65 -0
  86. package/src/data/dungeons/apply-spawn-placement.ts +171 -0
  87. package/src/data/dungeons/blackfathom-deeps.ts +539 -0
  88. package/src/data/dungeons/blackrock-depths.ts +1410 -0
  89. package/src/data/dungeons/blackwing-lair.ts +129 -0
  90. package/src/data/dungeons/boss-eventai.ts +8 -0
  91. package/src/data/dungeons/deadmines.ts +410 -0
  92. package/src/data/dungeons/dire-maul-east.ts +980 -0
  93. package/src/data/dungeons/dire-maul-north.ts +661 -0
  94. package/src/data/dungeons/dire-maul-west.ts +785 -0
  95. package/src/data/dungeons/dungeon-rooms.json +5479 -0
  96. package/src/data/dungeons/encounter-outdoors.json +359 -0
  97. package/src/data/dungeons/eventai/blackfathom-deeps.ts +308 -0
  98. package/src/data/dungeons/eventai/blackrock-depths.ts +1257 -0
  99. package/src/data/dungeons/eventai/deadmines.ts +264 -0
  100. package/src/data/dungeons/eventai/dire-maul-east.ts +320 -0
  101. package/src/data/dungeons/eventai/gnomeregan.ts +213 -0
  102. package/src/data/dungeons/eventai/helpers.ts +79 -0
  103. package/src/data/dungeons/eventai/index.ts +133 -0
  104. package/src/data/dungeons/eventai/lbrs.ts +372 -0
  105. package/src/data/dungeons/eventai/maraudon.ts +323 -0
  106. package/src/data/dungeons/eventai/ragefire-chasm.ts +108 -0
  107. package/src/data/dungeons/eventai/razorfen-downs.ts +207 -0
  108. package/src/data/dungeons/eventai/razorfen-kraul.ts +326 -0
  109. package/src/data/dungeons/eventai/scholomance.ts +680 -0
  110. package/src/data/dungeons/eventai/shadowfang-keep.ts +230 -0
  111. package/src/data/dungeons/eventai/sm-cathedral.ts +75 -0
  112. package/src/data/dungeons/eventai/sm-graveyard.ts +150 -0
  113. package/src/data/dungeons/eventai/sm-library.ts +55 -0
  114. package/src/data/dungeons/eventai/stratholme-undead.ts +127 -0
  115. package/src/data/dungeons/eventai/sunken-temple.ts +582 -0
  116. package/src/data/dungeons/eventai/the-stockade.ts +228 -0
  117. package/src/data/dungeons/eventai/ubrs.ts +225 -0
  118. package/src/data/dungeons/eventai/uldaman.ts +355 -0
  119. package/src/data/dungeons/eventai/wailing-caverns.ts +396 -0
  120. package/src/data/dungeons/eventai/zul-farrak.ts +591 -0
  121. package/src/data/dungeons/gnomeregan.ts +909 -0
  122. package/src/data/dungeons/index.ts +126 -0
  123. package/src/data/dungeons/instance-geometry.json +5233 -0
  124. package/src/data/dungeons/key-sources.json +169 -0
  125. package/src/data/dungeons/lbrs.ts +996 -0
  126. package/src/data/dungeons/maraudon.ts +786 -0
  127. package/src/data/dungeons/molten-core.ts +194 -0
  128. package/src/data/dungeons/naxxramas.ts +173 -0
  129. package/src/data/dungeons/onyxias-lair.ts +71 -0
  130. package/src/data/dungeons/pack-from-clusters.ts +1256 -0
  131. package/src/data/dungeons/ragefire-chasm.ts +238 -0
  132. package/src/data/dungeons/razorfen-downs.ts +698 -0
  133. package/src/data/dungeons/razorfen-kraul.ts +766 -0
  134. package/src/data/dungeons/ruins-of-ahnqiraj.ts +121 -0
  135. package/src/data/dungeons/scholomance.ts +1076 -0
  136. package/src/data/dungeons/shadowfang-keep.ts +740 -0
  137. package/src/data/dungeons/sm-armory.ts +266 -0
  138. package/src/data/dungeons/sm-cathedral.ts +430 -0
  139. package/src/data/dungeons/sm-graveyard.ts +482 -0
  140. package/src/data/dungeons/sm-library.ts +337 -0
  141. package/src/data/dungeons/stratholme-live.ts +808 -0
  142. package/src/data/dungeons/stratholme-undead.ts +1164 -0
  143. package/src/data/dungeons/sunken-temple.ts +931 -0
  144. package/src/data/dungeons/temple-of-ahnqiraj.ts +119 -0
  145. package/src/data/dungeons/the-stockade.ts +282 -0
  146. package/src/data/dungeons/ubrs.ts +1286 -0
  147. package/src/data/dungeons/uldaman.ts +685 -0
  148. package/src/data/dungeons/wailing-caverns.ts +356 -0
  149. package/src/data/dungeons/zul-farrak.ts +686 -0
  150. package/src/data/dungeons/zul-gurub.ts +142 -0
  151. package/src/data/dungeons.ts +42 -0
  152. package/src/data/fixtures.ts +446 -0
  153. package/src/data/gameobject-data.json.gz +0 -0
  154. package/src/data/item-data.json.gz +0 -0
  155. package/src/data/loot-data.json.gz +0 -0
  156. package/src/data/maps/atlas-approach-maps.json +1425 -0
  157. package/src/data/maps/atlas-landmarks.json +1711 -0
  158. package/src/data/maps/dungeon-viewports.json +392 -0
  159. package/src/data/materializeModDamagePercentTaken.ts +70 -0
  160. package/src/data/materializeModHealthRegen.ts +89 -0
  161. package/src/data/materializeSpellReputation.ts +26 -0
  162. package/src/data/pageTexts.ts +19 -0
  163. package/src/data/profession-data.json.gz +0 -0
  164. package/src/data/raid-plans/blackfathom-deeps.json +86 -0
  165. package/src/data/raid-plans/blackrock-depths.json +419 -0
  166. package/src/data/raid-plans/blackwing-lair.json +328 -0
  167. package/src/data/raid-plans/deadmines.json +55 -0
  168. package/src/data/raid-plans/dire-maul-east.json +94 -0
  169. package/src/data/raid-plans/dire-maul-north.json +70 -0
  170. package/src/data/raid-plans/dire-maul-west.json +75 -0
  171. package/src/data/raid-plans/gnomeregan.json +131 -0
  172. package/src/data/raid-plans/lbrs.json +176 -0
  173. package/src/data/raid-plans/maraudon.json +102 -0
  174. package/src/data/raid-plans/molten-core.json +169 -0
  175. package/src/data/raid-plans/naxxramas.json +354 -0
  176. package/src/data/raid-plans/onyxias-lair.json +18 -0
  177. package/src/data/raid-plans/ragefire-chasm.json +30 -0
  178. package/src/data/raid-plans/razorfen-downs.json +75 -0
  179. package/src/data/raid-plans/razorfen-kraul.json +53 -0
  180. package/src/data/raid-plans/ruins-of-ahnqiraj.json +110 -0
  181. package/src/data/raid-plans/scholomance.json +170 -0
  182. package/src/data/raid-plans/shadowfang-keep.json +87 -0
  183. package/src/data/raid-plans/sm-armory.json +53 -0
  184. package/src/data/raid-plans/sm-cathedral.json +72 -0
  185. package/src/data/raid-plans/sm-graveyard.json +63 -0
  186. package/src/data/raid-plans/sm-library.json +23 -0
  187. package/src/data/raid-plans/stratholme-live.json +129 -0
  188. package/src/data/raid-plans/stratholme-undead.json +73 -0
  189. package/src/data/raid-plans/sunken-temple.json +159 -0
  190. package/src/data/raid-plans/temple-of-ahnqiraj.json +163 -0
  191. package/src/data/raid-plans/the-stockade.json +42 -0
  192. package/src/data/raid-plans/ubrs.json +53 -0
  193. package/src/data/raid-plans/uldaman.json +131 -0
  194. package/src/data/raid-plans/wailing-caverns.json +90 -0
  195. package/src/data/raid-plans/zul-farrak.json +156 -0
  196. package/src/data/raid-plans/zul-gurub.json +307 -0
  197. package/src/data/raidInstanceCreatures.mjs +473 -0
  198. package/src/data/rotations/index.ts +152 -0
  199. package/src/data/rotations/layout.mjs +72 -0
  200. package/src/data/rotations/pve/druid/balance.json +754 -0
  201. package/src/data/rotations/pve/druid/feral-tank.json +2448 -0
  202. package/src/data/rotations/pve/druid/feral.json +2660 -0
  203. package/src/data/rotations/pve/druid/restoration.json +424 -0
  204. package/src/data/rotations/pve/hunter/beast-mastery.json +1288 -0
  205. package/src/data/rotations/pve/hunter/marksmanship.json +1260 -0
  206. package/src/data/rotations/pve/hunter/survival.json +1373 -0
  207. package/src/data/rotations/pve/mage/arcane-leveling.json +1798 -0
  208. package/src/data/rotations/pve/mage/fire-leveling.json +2003 -0
  209. package/src/data/rotations/pve/mage/frost-leveling.json +1912 -0
  210. package/src/data/rotations/pve/paladin/holy.json +755 -0
  211. package/src/data/rotations/pve/paladin/protection.json +962 -0
  212. package/src/data/rotations/pve/paladin/retribution.json +924 -0
  213. package/src/data/rotations/pve/priest/discipline.json +772 -0
  214. package/src/data/rotations/pve/priest/holy.json +707 -0
  215. package/src/data/rotations/pve/priest/shadow.json +787 -0
  216. package/src/data/rotations/pve/rogue/assassination.json +2477 -0
  217. package/src/data/rotations/pve/rogue/combat.json +2483 -0
  218. package/src/data/rotations/pve/rogue/subtlety.json +2523 -0
  219. package/src/data/rotations/pve/shaman/elemental.json +1157 -0
  220. package/src/data/rotations/pve/shaman/enhancement.json +1085 -0
  221. package/src/data/rotations/pve/shaman/restoration.json +592 -0
  222. package/src/data/rotations/pve/warlock/affliction.json +1185 -0
  223. package/src/data/rotations/pve/warlock/demonology.json +1165 -0
  224. package/src/data/rotations/pve/warlock/destruction.json +1177 -0
  225. package/src/data/rotations/pve/warrior/arms.json +3020 -0
  226. package/src/data/rotations/pve/warrior/fury.json +2996 -0
  227. package/src/data/rotations/pve/warrior/protection.json +2509 -0
  228. package/src/data/rotations/pvp/druid/balance.json +593 -0
  229. package/src/data/rotations/pvp/druid/feral.json +3276 -0
  230. package/src/data/rotations/pvp/druid/restoration.json +662 -0
  231. package/src/data/rotations/pvp/hunter/beast-mastery.json +665 -0
  232. package/src/data/rotations/pvp/hunter/marksmanship.json +2406 -0
  233. package/src/data/rotations/pvp/hunter/survival.json +635 -0
  234. package/src/data/rotations/pvp/mage/arcane.json +574 -0
  235. package/src/data/rotations/pvp/mage/fire.json +570 -0
  236. package/src/data/rotations/pvp/mage/frost.json +4048 -0
  237. package/src/data/rotations/pvp/paladin/holy.json +1498 -0
  238. package/src/data/rotations/pvp/paladin/protection.json +567 -0
  239. package/src/data/rotations/pvp/paladin/retribution.json +1110 -0
  240. package/src/data/rotations/pvp/priest/discipline.json +1848 -0
  241. package/src/data/rotations/pvp/priest/holy.json +6340 -0
  242. package/src/data/rotations/pvp/priest/shadow.json +2329 -0
  243. package/src/data/rotations/pvp/rogue/assassination.json +1322 -0
  244. package/src/data/rotations/pvp/rogue/combat.json +5258 -0
  245. package/src/data/rotations/pvp/rogue/subtlety.json +586 -0
  246. package/src/data/rotations/pvp/shaman/elemental.json +1404 -0
  247. package/src/data/rotations/pvp/shaman/enhancement.json +1277 -0
  248. package/src/data/rotations/pvp/shaman/restoration.json +2490 -0
  249. package/src/data/rotations/pvp/warlock/affliction.json +1017 -0
  250. package/src/data/rotations/pvp/warlock/demonology.json +1503 -0
  251. package/src/data/rotations/pvp/warlock/destruction.json +638 -0
  252. package/src/data/rotations/pvp/warrior/arms.json +5665 -0
  253. package/src/data/rotations/pvp/warrior/fury.json +850 -0
  254. package/src/data/rotations/pvp/warrior/protection.json +777 -0
  255. package/src/data/schema/bundle.ts +511 -0
  256. package/src/data/schema/constants.ts +49 -0
  257. package/src/data/schema/creature.ts +454 -0
  258. package/src/data/schema/encounter.ts +155 -0
  259. package/src/data/schema/faction.ts +48 -0
  260. package/src/data/schema/item.ts +297 -0
  261. package/src/data/schema/itemEnchant.ts +105 -0
  262. package/src/data/schema/npc.ts +44 -0
  263. package/src/data/schema/primitives.ts +295 -0
  264. package/src/data/schema/profession.ts +226 -0
  265. package/src/data/schema/quest.ts +154 -0
  266. package/src/data/schema/spell.ts +1149 -0
  267. package/src/data/schema/talent.ts +74 -0
  268. package/src/data/schema/world.ts +124 -0
  269. package/src/data/schema.ts +19 -0
  270. package/src/data/skinNodeGapFill.ts +68 -0
  271. package/src/data/spell-data.json.gz +0 -0
  272. package/src/data/spell-script-targets.json +1 -0
  273. package/src/data/tables/ahItemValues.json.gz +0 -0
  274. package/src/data/tables/alteracValley.json.gz +0 -0
  275. package/src/data/tables/areatriggerTeleports.json.gz +0 -0
  276. package/src/data/tables/botNames.json.gz +0 -0
  277. package/src/data/tables/botPopulation.json.gz +0 -0
  278. package/src/data/tables/botSpecs.json.gz +0 -0
  279. package/src/data/tables/classLevelStats.json.gz +0 -0
  280. package/src/data/tables/combatConditions.json.gz +0 -0
  281. package/src/data/tables/combatSkillMeta.json.gz +0 -0
  282. package/src/data/tables/conditions.json.gz +0 -0
  283. package/src/data/tables/createInfo.json.gz +0 -0
  284. package/src/data/tables/creatureAggroGroups.json.gz +0 -0
  285. package/src/data/tables/creatureClassLevelStats.json.gz +0 -0
  286. package/src/data/tables/creaturePatrolPacks.json.gz +0 -0
  287. package/src/data/tables/creatureWeapons.json.gz +0 -0
  288. package/src/data/tables/creatures.json.gz +0 -0
  289. package/src/data/tables/dbScripts.json.gz +0 -0
  290. package/src/data/tables/dungeonAuthoredRoutes.json.gz +0 -0
  291. package/src/data/tables/dungeonCensus.json.gz +0 -0
  292. package/src/data/tables/dungeonGameObjects.json.gz +0 -0
  293. package/src/data/tables/dungeonPacks.json.gz +0 -0
  294. package/src/data/tables/dungeonPlateCover.json.gz +0 -0
  295. package/src/data/tables/dungeonSpawns.json.gz +0 -0
  296. package/src/data/tables/dungeonSurvey.json.gz +0 -0
  297. package/src/data/tables/durabilityCosts.json.gz +0 -0
  298. package/src/data/tables/durabilityQuality.json.gz +0 -0
  299. package/src/data/tables/enchantApplicators.json.gz +0 -0
  300. package/src/data/tables/entranceYards.json.gz +0 -0
  301. package/src/data/tables/explorationBasexp.json.gz +0 -0
  302. package/src/data/tables/factionTemplates.json.gz +0 -0
  303. package/src/data/tables/factions.json.gz +0 -0
  304. package/src/data/tables/gameEvents.json.gz +0 -0
  305. package/src/data/tables/gameObjects.json.gz +0 -0
  306. package/src/data/tables/gossipMenus.json.gz +0 -0
  307. package/src/data/tables/graveyards.json.gz +0 -0
  308. package/src/data/tables/instanceMaps.json.gz +0 -0
  309. package/src/data/tables/itemEnchantmentTemplates.json.gz +0 -0
  310. package/src/data/tables/itemEnchants.json.gz +0 -0
  311. package/src/data/tables/itemRandomProperties.json.gz +0 -0
  312. package/src/data/tables/itemSets.json.gz +0 -0
  313. package/src/data/tables/items.json.gz +0 -0
  314. package/src/data/tables/levelStats.json.gz +0 -0
  315. package/src/data/tables/locks.json.gz +0 -0
  316. package/src/data/tables/map-pin-overrides.json.gz +0 -0
  317. package/src/data/tables/nonCombatTrash.json.gz +0 -0
  318. package/src/data/tables/npcTexts.json.gz +0 -0
  319. package/src/data/tables/pageTexts.json.gz +0 -0
  320. package/src/data/tables/petAbilityTP.json.gz +0 -0
  321. package/src/data/tables/petGenericSpells.json.gz +0 -0
  322. package/src/data/tables/petLevelStats.json.gz +0 -0
  323. package/src/data/tables/playerbot-weightscales.json.gz +0 -0
  324. package/src/data/tables/pools.json.gz +0 -0
  325. package/src/data/tables/quests.json.gz +0 -0
  326. package/src/data/tables/races.json.gz +0 -0
  327. package/src/data/tables/reputationRanks.json.gz +0 -0
  328. package/src/data/tables/reputationRates.json.gz +0 -0
  329. package/src/data/tables/reputationSpillover.json.gz +0 -0
  330. package/src/data/tables/ridingSpells.json.gz +0 -0
  331. package/src/data/tables/scriptTexts.json.gz +0 -0
  332. package/src/data/tables/soundClipVolume.json.gz +0 -0
  333. package/src/data/tables/spellChain.json.gz +0 -0
  334. package/src/data/tables/spellTeleports.json.gz +0 -0
  335. package/src/data/tables/spells.json.gz +0 -0
  336. package/src/data/tables/talents.json.gz +0 -0
  337. package/src/data/tables/tavernTriggers.json.gz +0 -0
  338. package/src/data/tables/taxiNodes.json.gz +0 -0
  339. package/src/data/tables/taxiRoutes.json.gz +0 -0
  340. package/src/data/tables/trainers.json.gz +0 -0
  341. package/src/data/tables/transports.json.gz +0 -0
  342. package/src/data/tables/travelAnchors.json.gz +0 -0
  343. package/src/data/tables/travelEdges.json.gz +0 -0
  344. package/src/data/tables/unitConditions.json.gz +0 -0
  345. package/src/data/tables/vendors.json.gz +0 -0
  346. package/src/data/tables/weaponEnchantProcs.json.gz +0 -0
  347. package/src/data/tables/xp.json.gz +0 -0
  348. package/src/data/tables/zoneWeather.json.gz +0 -0
  349. package/src/data/tables/zones.json.gz +0 -0
  350. package/src/data/world-data.ts +56 -0
  351. package/src/data/zone-music-sets.json +2751 -0
  352. package/src/dev/etl/lib/loot-chance-sanity.mjs +180 -0
  353. package/src/domain/audioQuality.mjs +145 -0
  354. package/src/domain/bg/ab.ts +433 -0
  355. package/src/domain/bg/arenaComps.ts +644 -0
  356. package/src/domain/bg/arenaLab.ts +695 -0
  357. package/src/domain/bg/arenaPace.ts +31 -0
  358. package/src/domain/bg/arenaRating.ts +110 -0
  359. package/src/domain/bg/av.ts +758 -0
  360. package/src/domain/bg/avEnemyPush.ts +219 -0
  361. package/src/domain/bg/avField.ts +283 -0
  362. package/src/domain/bg/avInstanceNodes.ts +197 -0
  363. package/src/domain/bg/avInstanceScore.ts +123 -0
  364. package/src/domain/bg/avQuestItems.ts +55 -0
  365. package/src/domain/bg/avQuests.ts +210 -0
  366. package/src/domain/bg/avSession.ts +196 -0
  367. package/src/domain/bg/bgConsumes.ts +269 -0
  368. package/src/domain/bg/bgPrebuff.ts +153 -0
  369. package/src/domain/bg/bgRest.ts +91 -0
  370. package/src/domain/bg/bgRoster.ts +305 -0
  371. package/src/domain/bg/bgTier.ts +61 -0
  372. package/src/domain/bg/bgWorld.ts +862 -0
  373. package/src/domain/bg/match.ts +215 -0
  374. package/src/domain/bg/strategies.ts +552 -0
  375. package/src/domain/bg/types.ts +291 -0
  376. package/src/domain/bg/wsg.ts +264 -0
  377. package/src/domain/bots/actionProviderSpec.ts +38 -0
  378. package/src/domain/bots/autoConsumables.ts +285 -0
  379. package/src/domain/bots/betweenPullRest.ts +239 -0
  380. package/src/domain/bots/botGear.ts +248 -0
  381. package/src/domain/bots/botInventory.ts +486 -0
  382. package/src/domain/bots/botPet.ts +535 -0
  383. package/src/domain/bots/botPool.ts +291 -0
  384. package/src/domain/bots/botProfessions.ts +334 -0
  385. package/src/domain/bots/companionActionBar.ts +209 -0
  386. package/src/domain/bots/companionHireCost.ts +236 -0
  387. package/src/domain/bots/companionMissions.ts +582 -0
  388. package/src/domain/bots/companionPrep.ts +254 -0
  389. package/src/domain/bots/companionQuests.ts +270 -0
  390. package/src/domain/bots/companionRep.ts +75 -0
  391. package/src/domain/bots/companionRotation.ts +708 -0
  392. package/src/domain/bots/companionXp.ts +66 -0
  393. package/src/domain/bots/consumableShare.ts +811 -0
  394. package/src/domain/bots/dpsMate.ts +1072 -0
  395. package/src/domain/bots/groupCompReport.ts +132 -0
  396. package/src/domain/bots/healthstoneSupply.ts +198 -0
  397. package/src/domain/bots/outfitter.ts +1056 -0
  398. package/src/domain/bots/paladinPrePull.ts +231 -0
  399. package/src/domain/bots/partyRole.ts +40 -0
  400. package/src/domain/bots/playerbotEquipCache.ts +412 -0
  401. package/src/domain/bots/playerbotItemEligibility.ts +60 -0
  402. package/src/domain/bots/playerbotStatWeight.ts +853 -0
  403. package/src/domain/bots/playerbotUnavailableItems.ts +147 -0
  404. package/src/domain/bots/prePullBuffs.ts +219 -0
  405. package/src/domain/bots/prePullStealth.ts +82 -0
  406. package/src/domain/bots/runSupply.ts +251 -0
  407. package/src/domain/bots/runSupplyPrefs.ts +28 -0
  408. package/src/domain/bots/sendTradeGoods.ts +394 -0
  409. package/src/domain/bots/soulShardCap.ts +35 -0
  410. package/src/domain/bots/squad.ts +842 -0
  411. package/src/domain/bots/squadRun.ts +81 -0
  412. package/src/domain/character/actionbar.ts +346 -0
  413. package/src/domain/character/appearance.ts +165 -0
  414. package/src/domain/character/buildCombatant.ts +1726 -0
  415. package/src/domain/character/character.ts +356 -0
  416. package/src/domain/character/characterName.ts +43 -0
  417. package/src/domain/character/characterRatings.ts +424 -0
  418. package/src/domain/character/characterSpells.ts +282 -0
  419. package/src/domain/character/characterStats.ts +1559 -0
  420. package/src/domain/character/characterTalents.ts +398 -0
  421. package/src/domain/character/combatSkills.ts +994 -0
  422. package/src/domain/character/displayForm.ts +72 -0
  423. package/src/domain/character/formTalentAuras.ts +171 -0
  424. package/src/domain/character/forms.ts +499 -0
  425. package/src/domain/character/races.ts +40 -0
  426. package/src/domain/character/resurrectionSickness.ts +49 -0
  427. package/src/domain/character/spellbook.ts +169 -0
  428. package/src/domain/character/stanceBar.ts +354 -0
  429. package/src/domain/character/stancePrereq.ts +70 -0
  430. package/src/domain/character/talentBuilds.ts +63 -0
  431. package/src/domain/character/talentImport.ts +130 -0
  432. package/src/domain/character/talentLink.ts +123 -0
  433. package/src/domain/character/talents.ts +201 -0
  434. package/src/domain/core/conditionSnapshot.ts +92 -0
  435. package/src/domain/core/hover.ts +14 -0
  436. package/src/domain/core/ids.ts +58 -0
  437. package/src/domain/core/internalNameTags.ts +5 -0
  438. package/src/domain/core/runtimeDataPatches.ts +357 -0
  439. package/src/domain/creature/aiTargeting.ts +588 -0
  440. package/src/domain/creature/combatCondition.ts +157 -0
  441. package/src/domain/creature/creatureAggro.ts +804 -0
  442. package/src/domain/creature/creatureAi.ts +206 -0
  443. package/src/domain/creature/creatureAiConstants.ts +661 -0
  444. package/src/domain/creature/creatureCastList.ts +1007 -0
  445. package/src/domain/creature/creatureEventAi.ts +1409 -0
  446. package/src/domain/creature/creatureGroups.ts +144 -0
  447. package/src/domain/creature/creatureLinking.ts +333 -0
  448. package/src/domain/creature/creatureScaling.ts +320 -0
  449. package/src/domain/creature/creatureTrigger.ts +53 -0
  450. package/src/domain/creature/creatureWander.ts +74 -0
  451. package/src/domain/creature/eventAiTexts.ts +145 -0
  452. package/src/domain/creature/faction.ts +287 -0
  453. package/src/domain/creature/forcedReaction.ts +48 -0
  454. package/src/domain/creature/outdoorHuntable.ts +74 -0
  455. package/src/domain/creature/patrolPacks.ts +210 -0
  456. package/src/domain/creature/reputation.ts +967 -0
  457. package/src/domain/creature/unitFlags.ts +74 -0
  458. package/src/domain/creature/worldBosses.ts +393 -0
  459. package/src/domain/dungeonMusic.mjs +48 -0
  460. package/src/domain/economy/auction.ts +282 -0
  461. package/src/domain/economy/auctionBot.ts +1060 -0
  462. package/src/domain/economy/honorPrice.ts +100 -0
  463. package/src/domain/economy/mail.ts +958 -0
  464. package/src/domain/economy/money.ts +42 -0
  465. package/src/domain/economy/syntheticClassTrainers.ts +62 -0
  466. package/src/domain/economy/trading.ts +296 -0
  467. package/src/domain/economy/vendorSellAll.ts +252 -0
  468. package/src/domain/economy/vendorStock.ts +146 -0
  469. package/src/domain/items/ammo.ts +817 -0
  470. package/src/domain/items/bank.ts +162 -0
  471. package/src/domain/items/consumableFamily.ts +205 -0
  472. package/src/domain/items/craftUpgrades.ts +83 -0
  473. package/src/domain/items/createItem.ts +93 -0
  474. package/src/domain/items/durability.ts +581 -0
  475. package/src/domain/items/equipment.ts +441 -0
  476. package/src/domain/items/equipmentHelper.ts +767 -0
  477. package/src/domain/items/inventory.ts +561 -0
  478. package/src/domain/items/itemBonding.ts +93 -0
  479. package/src/domain/items/itemContainer.ts +245 -0
  480. package/src/domain/items/itemDisplayName.ts +33 -0
  481. package/src/domain/items/itemInstance.ts +181 -0
  482. package/src/domain/items/itemRandomEnchantOutcomes.ts +315 -0
  483. package/src/domain/items/itemRandomProps.ts +77 -0
  484. package/src/domain/items/itemRestrictions.ts +329 -0
  485. package/src/domain/items/itemTeaches.ts +82 -0
  486. package/src/domain/items/itemUseCooldown.ts +52 -0
  487. package/src/domain/items/itemUseTarget.ts +90 -0
  488. package/src/domain/items/junkCategories.ts +174 -0
  489. package/src/domain/items/junkFilter.ts +368 -0
  490. package/src/domain/items/keyring.ts +131 -0
  491. package/src/domain/items/loot.ts +221 -0
  492. package/src/domain/items/mounts.ts +190 -0
  493. package/src/domain/items/onUsePayload.ts +102 -0
  494. package/src/domain/items/pendingLoot.ts +107 -0
  495. package/src/domain/items/relic.ts +105 -0
  496. package/src/domain/items/rocketBoots.ts +36 -0
  497. package/src/domain/items/sortContainer.ts +139 -0
  498. package/src/domain/items/spareContainers.ts +71 -0
  499. package/src/domain/items/spellReagentIndex.ts +131 -0
  500. package/src/domain/items/staleConsumables.ts +66 -0
  501. package/src/domain/items/weaponSpender.ts +110 -0
  502. package/src/domain/listDungeonIds.mjs +28 -0
  503. package/src/domain/macro/compose.ts +239 -0
  504. package/src/domain/macro/conditions.ts +260 -0
  505. package/src/domain/macro/creatureTypes.ts +40 -0
  506. package/src/domain/macro/describe.ts +169 -0
  507. package/src/domain/macro/icon.ts +60 -0
  508. package/src/domain/macro/index.ts +20 -0
  509. package/src/domain/macro/normalize.ts +112 -0
  510. package/src/domain/macro/parse.ts +316 -0
  511. package/src/domain/macro/plan.ts +288 -0
  512. package/src/domain/macro/rotation.ts +590 -0
  513. package/src/domain/macro/rotationEnv.ts +173 -0
  514. package/src/domain/macro/slots.ts +101 -0
  515. package/src/domain/macro/snapshot.ts +114 -0
  516. package/src/domain/macro/templates.ts +446 -0
  517. package/src/domain/macro/types.ts +70 -0
  518. package/src/domain/macro/units.ts +93 -0
  519. package/src/domain/macro/weaponTypes.ts +83 -0
  520. package/src/domain/nav/cityTeleports.ts +10 -0
  521. package/src/domain/nav/mounting.ts +113 -0
  522. package/src/domain/nav/nav.ts +43 -0
  523. package/src/domain/nav/navCollision.ts +606 -0
  524. package/src/domain/nav/navOutdoors.ts +91 -0
  525. package/src/domain/nav/navRegistry.ts +179 -0
  526. package/src/domain/nav/navRoomGraph.ts +302 -0
  527. package/src/domain/nav/navTypes.ts +43 -0
  528. package/src/domain/nav/navmesh.ts +1715 -0
  529. package/src/domain/nav/speed.ts +200 -0
  530. package/src/domain/nav/storey.ts +10 -0
  531. package/src/domain/nav/travel.ts +725 -0
  532. package/src/domain/nav/travelTypes.ts +75 -0
  533. package/src/domain/pet/pet.ts +1150 -0
  534. package/src/domain/pet/petActionBar.ts +180 -0
  535. package/src/domain/pet/petSpellbook.ts +39 -0
  536. package/src/domain/pet/petStable.ts +81 -0
  537. package/src/domain/professions/autoDisenchant.ts +236 -0
  538. package/src/domain/professions/characterEnchants.ts +176 -0
  539. package/src/domain/professions/craftCooldown.ts +52 -0
  540. package/src/domain/professions/enchantApply.ts +62 -0
  541. package/src/domain/professions/enchantTargets.ts +114 -0
  542. package/src/domain/professions/enchanting.ts +236 -0
  543. package/src/domain/professions/gatherFilter.ts +149 -0
  544. package/src/domain/professions/gearEnchant.ts +137 -0
  545. package/src/domain/professions/heldTools.ts +29 -0
  546. package/src/domain/professions/learnAllRecipes.ts +146 -0
  547. package/src/domain/professions/miningHarvest.ts +69 -0
  548. package/src/domain/professions/partyDisenchant.ts +294 -0
  549. package/src/domain/professions/partyWork.ts +83 -0
  550. package/src/domain/professions/pickpocket.ts +172 -0
  551. package/src/domain/professions/poisons.ts +240 -0
  552. package/src/domain/professions/professions.ts +677 -0
  553. package/src/domain/professions/rareNodes.ts +45 -0
  554. package/src/domain/professions/skinLoot.ts +27 -0
  555. package/src/domain/professions/vendorReagents.ts +152 -0
  556. package/src/domain/professions/weaponImbueHand.ts +171 -0
  557. package/src/domain/questFarmFilter.mjs +42 -0
  558. package/src/domain/quests/doQuest.ts +1204 -0
  559. package/src/domain/quests/gossip.ts +308 -0
  560. package/src/domain/quests/gossipTalk.ts +298 -0
  561. package/src/domain/quests/interpreter/canComplete.ts +150 -0
  562. package/src/domain/quests/interpreter/claim.ts +137 -0
  563. package/src/domain/quests/interpreter/dbscript/handlers.ts +1371 -0
  564. package/src/domain/quests/interpreter/dbscript/handlersBatch.ts +1251 -0
  565. package/src/domain/quests/interpreter/dbscript/hooks.ts +331 -0
  566. package/src/domain/quests/interpreter/dbscript/index.ts +212 -0
  567. package/src/domain/quests/interpreter/dbscript/opcodes.ts +257 -0
  568. package/src/domain/quests/interpreter/dbscript/registry.ts +1194 -0
  569. package/src/domain/quests/interpreter/dbscript/registryAreatriggerScripts.ts +539 -0
  570. package/src/domain/quests/interpreter/dbscript/registryAshenvale.ts +553 -0
  571. package/src/domain/quests/interpreter/dbscript/registryAzshara.ts +272 -0
  572. package/src/domain/quests/interpreter/dbscript/registryDarkshore.ts +637 -0
  573. package/src/domain/quests/interpreter/dbscript/registryDesolace.ts +501 -0
  574. package/src/domain/quests/interpreter/dbscript/registryDustwallowMarsh.ts +735 -0
  575. package/src/domain/quests/interpreter/dbscript/registryFelwood.ts +493 -0
  576. package/src/domain/quests/interpreter/dbscript/registryFeralas.ts +485 -0
  577. package/src/domain/quests/interpreter/dbscript/registryGoScripts.ts +203 -0
  578. package/src/domain/quests/interpreter/dbscript/registryMoonglade.ts +288 -0
  579. package/src/domain/quests/interpreter/dbscript/registryNpcProfessions.ts +230 -0
  580. package/src/domain/quests/interpreter/dbscript/registryNpcsSpecial.ts +545 -0
  581. package/src/domain/quests/interpreter/dbscript/registryRazorfenDowns.ts +293 -0
  582. package/src/domain/quests/interpreter/dbscript/registryRazorfenKraul.ts +221 -0
  583. package/src/domain/quests/interpreter/dbscript/registryRedridge.ts +112 -0
  584. package/src/domain/quests/interpreter/dbscript/registrySearingGorge.ts +125 -0
  585. package/src/domain/quests/interpreter/dbscript/registrySiblings.ts +51 -0
  586. package/src/domain/quests/interpreter/dbscript/registrySilverpineForest.ts +172 -0
  587. package/src/domain/quests/interpreter/dbscript/registryStonetalonMountains.ts +180 -0
  588. package/src/domain/quests/interpreter/dbscript/registryStormwindCity.ts +369 -0
  589. package/src/domain/quests/interpreter/dbscript/registryStranglethornVale.ts +115 -0
  590. package/src/domain/quests/interpreter/dbscript/registryStratholme.ts +146 -0
  591. package/src/domain/quests/interpreter/dbscript/registrySunkenTemple.ts +149 -0
  592. package/src/domain/quests/interpreter/dbscript/registrySwampOfSorrows.ts +163 -0
  593. package/src/domain/quests/interpreter/dbscript/registryTanaris.ts +318 -0
  594. package/src/domain/quests/interpreter/dbscript/registryTeldrassil.ts +120 -0
  595. package/src/domain/quests/interpreter/dbscript/registryTheBarrens.ts +603 -0
  596. package/src/domain/quests/interpreter/dbscript/registryThousandNeedles.ts +499 -0
  597. package/src/domain/quests/interpreter/dbscript/registryTirisfalGlades.ts +222 -0
  598. package/src/domain/quests/interpreter/dbscript/registryUngoroCrater.ts +291 -0
  599. package/src/domain/quests/interpreter/dbscript/registryWarEffort.ts +773 -0
  600. package/src/domain/quests/interpreter/dbscript/registryWesternPlaguelands.ts +206 -0
  601. package/src/domain/quests/interpreter/dbscript/registryWestfall.ts +190 -0
  602. package/src/domain/quests/interpreter/dbscript/registryWetlands.ts +186 -0
  603. package/src/domain/quests/interpreter/dbscript/registryWinterspring.ts +235 -0
  604. package/src/domain/quests/interpreter/dbscript/types.ts +817 -0
  605. package/src/domain/quests/interpreter/dbscript/vm.ts +171 -0
  606. package/src/domain/quests/interpreter/diff.ts +349 -0
  607. package/src/domain/quests/interpreter/fixtures/oracle-questlog-qi2.json +2417 -0
  608. package/src/domain/quests/interpreter/flags.ts +101 -0
  609. package/src/domain/quests/interpreter/index.ts +113 -0
  610. package/src/domain/quests/interpreter/live.ts +178 -0
  611. package/src/domain/quests/interpreter/types.ts +81 -0
  612. package/src/domain/quests/interpreter/updaters.ts +412 -0
  613. package/src/domain/quests/questCorpseUse.ts +155 -0
  614. package/src/domain/quests/questDialog.ts +43 -0
  615. package/src/domain/quests/questFight.ts +34 -0
  616. package/src/domain/quests/questObjectiveLabel.ts +39 -0
  617. package/src/domain/quests/questRewardChoice.ts +85 -0
  618. package/src/domain/quests/questScriptCredit.ts +26 -0
  619. package/src/domain/quests/questScriptItemUse.ts +74 -0
  620. package/src/domain/quests/questTameRods.ts +79 -0
  621. package/src/domain/quests/questlog.ts +1545 -0
  622. package/src/domain/quests/talkDeliver.ts +170 -0
  623. package/src/domain/raid/globalActionBar.ts +195 -0
  624. package/src/domain/raid/instanceRoster.ts +194 -0
  625. package/src/domain/raid/partySummon.ts +198 -0
  626. package/src/domain/raid/partyVault.ts +320 -0
  627. package/src/domain/raid/raidBossAbilities.ts +268 -0
  628. package/src/domain/raid/raidComp.ts +335 -0
  629. package/src/domain/raid/raidCustomRows.ts +453 -0
  630. package/src/domain/raid/raidEncounterGear.ts +298 -0
  631. package/src/domain/raid/raidEncounterTactics.ts +412 -0
  632. package/src/domain/raid/raidPlan.ts +509 -0
  633. package/src/domain/raid/raidPlanEdits.ts +98 -0
  634. package/src/domain/raid/raidPlanPacks.ts +480 -0
  635. package/src/domain/raid/raidRecovery.ts +183 -0
  636. package/src/domain/raid/raidRosterTemplate.ts +138 -0
  637. package/src/domain/rotation/auraSide.ts +68 -0
  638. package/src/domain/rotation/build.ts +3031 -0
  639. package/src/domain/rotation/classes/druid.ts +58 -0
  640. package/src/domain/rotation/classes/hooks.ts +59 -0
  641. package/src/domain/rotation/classes/hunter.ts +156 -0
  642. package/src/domain/rotation/classes/index.ts +104 -0
  643. package/src/domain/rotation/classes/mage.ts +99 -0
  644. package/src/domain/rotation/classes/paladin.ts +296 -0
  645. package/src/domain/rotation/classes/priest.ts +94 -0
  646. package/src/domain/rotation/classes/pullOpener.ts +92 -0
  647. package/src/domain/rotation/classes/rogue.ts +69 -0
  648. package/src/domain/rotation/classes/shaman.ts +29 -0
  649. package/src/domain/rotation/classes/supportSpec.ts +94 -0
  650. package/src/domain/rotation/classes/warlock.ts +81 -0
  651. package/src/domain/rotation/classes/warrior.ts +402 -0
  652. package/src/domain/rotation/classify.ts +1381 -0
  653. package/src/domain/rotation/condMetricPicker.ts +379 -0
  654. package/src/domain/rotation/consumables.ts +242 -0
  655. package/src/domain/rotation/evaluate.ts +1115 -0
  656. package/src/domain/rotation/finisherLadder.ts +145 -0
  657. package/src/domain/rotation/invent.ts +938 -0
  658. package/src/domain/rotation/killOrder.ts +30 -0
  659. package/src/domain/rotation/openerForm.ts +22 -0
  660. package/src/domain/rotation/paladinBuffs.ts +568 -0
  661. package/src/domain/rotation/prebuff.ts +283 -0
  662. package/src/domain/rotation/raidRowTuning.ts +34 -0
  663. package/src/domain/rotation/rotation.ts +11 -0
  664. package/src/domain/rotation/rotationProfiles.ts +180 -0
  665. package/src/domain/rotation/rotationSuggestions.ts +851 -0
  666. package/src/domain/rotation/ruleAfterChain.ts +49 -0
  667. package/src/domain/rotation/spec.ts +70 -0
  668. package/src/domain/rotation/spellPicker.ts +140 -0
  669. package/src/domain/rotation/stand.ts +143 -0
  670. package/src/domain/rotation/types.ts +718 -0
  671. package/src/domain/run/battlegroundRun.ts +111 -0
  672. package/src/domain/run/canEnterContext.ts +32 -0
  673. package/src/domain/run/death.ts +561 -0
  674. package/src/domain/run/deathRecovery.ts +289 -0
  675. package/src/domain/run/duel.ts +141 -0
  676. package/src/domain/run/dungeonRun.ts +344 -0
  677. package/src/domain/run/floorRest.ts +159 -0
  678. package/src/domain/run/honor.ts +557 -0
  679. package/src/domain/run/honorWeek.ts +180 -0
  680. package/src/domain/run/whenMap.ts +977 -0
  681. package/src/domain/scriptdev/arathiHighlands.ts +445 -0
  682. package/src/domain/scriptdev/ashenvale.ts +635 -0
  683. package/src/domain/scriptdev/ashenvaleHelpers.ts +1215 -0
  684. package/src/domain/scriptdev/azshara.ts +892 -0
  685. package/src/domain/scriptdev/blackfathomDeeps.ts +212 -0
  686. package/src/domain/scriptdev/blackrockDepths.ts +1434 -0
  687. package/src/domain/scriptdev/blackrockSpire.ts +730 -0
  688. package/src/domain/scriptdev/blackwingLair.ts +521 -0
  689. package/src/domain/scriptdev/burningSteppes.ts +62 -0
  690. package/src/domain/scriptdev/classFilter.ts +43 -0
  691. package/src/domain/scriptdev/darkshore.ts +817 -0
  692. package/src/domain/scriptdev/darkshoreHelpers.ts +853 -0
  693. package/src/domain/scriptdev/deadmines.ts +331 -0
  694. package/src/domain/scriptdev/desolace.ts +1239 -0
  695. package/src/domain/scriptdev/direMaul.ts +859 -0
  696. package/src/domain/scriptdev/durotar.ts +532 -0
  697. package/src/domain/scriptdev/dustwallowMarsh.ts +758 -0
  698. package/src/domain/scriptdev/dustwallowMarshHelpers.ts +994 -0
  699. package/src/domain/scriptdev/easternPlaguelands.ts +21 -0
  700. package/src/domain/scriptdev/felwood.ts +1055 -0
  701. package/src/domain/scriptdev/feralas.ts +571 -0
  702. package/src/domain/scriptdev/feralasHelpers.ts +838 -0
  703. package/src/domain/scriptdev/gnomeregan.ts +466 -0
  704. package/src/domain/scriptdev/guards.ts +616 -0
  705. package/src/domain/scriptdev/hinterlands.ts +693 -0
  706. package/src/domain/scriptdev/host.ts +1134 -0
  707. package/src/domain/scriptdev/index.ts +123 -0
  708. package/src/domain/scriptdev/instanceRaids.ts +136 -0
  709. package/src/domain/scriptdev/itemScripts.ts +37 -0
  710. package/src/domain/scriptdev/lochModan.ts +283 -0
  711. package/src/domain/scriptdev/maraudon.ts +232 -0
  712. package/src/domain/scriptdev/moltenCore.ts +831 -0
  713. package/src/domain/scriptdev/moonglade.ts +659 -0
  714. package/src/domain/scriptdev/moongladeHelpers.ts +933 -0
  715. package/src/domain/scriptdev/naxxramas.ts +577 -0
  716. package/src/domain/scriptdev/naxxramasConstruct.ts +364 -0
  717. package/src/domain/scriptdev/naxxramasFrostwyrm.ts +378 -0
  718. package/src/domain/scriptdev/naxxramasMilitary.ts +276 -0
  719. package/src/domain/scriptdev/npcProfessions.ts +1025 -0
  720. package/src/domain/scriptdev/npcsSpecial.ts +1379 -0
  721. package/src/domain/scriptdev/onyxiasLair.ts +313 -0
  722. package/src/domain/scriptdev/orgrimmar.ts +147 -0
  723. package/src/domain/scriptdev/professionSpecConsumer.ts +481 -0
  724. package/src/domain/scriptdev/razorfenDowns.ts +468 -0
  725. package/src/domain/scriptdev/razorfenKraul.ts +410 -0
  726. package/src/domain/scriptdev/redridgeMountains.ts +163 -0
  727. package/src/domain/scriptdev/registry.ts +945 -0
  728. package/src/domain/scriptdev/ruinsOfAhnqiraj.ts +356 -0
  729. package/src/domain/scriptdev/scarletMonastery.ts +713 -0
  730. package/src/domain/scriptdev/scholomance.ts +682 -0
  731. package/src/domain/scriptdev/searingGorge.ts +295 -0
  732. package/src/domain/scriptdev/shadowfangKeep.ts +181 -0
  733. package/src/domain/scriptdev/silithus.ts +71 -0
  734. package/src/domain/scriptdev/silverpineForest.ts +662 -0
  735. package/src/domain/scriptdev/stonetalonMountains.ts +493 -0
  736. package/src/domain/scriptdev/stormwindCity.ts +1192 -0
  737. package/src/domain/scriptdev/stranglethornVale.ts +402 -0
  738. package/src/domain/scriptdev/stratholme.ts +650 -0
  739. package/src/domain/scriptdev/stratholmeScripts.ts +505 -0
  740. package/src/domain/scriptdev/sunkenTemple.ts +736 -0
  741. package/src/domain/scriptdev/swampOfSorrows.ts +22 -0
  742. package/src/domain/scriptdev/tanaris.ts +391 -0
  743. package/src/domain/scriptdev/tanarisHelpers.ts +661 -0
  744. package/src/domain/scriptdev/teldrassil.ts +143 -0
  745. package/src/domain/scriptdev/templeOfAhnqiraj.ts +1013 -0
  746. package/src/domain/scriptdev/theBarrens.ts +709 -0
  747. package/src/domain/scriptdev/theBarrensHelpers.ts +1026 -0
  748. package/src/domain/scriptdev/thousandNeedles.ts +426 -0
  749. package/src/domain/scriptdev/thousandNeedlesHelpers.ts +566 -0
  750. package/src/domain/scriptdev/tirisfalGlades.ts +533 -0
  751. package/src/domain/scriptdev/types.ts +1026 -0
  752. package/src/domain/scriptdev/uldaman.ts +437 -0
  753. package/src/domain/scriptdev/ungoroCrater.ts +549 -0
  754. package/src/domain/scriptdev/ungoroCraterHelpers.ts +1006 -0
  755. package/src/domain/scriptdev/wailingCaverns.ts +700 -0
  756. package/src/domain/scriptdev/warEffort.ts +371 -0
  757. package/src/domain/scriptdev/westernPlaguelands.ts +952 -0
  758. package/src/domain/scriptdev/westfall.ts +767 -0
  759. package/src/domain/scriptdev/wetlands.ts +660 -0
  760. package/src/domain/scriptdev/winterspring.ts +482 -0
  761. package/src/domain/scriptdev/winterspringHelpers.ts +801 -0
  762. package/src/domain/scriptdev/worldBosses.ts +605 -0
  763. package/src/domain/scriptdev/zulfarrak.ts +478 -0
  764. package/src/domain/scriptdev/zulgurub.ts +1152 -0
  765. package/src/domain/sim/dummySim.ts +408 -0
  766. package/src/domain/sim/targetDummy.ts +29 -0
  767. package/src/domain/social/guild.ts +148 -0
  768. package/src/domain/spells/areaAuraMembership.ts +93 -0
  769. package/src/domain/spells/breakableStunCc.ts +166 -0
  770. package/src/domain/spells/cancelAura.ts +80 -0
  771. package/src/domain/spells/diminishing.ts +167 -0
  772. package/src/domain/spells/dispel.ts +149 -0
  773. package/src/domain/spells/dispelMechanic.ts +105 -0
  774. package/src/domain/spells/equipSpells.ts +247 -0
  775. package/src/domain/spells/learnOnTargets.ts +260 -0
  776. package/src/domain/spells/mergeSchoolImmunityFromRaw.ts +66 -0
  777. package/src/domain/spells/resurrectSpell.ts +124 -0
  778. package/src/domain/spells/spellPushback.ts +39 -0
  779. package/src/domain/spells/spellReflect.ts +43 -0
  780. package/src/domain/spells/stealth.ts +183 -0
  781. package/src/domain/spells/totem.ts +394 -0
  782. package/src/domain/spells/worldCast.ts +187 -0
  783. package/src/domain/world/areaTriggerLocks.ts +177 -0
  784. package/src/domain/world/dungeonMusic.ts +108 -0
  785. package/src/domain/world/gameEvents.ts +119 -0
  786. package/src/domain/world/gameObjects.ts +1030 -0
  787. package/src/domain/world/goEventFire.ts +234 -0
  788. package/src/domain/world/goMoTransport.ts +74 -0
  789. package/src/domain/world/goTransport.ts +81 -0
  790. package/src/domain/world/hazards.ts +459 -0
  791. package/src/domain/world/openLock.ts +398 -0
  792. package/src/domain/world/pools.ts +470 -0
  793. package/src/domain/world/restArea.ts +37 -0
  794. package/src/domain/world/weather.ts +201 -0
  795. package/src/domain/zoneAmbience.mjs +87 -0
  796. package/src/domain/zoneMusic.mjs +62 -0
  797. package/src/domain/zoneMusicQueue.mjs +7 -0
  798. package/src/engine/combat/activeSeal.ts +39 -0
  799. package/src/engine/combat/aiTargetResolve.ts +64 -0
  800. package/src/engine/combat/aoeCast.ts +289 -0
  801. package/src/engine/combat/applyConsumeAura.ts +74 -0
  802. package/src/engine/combat/applyDemonicSacrifice.ts +70 -0
  803. package/src/engine/combat/applyDispelMechanic.ts +30 -0
  804. package/src/engine/combat/applyHealEffect.ts +301 -0
  805. package/src/engine/combat/applySchoolAbsorb.ts +114 -0
  806. package/src/engine/combat/applySpell.ts +3169 -0
  807. package/src/engine/combat/applySpellLate.ts +2026 -0
  808. package/src/engine/combat/applySpellLateBag.ts +144 -0
  809. package/src/engine/combat/areaAura.ts +283 -0
  810. package/src/engine/combat/attackTable.ts +508 -0
  811. package/src/engine/combat/battleRez.ts +87 -0
  812. package/src/engine/combat/castAction.ts +36 -0
  813. package/src/engine/combat/castTargetGates.ts +75 -0
  814. package/src/engine/combat/castableKit.ts +68 -0
  815. package/src/engine/combat/ccMirrorUpgrade.ts +39 -0
  816. package/src/engine/combat/chainFan.ts +210 -0
  817. package/src/engine/combat/channel.ts +423 -0
  818. package/src/engine/combat/chaseCloseness.ts +95 -0
  819. package/src/engine/combat/cmangosCastGates.ts +129 -0
  820. package/src/engine/combat/combatFlag.ts +77 -0
  821. package/src/engine/combat/combatGeometry.ts +1329 -0
  822. package/src/engine/combat/combustion.ts +68 -0
  823. package/src/engine/combat/context.ts +730 -0
  824. package/src/engine/combat/createSession.ts +1165 -0
  825. package/src/engine/combat/creatureLeash.ts +38 -0
  826. package/src/engine/combat/crowdControl.ts +1259 -0
  827. package/src/engine/combat/dispelDuty.ts +54 -0
  828. package/src/engine/combat/dispelReflect.ts +609 -0
  829. package/src/engine/combat/displaceFloor.ts +113 -0
  830. package/src/engine/combat/duelBounds.ts +47 -0
  831. package/src/engine/combat/equippedItemGate.ts +297 -0
  832. package/src/engine/combat/evadeLifecycle.ts +63 -0
  833. package/src/engine/combat/eventAi.ts +2220 -0
  834. package/src/engine/combat/facing.ts +74 -0
  835. package/src/engine/combat/fearFlee.ts +137 -0
  836. package/src/engine/combat/fighterFactory.ts +1144 -0
  837. package/src/engine/combat/forceDespawnAction.ts +51 -0
  838. package/src/engine/combat/formulas.ts +807 -0
  839. package/src/engine/combat/friendlyFan.ts +55 -0
  840. package/src/engine/combat/groundPoolTick.ts +210 -0
  841. package/src/engine/combat/hazards.ts +114 -0
  842. package/src/engine/combat/healTargets.ts +226 -0
  843. package/src/engine/combat/heartbeatResist.ts +49 -0
  844. package/src/engine/combat/hostileItemUse.ts +75 -0
  845. package/src/engine/combat/interruptAuras.ts +66 -0
  846. package/src/engine/combat/itemRescue.ts +49 -0
  847. package/src/engine/combat/itemUse.ts +260 -0
  848. package/src/engine/combat/kitById.ts +23 -0
  849. package/src/engine/combat/knockBack.ts +201 -0
  850. package/src/engine/combat/leap.ts +89 -0
  851. package/src/engine/combat/mitigation.ts +587 -0
  852. package/src/engine/combat/modTaunt.ts +43 -0
  853. package/src/engine/combat/motionClaim.ts +268 -0
  854. package/src/engine/combat/motionGate.ts +150 -0
  855. package/src/engine/combat/motionGenerator.ts +27 -0
  856. package/src/engine/combat/navSight.ts +138 -0
  857. package/src/engine/combat/perfSink.ts +28 -0
  858. package/src/engine/combat/periodicDue.ts +55 -0
  859. package/src/engine/combat/petAuras.ts +86 -0
  860. package/src/engine/combat/pickAction.ts +3449 -0
  861. package/src/engine/combat/powerForm.ts +735 -0
  862. package/src/engine/combat/powerPools.ts +49 -0
  863. package/src/engine/combat/predicates.ts +538 -0
  864. package/src/engine/combat/procsDamage.ts +1823 -0
  865. package/src/engine/combat/reactiveGates.ts +135 -0
  866. package/src/engine/combat/roles.ts +389 -0
  867. package/src/engine/combat/rotationSubject.ts +78 -0
  868. package/src/engine/combat/ruleAfter.ts +106 -0
  869. package/src/engine/combat/seedDisplayAuras.ts +203 -0
  870. package/src/engine/combat/seedOocEffects.ts +317 -0
  871. package/src/engine/combat/seedSchoolImmunities.ts +45 -0
  872. package/src/engine/combat/session-types.ts +458 -0
  873. package/src/engine/combat/sessionApi.ts +1785 -0
  874. package/src/engine/combat/sessionCharge.ts +124 -0
  875. package/src/engine/combat/sessionChase.ts +869 -0
  876. package/src/engine/combat/sessionDeaths.ts +469 -0
  877. package/src/engine/combat/sessionFocus.ts +506 -0
  878. package/src/engine/combat/sessionFollow.ts +167 -0
  879. package/src/engine/combat/sessionGeometry.ts +188 -0
  880. package/src/engine/combat/sessionHome.ts +75 -0
  881. package/src/engine/combat/sessionInject.ts +719 -0
  882. package/src/engine/combat/sessionMechanicMove.ts +555 -0
  883. package/src/engine/combat/sessionMotion.ts +1553 -0
  884. package/src/engine/combat/sessionMotionKit.ts +247 -0
  885. package/src/engine/combat/sessionMoveIntent.ts +49 -0
  886. package/src/engine/combat/sessionMoveOrder.ts +200 -0
  887. package/src/engine/combat/sessionPathTo.ts +657 -0
  888. package/src/engine/combat/sessionPools.ts +688 -0
  889. package/src/engine/combat/sessionSteer.ts +144 -0
  890. package/src/engine/combat/sessionStepBack.ts +151 -0
  891. package/src/engine/combat/sessionStepWrap.ts +116 -0
  892. package/src/engine/combat/sessionView.ts +442 -0
  893. package/src/engine/combat/simEffects.ts +32 -0
  894. package/src/engine/combat/simFacade.ts +620 -0
  895. package/src/engine/combat/simPump.ts +264 -0
  896. package/src/engine/combat/simSnapshot.ts +165 -0
  897. package/src/engine/combat/simThreadPool.ts +35 -0
  898. package/src/engine/combat/skeramImages.ts +57 -0
  899. package/src/engine/combat/slowUpdate.ts +178 -0
  900. package/src/engine/combat/snapToFloor.ts +42 -0
  901. package/src/engine/combat/speedAura.ts +29 -0
  902. package/src/engine/combat/spellReagents.ts +71 -0
  903. package/src/engine/combat/stealthDetect.ts +93 -0
  904. package/src/engine/combat/stepBackMotion.ts +171 -0
  905. package/src/engine/combat/stepSession.ts +3102 -0
  906. package/src/engine/combat/summonCast.ts +243 -0
  907. package/src/engine/combat/thaddiusPolarity.ts +97 -0
  908. package/src/engine/combat/threat.ts +388 -0
  909. package/src/engine/combat/threatOps.ts +272 -0
  910. package/src/engine/combat/tickWorkerBody.ts +211 -0
  911. package/src/engine/combat/totemAuras.ts +122 -0
  912. package/src/engine/combat/triggerPayload.ts +42 -0
  913. package/src/engine/combat/triggeredCompanion.ts +63 -0
  914. package/src/engine/combat/types.ts +1897 -0
  915. package/src/engine/combat/useObjectTrap.ts +140 -0
  916. package/src/engine/combat/walkSurface.ts +54 -0
  917. package/src/engine/combat/weapon.ts +1248 -0
  918. package/src/engine/combat/worldFrame.ts +43 -0
  919. package/src/engine/combat.solo-golden.json +2242 -0
  920. package/src/engine/combat.ts +84 -0
  921. package/src/engine/core/detMath.ts +289 -0
  922. package/src/engine/core/events.ts +357 -0
  923. package/src/engine/core/rng.ts +36 -0
  924. package/src/engine/game/actionBars.ts +124 -0
  925. package/src/engine/game/activateObjectFromSpell.ts +320 -0
  926. package/src/engine/game/applyActiveObjectFromDbScript.ts +98 -0
  927. package/src/engine/game/applyDeathAndSpellScripts.ts +268 -0
  928. package/src/engine/game/applyDoorFromDbScript.ts +388 -0
  929. package/src/engine/game/applyEscortFromDbScript.ts +290 -0
  930. package/src/engine/game/applyGoSpellcasterCast.ts +40 -0
  931. package/src/engine/game/applyHoverFromDbScript.ts +110 -0
  932. package/src/engine/game/applyOocResurrect.ts +71 -0
  933. package/src/engine/game/applySpellDurability.ts +115 -0
  934. package/src/engine/game/applyTailFromDbScript.ts +478 -0
  935. package/src/engine/game/applyTerminateFromDbScript.ts +95 -0
  936. package/src/engine/game/auctionMail.ts +269 -0
  937. package/src/engine/game/bagOverflow.ts +130 -0
  938. package/src/engine/game/bank.ts +110 -0
  939. package/src/engine/game/barAutofill.ts +26 -0
  940. package/src/engine/game/battleground.ts +369 -0
  941. package/src/engine/game/combatEnemySpec.ts +216 -0
  942. package/src/engine/game/combatObjectTraps.ts +167 -0
  943. package/src/engine/game/combatSeed.ts +320 -0
  944. package/src/engine/game/combatSession.ts +3241 -0
  945. package/src/engine/game/combatSessionClock.ts +62 -0
  946. package/src/engine/game/companionQuestActions.ts +242 -0
  947. package/src/engine/game/companionTraining.ts +40 -0
  948. package/src/engine/game/consumables.ts +624 -0
  949. package/src/engine/game/context.ts +53 -0
  950. package/src/engine/game/createHealthstone.ts +45 -0
  951. package/src/engine/game/deathFlow.ts +127 -0
  952. package/src/engine/game/devGrant.ts +117 -0
  953. package/src/engine/game/dynamicObject.ts +365 -0
  954. package/src/engine/game/enchantItem.ts +177 -0
  955. package/src/engine/game/equipmentHelper.ts +806 -0
  956. package/src/engine/game/factionState.ts +108 -0
  957. package/src/engine/game/garmentsOoc.ts +69 -0
  958. package/src/engine/game/globalActionBar.ts +179 -0
  959. package/src/engine/game/goInteractQuestCredit.ts +51 -0
  960. package/src/engine/game/goMoTransportUse.ts +61 -0
  961. package/src/engine/game/goTransportUse.ts +60 -0
  962. package/src/engine/game/healthstoneUpkeep.ts +59 -0
  963. package/src/engine/game/killSkin.ts +124 -0
  964. package/src/engine/game/learnFromItem.ts +118 -0
  965. package/src/engine/game/loadReconcile.ts +551 -0
  966. package/src/engine/game/loot.ts +294 -0
  967. package/src/engine/game/macros.ts +125 -0
  968. package/src/engine/game/mail.ts +293 -0
  969. package/src/engine/game/meetingStoneQueue.ts +75 -0
  970. package/src/engine/game/meetingStoneUse.ts +54 -0
  971. package/src/engine/game/newGameState.ts +363 -0
  972. package/src/engine/game/oocAuraInterrupt.ts +92 -0
  973. package/src/engine/game/oocCast.ts +241 -0
  974. package/src/engine/game/oocCastEffects.ts +803 -0
  975. package/src/engine/game/oocCastMethods.ts +1077 -0
  976. package/src/engine/game/openLockFromSpell.ts +174 -0
  977. package/src/engine/game/outdoorPvp.ts +187 -0
  978. package/src/engine/game/outfitter.ts +644 -0
  979. package/src/engine/game/paladinBoard.ts +393 -0
  980. package/src/engine/game/partyAuras.ts +121 -0
  981. package/src/engine/game/persistCombatAuras.ts +91 -0
  982. package/src/engine/game/pets.ts +459 -0
  983. package/src/engine/game/prePullHealthstones.ts +154 -0
  984. package/src/engine/game/professions.ts +2227 -0
  985. package/src/engine/game/pruneStaleRuntime.ts +39 -0
  986. package/src/engine/game/questFightCredit.ts +36 -0
  987. package/src/engine/game/questItemOnCorpse.ts +166 -0
  988. package/src/engine/game/questItemOnCreature.ts +103 -0
  989. package/src/engine/game/questLog.ts +879 -0
  990. package/src/engine/game/questSpellComplete.ts +21 -0
  991. package/src/engine/game/questTurnIn.ts +598 -0
  992. package/src/engine/game/raidParty.ts +32 -0
  993. package/src/engine/game/reagentBuyIn.ts +39 -0
  994. package/src/engine/game/regenRest.ts +186 -0
  995. package/src/engine/game/rotation.ts +425 -0
  996. package/src/engine/game/runFullDungeon.ts +611 -0
  997. package/src/engine/game/runSupply.ts +80 -0
  998. package/src/engine/game/sanitizeDriftedItems.ts +135 -0
  999. package/src/engine/game/scriptDevGoUse.ts +397 -0
  1000. package/src/engine/game/scriptDevInnkeeper.ts +150 -0
  1001. package/src/engine/game/scriptDevProfessionSpec.ts +99 -0
  1002. package/src/engine/game/sendEventFromSpell.ts +87 -0
  1003. package/src/engine/game/sortContainers.ts +85 -0
  1004. package/src/engine/game/spellReputation.ts +69 -0
  1005. package/src/engine/game/squad/squadDungeonSeating.ts +197 -0
  1006. package/src/engine/game/squadDungeon.ts +4222 -0
  1007. package/src/engine/game/squadQuestShare.ts +260 -0
  1008. package/src/engine/game/summonObjectSlot.ts +69 -0
  1009. package/src/engine/game/summonObjectWild.ts +73 -0
  1010. package/src/engine/game/summoningRitualUse.ts +141 -0
  1011. package/src/engine/game/talents.ts +356 -0
  1012. package/src/engine/game/tamingRodUse.ts +66 -0
  1013. package/src/engine/game/tempSpawnCreature.ts +136 -0
  1014. package/src/engine/game/tickDungeonPatrolScripts.ts +205 -0
  1015. package/src/engine/game/tickTimedQuests.ts +28 -0
  1016. package/src/engine/game/trade.ts +586 -0
  1017. package/src/engine/game/travel.ts +1155 -0
  1018. package/src/engine/game/types.ts +1855 -0
  1019. package/src/engine/game/vendorOffers.ts +244 -0
  1020. package/src/engine/game/weaponImbueItem.ts +281 -0
  1021. package/src/engine/game/worldSession.ts +183 -0
  1022. package/src/engine/game/worldState.ts +166 -0
  1023. package/src/engine/game.ts +968 -0
  1024. package/src/engine/spells/GAP.md +67 -0
  1025. package/src/engine/spells/absorbs.ts +376 -0
  1026. package/src/engine/spells/addTargetTrigger.ts +53 -0
  1027. package/src/engine/spells/auraPerSecondCost.ts +50 -0
  1028. package/src/engine/spells/auraStacking.ts +497 -0
  1029. package/src/engine/spells/cmangos-special-cases-combustion.ts +13 -0
  1030. package/src/engine/spells/cmangos-special-cases-s18.ts +445 -0
  1031. package/src/engine/spells/cmangos-special-cases-s19.ts +324 -0
  1032. package/src/engine/spells/cmangos-special-cases-s20.ts +385 -0
  1033. package/src/engine/spells/cmangos-special-cases-s21.ts +116 -0
  1034. package/src/engine/spells/cmangos-special-cases-s22.ts +24 -0
  1035. package/src/engine/spells/cmangos-special-cases-s23.ts +52 -0
  1036. package/src/engine/spells/cmangos-special-cases.ts +1570 -0
  1037. package/src/engine/spells/conditions.ts +718 -0
  1038. package/src/engine/spells/effects.ts +203 -0
  1039. package/src/engine/spells/fixtures/oracle-effects-lock9a.json +1 -0
  1040. package/src/engine/spells/immunity.ts +942 -0
  1041. package/src/engine/spells/intentEffects.ts +351 -0
  1042. package/src/engine/spells/interpreter/GAPS.md +21 -0
  1043. package/src/engine/spells/interpreter/amount.ts +109 -0
  1044. package/src/engine/spells/interpreter/class-scripts-kit.ts +478 -0
  1045. package/src/engine/spells/interpreter/diff.ts +246 -0
  1046. package/src/engine/spells/interpreter/duration.ts +90 -0
  1047. package/src/engine/spells/interpreter/form-attrs.json +1 -0
  1048. package/src/engine/spells/interpreter/form-attrs.ts +95 -0
  1049. package/src/engine/spells/interpreter/handlers/aura-remove.ts +113 -0
  1050. package/src/engine/spells/interpreter/handlers/auras-control.ts +1547 -0
  1051. package/src/engine/spells/interpreter/handlers/auras-core.ts +1583 -0
  1052. package/src/engine/spells/interpreter/handlers/auras-misc.ts +1774 -0
  1053. package/src/engine/spells/interpreter/handlers/effect-disenchant.ts +17 -0
  1054. package/src/engine/spells/interpreter/handlers/effect-skinning.ts +20 -0
  1055. package/src/engine/spells/interpreter/handlers/effects-action-utility.ts +1455 -0
  1056. package/src/engine/spells/interpreter/handlers/effects-core.ts +432 -0
  1057. package/src/engine/spells/interpreter/handlers/effects-remainder.ts +105 -0
  1058. package/src/engine/spells/interpreter/handlers/effects-summon-item.ts +687 -0
  1059. package/src/engine/spells/interpreter/handlers/mod-increase-energy-percent.ts +36 -0
  1060. package/src/engine/spells/interpreter/handlers/mod-increase-energy.ts +36 -0
  1061. package/src/engine/spells/interpreter/handlers/periodic-trigger-zero.ts +327 -0
  1062. package/src/engine/spells/interpreter/handlers/procs.ts +131 -0
  1063. package/src/engine/spells/interpreter/handlers/registry.ts +975 -0
  1064. package/src/engine/spells/interpreter/handlers/shared.ts +667 -0
  1065. package/src/engine/spells/interpreter/handlers.ts +9 -0
  1066. package/src/engine/spells/interpreter/hunter-kit.ts +202 -0
  1067. package/src/engine/spells/interpreter/index.ts +525 -0
  1068. package/src/engine/spells/interpreter/item-triggers.ts +1121 -0
  1069. package/src/engine/spells/interpreter/lift-consume-energy.ts +37 -0
  1070. package/src/engine/spells/interpreter/mage-portals.ts +37 -0
  1071. package/src/engine/spells/interpreter/materialize-charm.ts +88 -0
  1072. package/src/engine/spells/interpreter/materialize-dispel-mechanic.ts +25 -0
  1073. package/src/engine/spells/interpreter/materialize-rating-buffs.ts +81 -0
  1074. package/src/engine/spells/interpreter/materialize-speed.ts +109 -0
  1075. package/src/engine/spells/interpreter/materialize-spell-magnet.ts +22 -0
  1076. package/src/engine/spells/interpreter/opcodes.ts +789 -0
  1077. package/src/engine/spells/interpreter/paladin-kit.ts +95 -0
  1078. package/src/engine/spells/interpreter/paladin-seals.ts +499 -0
  1079. package/src/engine/spells/interpreter/priest-warlock-kit.ts +135 -0
  1080. package/src/engine/spells/interpreter/proc.ts +443 -0
  1081. package/src/engine/spells/interpreter/registry/helpers.ts +16 -0
  1082. package/src/engine/spells/interpreter/registry/index.ts +216 -0
  1083. package/src/engine/spells/interpreter/registry/packs/class-abilities.ts +304 -0
  1084. package/src/engine/spells/interpreter/registry/packs/dire-maul.ts +44 -0
  1085. package/src/engine/spells/interpreter/registry/packs/dummy-script-tail.ts +1065 -0
  1086. package/src/engine/spells/interpreter/registry/packs/ex-wave-m.ts +70 -0
  1087. package/src/engine/spells/interpreter/registry/packs/life-tap.ts +107 -0
  1088. package/src/engine/spells/interpreter/registry/packs/paladin.ts +246 -0
  1089. package/src/engine/spells/interpreter/registry/packs/raid-script-summons.ts +26 -0
  1090. package/src/engine/spells/interpreter/registry/packs/raid-threat-wipe.ts +22 -0
  1091. package/src/engine/spells/interpreter/registry/packs/shaman.ts +214 -0
  1092. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-a.ts +269 -0
  1093. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-b.ts +370 -0
  1094. package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-c.ts +172 -0
  1095. package/src/engine/spells/interpreter/registry/packs/si4-dummy-hunter.ts +60 -0
  1096. package/src/engine/spells/interpreter/registry/packs/si4-dummy-warrior.ts +31 -0
  1097. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-a.ts +114 -0
  1098. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-b.ts +249 -0
  1099. package/src/engine/spells/interpreter/registry/packs/si4-script-generic-c.ts +233 -0
  1100. package/src/engine/spells/interpreter/registry/types.ts +48 -0
  1101. package/src/engine/spells/interpreter/talent-scripted.ts +329 -0
  1102. package/src/engine/spells/interpreter/targeting.ts +90 -0
  1103. package/src/engine/spells/interpreter/types-intent.ts +1501 -0
  1104. package/src/engine/spells/interpreter/types.ts +419 -0
  1105. package/src/engine/spells/interpreter/warrior-druid-kit.ts +314 -0
  1106. package/src/engine/spells/interpreter/weapon-imbue-kit.ts +384 -0
  1107. package/src/engine/spells/interrupt.ts +217 -0
  1108. package/src/engine/spells/meleeAttackReset.ts +60 -0
  1109. package/src/engine/spells/oocTriggerSpell.ts +49 -0
  1110. package/src/engine/spells/overrideClassScripts.ts +319 -0
  1111. package/src/engine/spells/parryHaste.ts +20 -0
  1112. package/src/engine/spells/procs.ts +300 -0
  1113. package/src/engine/spells/recovery.ts +203 -0
  1114. package/src/engine/spells/scriptTargetDest.ts +76 -0
  1115. package/src/engine/spells/scriptTargets.ts +85 -0
  1116. package/src/engine/spells/singleTargetAura.ts +82 -0
  1117. package/src/engine/spells/specialCasePayloads.ts +57 -0
  1118. package/src/engine/spells/spellAttributes.ts +249 -0
  1119. package/src/engine/spells/spellBonus.ts +143 -0
  1120. package/src/engine/spells/spellModIntents.ts +419 -0
  1121. package/src/engine/spells/spellMods.ts +283 -0
  1122. package/src/engine/spells/spellRadius.ts +15 -0
  1123. package/src/engine/spells/trapObjects.ts +26 -0
  1124. package/src/json.d.ts +7 -0
  1125. package/src/persistence/memoryRepository.ts +23 -0
  1126. package/src/persistence/saveBackups.ts +162 -0
  1127. package/src/persistence/saveFile.ts +68 -0
  1128. package/src/persistence/saveRepository.ts +11 -0
  1129. package/src/persistence/saveShape.ts +668 -0
  1130. package/src/progression/leveling.ts +89 -0
  1131. package/src/progression/rest.ts +1434 -0
  1132. package/src/progression/training.ts +226 -0
  1133. package/src/progression/xpGain.ts +369 -0
  1134. package/src/quests/quests.ts +1580 -0
  1135. package/src/world/aoePull.ts +198 -0
  1136. package/src/world/areaTableDbc.ts +39 -0
  1137. package/src/world/areaTableMapIdPairs.ts +141 -0
  1138. package/src/world/bakeSlug.ts +43 -0
  1139. package/src/world/continuousDungeon.ts +1250 -0
  1140. package/src/world/dungeonBakeProjection.ts +190 -0
  1141. package/src/world/dungeonMapDensity.ts +342 -0
  1142. package/src/world/dungeonMapProjection.ts +135 -0
  1143. package/src/world/dungeonNav.ts +904 -0
  1144. package/src/world/dungeonNpcSim.ts +147 -0
  1145. package/src/world/dungeonObjectives.ts +234 -0
  1146. package/src/world/dungeonPreset.ts +35 -0
  1147. package/src/world/dungeonRoute.ts +311 -0
  1148. package/src/world/dungeonRouteGeometry.ts +732 -0
  1149. package/src/world/dungeonRouteOrder.ts +1037 -0
  1150. package/src/world/dungeonWingRooms.ts +426 -0
  1151. package/src/world/escort.ts +296 -0
  1152. package/src/world/goPoolRoll.ts +75 -0
  1153. package/src/world/instanceObjects.ts +785 -0
  1154. package/src/world/instances.ts +1572 -0
  1155. package/src/world/meetingStones.ts +56 -0
  1156. package/src/world/navmeshFloors.ts +145 -0
  1157. package/src/world/nearGrid.ts +167 -0
  1158. package/src/world/packBudget.ts +613 -0
  1159. package/src/world/rareRoll.ts +335 -0
  1160. package/src/world/routeAuthoring.ts +132 -0
  1161. package/src/world/routeEdit.ts +209 -0
  1162. package/src/world/world.ts +812 -0
  1163. package/src/world/zoneHazards.ts +47 -0
@@ -0,0 +1,1030 @@
1
+ // Per-type GameObject use engine, pure. Cite: GameObject.cpp Use 1398–1972; SharedDefines.h
2
+ // GameobjectTypes 515–548. The data-union index per type is documented in type-system.md.
3
+
4
+ import type { GameObjectDef, LockDataDef, LootEntryDef } from '../../data/schema.ts';
5
+ import { firstPageForGo } from '../../data/pageTexts.ts';
6
+ import type { Rng } from '../../engine/core/rng.ts';
7
+ import { isQuestRequiredLootEntry } from '../items/loot.ts';
8
+ import {
9
+ canOpenLock,
10
+ type LockDef,
11
+ type OpenLockResult,
12
+ } from './openLock.ts';
13
+
14
+ // ---- GAMEOBJECT_TYPE_* (SharedDefines.h 515–548) --------------------------
15
+
16
+ export const GAMEOBJECT_TYPE_DOOR = 0;
17
+ export const GAMEOBJECT_TYPE_BUTTON = 1;
18
+ export const GAMEOBJECT_TYPE_QUESTGIVER = 2;
19
+ export const GAMEOBJECT_TYPE_CHEST = 3;
20
+ export const GAMEOBJECT_TYPE_BINDER = 4;
21
+ export const GAMEOBJECT_TYPE_GENERIC = 5;
22
+ export const GAMEOBJECT_TYPE_TRAP = 6;
23
+ export const GAMEOBJECT_TYPE_CHAIR = 7;
24
+ export const GAMEOBJECT_TYPE_SPELL_FOCUS = 8;
25
+ export const GAMEOBJECT_TYPE_TEXT = 9;
26
+ export const GAMEOBJECT_TYPE_GOOBER = 10;
27
+ export const GAMEOBJECT_TYPE_TRANSPORT = 11;
28
+ export const GAMEOBJECT_TYPE_AREADAMAGE = 12;
29
+ export const GAMEOBJECT_TYPE_CAMERA = 13;
30
+ export const GAMEOBJECT_TYPE_MAP_OBJECT = 14;
31
+ export const GAMEOBJECT_TYPE_MO_TRANSPORT = 15;
32
+ export const GAMEOBJECT_TYPE_DUEL_ARBITER = 16;
33
+ export const GAMEOBJECT_TYPE_FISHINGNODE = 17;
34
+ export const GAMEOBJECT_TYPE_SUMMONING_RITUAL = 18;
35
+ export const GAMEOBJECT_TYPE_MAILBOX = 19;
36
+ export const GAMEOBJECT_TYPE_AUCTIONHOUSE = 20;
37
+ export const GAMEOBJECT_TYPE_GUARDPOST = 21;
38
+ export const GAMEOBJECT_TYPE_SPELLCASTER = 22;
39
+ export const GAMEOBJECT_TYPE_MEETINGSTONE = 23;
40
+ export const GAMEOBJECT_TYPE_FLAGSTAND = 24;
41
+ export const GAMEOBJECT_TYPE_FISHINGHOLE = 25;
42
+ export const GAMEOBJECT_TYPE_FLAGDROP = 26;
43
+
44
+ // Default trap rearm cooldown when trap.cooldown is 0. Cite: GameObject.cpp:1532 — `cooldown ? cooldown :
45
+ // uint32(4)`.
46
+ export const TRAP_DEFAULT_COOLDOWN_SECS = 4;
47
+
48
+ /** Meeting Stone Summon. Cite: GameObject.cpp:1888 `spellId = 23598`. */
49
+ export const MEETINGSTONE_SUMMON_SPELL_ID = 23598;
50
+
51
+ // ---- Result / context -----------------------------------------------------
52
+
53
+ export type UseGameObjectKind =
54
+ | 'door'
55
+ | 'button'
56
+ | 'chest'
57
+ | 'trap'
58
+ | 'goober'
59
+ | 'questgiver'
60
+ | 'fishingnode'
61
+ | 'fishinghole'
62
+ | 'transport'
63
+ | 'mo_transport'
64
+ | 'summoning_ritual'
65
+ | 'spellcaster'
66
+ | 'spell_focus'
67
+ | 'text'
68
+ | 'mailbox'
69
+ | 'meetingstone'
70
+ | 'unsupported';
71
+
72
+ export type UseGameObjectReason =
73
+ | 'locked'
74
+ | 'low_skill'
75
+ | 'quest_incomplete'
76
+ | 'event_inactive'
77
+ | 'not_ready'
78
+ | 'cooldown'
79
+ | 'no_charges'
80
+ | 'party_only'
81
+ | 'fishing_failed'
82
+ | 'unsupported'
83
+ | 'missing_context'
84
+ | 'not_in_group'
85
+ | 'is_owner'
86
+ | 'owner_not_channeling'
87
+ | 'no_target'
88
+ | 'level_out_of_range'
89
+ /** GO_FLAG_NO_INTERACT. Cite: SpellHandler.cpp:304-308 HandleGameObjectUseOpcode. */
90
+ | 'no_interact';
91
+
92
+ export type GoLootState = 'ready' | 'activated' | 'not_ready' | 'just_deactivated';
93
+
94
+ export interface UseGameObjectResult {
95
+ ok: boolean;
96
+ reason?: UseGameObjectReason;
97
+ kind: UseGameObjectKind;
98
+ /** gameobject_loot_template id for caller to roll — never invented here. */
99
+ lootId?: number;
100
+ /** Spell to cast on user (trap detonation / goober.spellId). */
101
+ castSpellId?: number;
102
+ /** Linked trap entry for caller to detonate (TriggerLinkedGameObject). */
103
+ linkedTrapId?: number;
104
+ /** Goober RewardPlayerAndGroupAtCast / cast-on-GO quest credit. */
105
+ questCredit?: boolean;
106
+ // Scripted event id to fire after a successful Use, from the goober or chest data union. The caller
107
+ // may route it to a scripted-event handler — it is never a pre-use gate.
108
+ firedEventId?: number;
109
+ /** Consumable chest/goober: despawn (no restock). */
110
+ despawn?: boolean;
111
+ /** Non-consumable chest with restockTime: ready again at this wall-clock ms. */
112
+ restockAtMs?: number;
113
+ /** Flavor state after door/button open. */
114
+ state?: GoLootState;
115
+ /** Baked autoCloseSecs for door/button/goober (already /0x10000 at bake). */
116
+ autoCloseSecs?: number;
117
+ /** Trap bookkeeping after trigger. */
118
+ trapUses?: number;
119
+ trapCooldownUntilMs?: number;
120
+ // SUMMONING_RITUAL: animSpell, else GO m_spellId (GetSpellId). Cite: GameObject.cpp:1815–1818
121
+ // CastSpell(animSpell) / CastSpell(GetSpellId, CHANNEL_ONLY).
122
+ channelSpellId?: number;
123
+ // SUMMONING_RITUAL completion spell when unique uses ≥ reqParticipants. Cite: GameObject.cpp:2476
124
+ // TriggerSummoningRitual CastSpell(spellId).
125
+ ritualSpellId?: number;
126
+ uniqueUseCount?: number;
127
+ reqParticipants?: number;
128
+ ritualReady?: boolean;
129
+ uniqueUserIds?: string[];
130
+ firstUser?: string;
131
+ /** TEXT data0 pageID; host opens page_text. Cite: GameObject.h:156–163. */
132
+ pageId?: number;
133
+ }
134
+
135
+ // Runtime bookkeeping for multi-step GO lifecycle (trap arm, restock window). Caller owns persistence; pure
136
+ // helpers only read/return new values.
137
+ export interface GoRuntimeState {
138
+ /** Trap: wall-clock when arming started (NOT_READY). */
139
+ armStartedAtMs?: number;
140
+ /** Trap / restock: earliest time the GO is ready. */
141
+ readyAtMs?: number;
142
+ /** Trap: uses so far (charges bookkeeping). */
143
+ uses?: number;
144
+ /** Trap: rearm cooldown end. */
145
+ cooldownUntilMs?: number;
146
+ /** Door/button open/closed flavor. */
147
+ open?: boolean;
148
+ /** Script spawn visibility. Cite: ScriptMgr.cpp:1980–2025 / :2864–2871. */
149
+ spawned?: boolean;
150
+ /** GO_FLAG_LOCKED. Cite: ScriptMgr.cpp:2478–2503. */
151
+ locked?: boolean;
152
+ /** GO_FLAG_NO_INTERACT. Cite: ScriptMgr.cpp:2478–2503. */
153
+ noInteract?: boolean;
154
+ /** Pending ForcedDespawn delay (secs) when > 0. Cite: ScriptMgr.cpp:2864–2871. */
155
+ despawnDelay?: number;
156
+ /** SUMMONING_RITUAL unique channelers (m_UniqueUsers). Cite: GameObject.cpp:772 AddUniqueUse. */
157
+ uniqueUsers?: string[];
158
+ /** First unique user (m_firstUser). Cite: GameObject.cpp:776. */
159
+ firstUser?: string;
160
+ /** Custom delay before TriggerSummoningRitual (CustomData1; unset in bake). */
161
+ delayedActionUntilMs?: number;
162
+ }
163
+
164
+ export interface UseGameObjectCtx {
165
+ /** Lock.dbc row for go.lockId (from DataBundle.locks). Shape matches LockDef. */
166
+ lock?: LockDef | LockDataDef;
167
+ // Item entry used as key for LOCK_KEY_ITEM (go.keyId when player holds that item). Do not invent ids —
168
+ // pass inventory match of baked keyId.
169
+ keyItemEntry?: number;
170
+ /** Spell EffectMiscValue for skill-lock type match (openLock). */
171
+ spellLockType?: number;
172
+ /** Player skill value for LOCK_KEY_SKILL. */
173
+ skillValue?: number;
174
+ /** Per-LockType skill value (lockpicking / mining / herbalism). Cite: openLock.skillValueFor. */
175
+ skillValueFor?: (lockType: number) => number | undefined;
176
+ /** Active incomplete quest ids (goober.questId gate). */
177
+ incompleteQuestIds?: ReadonlySet<number> | readonly number[];
178
+ /** Fishing skill + zone base skill (FISHINGNODE roll). */
179
+ fishingSkill?: number;
180
+ zoneSkill?: number;
181
+ // Optional fixed d100 for fishing tests (1..100). When omitted, uses rng.int(1,100). Cite:
182
+ // GameObject.cpp:1703 irand(1, 100).
183
+ fishingRoll1to100?: number;
184
+ /** Injected clock (ms). */
185
+ nowMs: number;
186
+ /** Injected RNG (fishing roll when fishingRoll1to100 not set). */
187
+ rng?: Rng;
188
+ /** Optional prior runtime state (trap charges / arm / restock). */
189
+ runtime?: GoRuntimeState;
190
+ /** SPELLCASTER partyOnly: false refuses; omitted = solo user is the party. Cite: GameObject.cpp:1837–1845. */
191
+ inOwnerGroup?: boolean;
192
+ /** User level for MEETINGSTONE [minLevel, maxLevel]. Cite: GameObject.cpp:1880–1882. */
193
+ playerLevel?: number;
194
+ /** Selected group member level. Cite: GameObject.cpp:1884–1886. */
195
+ targetLevel?: number;
196
+ /** Selected target is in the user's group and not self. Cite: GameObject.cpp:1876–1877. */
197
+ hasGroupTarget?: boolean;
198
+ // Active CALENDAR game_event ids, reserved for spawn-side presence. Goober and chest event ids are
199
+ // scripted values that fire ON use, and never gate it.
200
+ activeEventIds?: ReadonlySet<number> | readonly number[];
201
+ // SUMMONING_RITUAL unique-use id (player / ally_N). Default `player`. Cite: GameObject.cpp:1813
202
+ // AddUniqueUse.
203
+ userId?: string;
204
+ /** Prior unique users (runtime.uniqueUsers). */
205
+ uniqueUserIds?: readonly string[];
206
+ /** m_firstUser from a prior Use. */
207
+ firstUser?: string;
208
+ /** Spell-created ritual has an owner (EffectTransmitted). */
209
+ hasOwner?: boolean;
210
+ /** User is the owner — C++ refuses (already counted at create). */
211
+ isOwner?: boolean;
212
+ /** Owner must already be channeling. Cite: GameObject.cpp:1796–1797. */
213
+ ownerChanneling?: boolean;
214
+ /** User is in the owner's / firstUser's group. Cite: GameObject.cpp:1792, :1801–1810. */
215
+ inGroup?: boolean;
216
+ /** GO instance m_spellId (SetSpellId from the creating spell). */
217
+ goSpellId?: number;
218
+ /** m_delayedActionTimer still running. Cite: GameObject.cpp:1777–1778. */
219
+ delayedActionUntilMs?: number;
220
+ /** TEXT pageID (gameobject_template.data0 / pageTexts.goPages). Cite: GameObject.h:159. */
221
+ pageId?: number;
222
+ }
223
+
224
+ // ---- Helpers --------------------------------------------------------------
225
+
226
+ /** LockDataDef and LockDef share { id, cases } — cast for openLock. */
227
+ export function asLockDef(lock: LockDef | LockDataDef | undefined): LockDef | undefined {
228
+ return lock as LockDef | undefined;
229
+ }
230
+
231
+ function hasIncompleteQuest(
232
+ incomplete: UseGameObjectCtx['incompleteQuestIds'],
233
+ questId: number,
234
+ ): boolean {
235
+ if (!incomplete) return false;
236
+ if (Array.isArray(incomplete)) return incomplete.includes(questId);
237
+ // Array.isArray doesn't narrow ReadonlyArray out of the union, but only a Set reaches here.
238
+ return (incomplete as ReadonlySet<number>).has(questId);
239
+ }
240
+
241
+ function hasActiveEvent(
242
+ active: UseGameObjectCtx['activeEventIds'],
243
+ eventId: number,
244
+ ): boolean {
245
+ if (!active) return false;
246
+ if (Array.isArray(active)) return active.includes(eventId);
247
+ return (active as ReadonlySet<number>).has(eventId);
248
+ }
249
+
250
+ // Calendar game_event presence helper, spawn-side only. Do NOT use it with the goober or chest data
251
+ // union — those are scripted event ids fired on Use, not calendar prerequisites.
252
+ export function isGoEventActive(
253
+ eventId: number | undefined,
254
+ activeEventIds: UseGameObjectCtx['activeEventIds'],
255
+ ): boolean {
256
+ if (eventId == null || eventId <= 0) return true;
257
+ // No event snapshot provided → do not invent a refuse.
258
+ if (activeEventIds == null) return true;
259
+ return hasActiveEvent(activeEventIds, eventId);
260
+ }
261
+
262
+ function lockRefuseReason(r: OpenLockResult): UseGameObjectReason {
263
+ if (!r.ok && r.reason === 'low_skill') return 'low_skill';
264
+ return 'locked';
265
+ }
266
+
267
+ // Gate a GO open through canOpenLock when a lockId is present: a key item, a skill value, or one of
268
+ // the free-open lock types. A prior OPEN_LOCK cast sets runtime.open and Use proceeds.
269
+ export function checkGoLock(
270
+ go: GameObjectDef,
271
+ ctx: Pick<
272
+ UseGameObjectCtx,
273
+ 'lock' | 'keyItemEntry' | 'spellLockType' | 'skillValue' | 'skillValueFor' | 'runtime'
274
+ >,
275
+ ): OpenLockResult {
276
+ if (!go.lockId) return { ok: true };
277
+ // Already unlocked by Pick Lock / Opening spell (goRuntime.open). Cite: EffectOpenLock.
278
+ if (ctx.runtime?.open) return { ok: true };
279
+ return canOpenLock({
280
+ lock: asLockDef(ctx.lock) ?? { id: go.lockId, cases: [] },
281
+ keyItemEntry: ctx.keyItemEntry,
282
+ spellLockType: ctx.spellLockType,
283
+ skillValue: ctx.skillValue,
284
+ skillValueFor: ctx.skillValueFor,
285
+ });
286
+ }
287
+
288
+ // Fishing bobber skill roll: chance is skill - zone skill + 5, and success needs the skill to meet the
289
+ // zone's and the chance to beat an irand(1,100). Cite: GameObject.cpp:1701–1708.
290
+ export function fishingBobberSuccess(
291
+ skill: number,
292
+ zoneSkill: number,
293
+ roll1to100: number,
294
+ ): boolean {
295
+ const chance = skill - zoneSkill + 5;
296
+ return skill >= zoneSkill && chance >= roll1to100;
297
+ }
298
+
299
+ /** Chance percent used by fishingBobberSuccess (for tests / UI). */
300
+ export function fishingBobberChance(skill: number, zoneSkill: number): number {
301
+ return skill - zoneSkill + 5;
302
+ }
303
+
304
+ // ---- Trap arm / trigger (pure) --------------------------------------------
305
+
306
+ // Begin trap arming. Ready after startDelay seconds (0 → immediately ready). Cite: GameObject.cpp:321–328
307
+ // arm with trap.startDelay.
308
+ export function armTrap(
309
+ go: GameObjectDef,
310
+ nowMs: number,
311
+ runtime: GoRuntimeState = {},
312
+ ): { runtime: GoRuntimeState; readyAtMs: number } {
313
+ const delaySecs = go.trap?.startDelay ?? 0;
314
+ const readyAtMs = nowMs + delaySecs * 1000;
315
+ return {
316
+ readyAtMs,
317
+ runtime: {
318
+ ...runtime,
319
+ armStartedAtMs: nowMs,
320
+ readyAtMs,
321
+ },
322
+ };
323
+ }
324
+
325
+ // Trigger a trap if armed, off cooldown and with charges left, returning the spellId for the caller to
326
+ // detonate. GAP: the radius search and triggerOn filter are out of pure scope.
327
+ export function triggerTrap(
328
+ go: GameObjectDef,
329
+ ctx: Pick<UseGameObjectCtx, 'nowMs' | 'runtime'>,
330
+ ): UseGameObjectResult {
331
+ const kind: UseGameObjectKind = 'trap';
332
+ if (go.type !== GAMEOBJECT_TYPE_TRAP || !go.trap) {
333
+ return { ok: false, reason: 'unsupported', kind: 'unsupported' };
334
+ }
335
+ const rt = ctx.runtime ?? {};
336
+ const now = ctx.nowMs;
337
+ const readyAt = rt.readyAtMs ?? 0;
338
+ if (readyAt > now) {
339
+ return { ok: false, reason: 'not_ready', kind, state: 'not_ready' };
340
+ }
341
+ if (rt.cooldownUntilMs != null && rt.cooldownUntilMs > now) {
342
+ return { ok: false, reason: 'cooldown', kind, trapCooldownUntilMs: rt.cooldownUntilMs };
343
+ }
344
+ const maxCharges = go.trap.charges ?? 0;
345
+ const uses = rt.uses ?? 0;
346
+ if (maxCharges > 0 && uses >= maxCharges) {
347
+ return { ok: false, reason: 'no_charges', kind, trapUses: uses, despawn: true };
348
+ }
349
+
350
+ const cdSecs = go.trap.cooldown && go.trap.cooldown > 0
351
+ ? go.trap.cooldown
352
+ : TRAP_DEFAULT_COOLDOWN_SECS;
353
+ const newUses = uses + (maxCharges > 0 ? 1 : 0);
354
+ const exhausted = maxCharges > 0 && newUses >= maxCharges;
355
+
356
+ return {
357
+ ok: true,
358
+ kind,
359
+ castSpellId: go.trap.spellId,
360
+ trapUses: newUses,
361
+ trapCooldownUntilMs: now + cdSecs * 1000,
362
+ state: exhausted ? 'just_deactivated' : 'activated',
363
+ despawn: exhausted || undefined,
364
+ };
365
+ }
366
+
367
+ // ---- useGameObject --------------------------------------------------------
368
+
369
+ // Pure per-type GO interaction. Deterministic given ctx (nowMs, rng, locks, quests). Caller rolls lootId
370
+ // and applies combat/spell side effects.
371
+ export function useGameObject(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
372
+ switch (go.type) {
373
+ case GAMEOBJECT_TYPE_DOOR:
374
+ return useDoor(go, ctx);
375
+ case GAMEOBJECT_TYPE_BUTTON:
376
+ return useButton(go, ctx);
377
+ case GAMEOBJECT_TYPE_CHEST:
378
+ return useChest(go, ctx);
379
+ case GAMEOBJECT_TYPE_TRAP:
380
+ return triggerTrap(go, ctx);
381
+ case GAMEOBJECT_TYPE_GOOBER:
382
+ return useGoober(go, ctx);
383
+ case GAMEOBJECT_TYPE_QUESTGIVER:
384
+ return useQuestGiver(go, ctx);
385
+ case GAMEOBJECT_TYPE_FISHINGNODE:
386
+ return useFishingNode(go, ctx);
387
+ case GAMEOBJECT_TYPE_FISHINGHOLE:
388
+ return useFishingHole(go, ctx);
389
+ case GAMEOBJECT_TYPE_MO_TRANSPORT:
390
+ return useMoTransport(go, ctx);
391
+ case GAMEOBJECT_TYPE_TRANSPORT:
392
+ return useTransport(go, ctx);
393
+ case GAMEOBJECT_TYPE_SUMMONING_RITUAL:
394
+ return useSummoningRitual(go, ctx);
395
+ case GAMEOBJECT_TYPE_SPELLCASTER:
396
+ return useSpellcaster(go, ctx);
397
+ case GAMEOBJECT_TYPE_SPELL_FOCUS:
398
+ return useSpellFocus(go);
399
+ case GAMEOBJECT_TYPE_TEXT:
400
+ return useText(go, ctx);
401
+ case GAMEOBJECT_TYPE_MAILBOX:
402
+ return useMailbox(go);
403
+ case GAMEOBJECT_TYPE_MEETINGSTONE:
404
+ return useMeetingStone(go, ctx);
405
+ default:
406
+ return {
407
+ ok: false,
408
+ reason: 'unsupported',
409
+ kind: 'unsupported',
410
+ };
411
+ }
412
+ }
413
+
414
+ // QUESTGIVER Use — PrepareGossipMenu plus SendPreparedGossip. No loot: the caller surfaces the quest
415
+ // relations. The lock gate still applies, as on a locked document.
416
+ function useQuestGiver(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
417
+ const lockCheck = checkGoLock(go, ctx);
418
+ if (!lockCheck.ok) {
419
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'questgiver' };
420
+ }
421
+ // A type-2 QUESTGIVER may ALSO carry gameobject loot, so keep the relations AND the lootId — the
422
+ // interact path must roll it when present. Cite: type-system.md quest relations plus loot.
423
+ return {
424
+ ok: true,
425
+ kind: 'questgiver',
426
+ lootId: go.lootId && go.lootId > 0 ? go.lootId : undefined,
427
+ // Leave questCredit undefined so the interact path still records the object for objectTargets
428
+ // when the same entry is also a click objective.
429
+ state: 'activated',
430
+ };
431
+ }
432
+
433
+ /** TEXT Use opens pageID (data0). Cite: GameObject.h:156–163; SMSG_GAMEOBJECT_PAGETEXT cpp:1607–1611. */
434
+ function useText(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
435
+ const lockCheck = checkGoLock(go, ctx);
436
+ if (!lockCheck.ok) {
437
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'text' };
438
+ }
439
+ const pageId = (ctx.pageId && ctx.pageId > 0 ? ctx.pageId : firstPageForGo(go.entry)) ?? undefined;
440
+ return { ok: true, kind: 'text', pageId, state: 'activated' };
441
+ }
442
+
443
+ /** GAMEOBJECT_TYPE_MAILBOX — empty union; type value opens mail. Cite: GameObject.h:244; MailHandler.cpp:44–52, :536–545. */
444
+ function useMailbox(go: GameObjectDef): UseGameObjectResult {
445
+ if (go.type !== GAMEOBJECT_TYPE_MAILBOX) {
446
+ return { ok: false, reason: 'unsupported', kind: 'unsupported' };
447
+ }
448
+ return { ok: true, kind: 'mailbox', state: 'activated' };
449
+ }
450
+
451
+ // ---- FO2 reverse quest links (pure) ----------------------------------------
452
+
453
+ /** Quest entries this GO starts (gameobject_questrelation reverse of QuestDef.goStarter). */
454
+ export function questsStartedAtGo(go: Pick<GameObjectDef, 'questsStarted'>): number[] {
455
+ return (go.questsStarted ?? []).filter((id) => id > 0);
456
+ }
457
+
458
+ /** Quest entries this GO ends (gameobject_involvedrelation reverse of QuestDef.goEnder). */
459
+ export function questsEndedAtGo(go: Pick<GameObjectDef, 'questsEnded'>): number[] {
460
+ return (go.questsEnded ?? []).filter((id) => id > 0);
461
+ }
462
+
463
+ /** True when the GO is a quest-giver type or has baked start/end reverse links. */
464
+ export function isGoQuestGiver(go: Pick<GameObjectDef, 'type' | 'questsStarted' | 'questsEnded'>): boolean {
465
+ if (go.type === GAMEOBJECT_TYPE_QUESTGIVER) return true;
466
+ return questsStartedAtGo(go).length > 0 || questsEndedAtGo(go).length > 0;
467
+ }
468
+
469
+ /** FISHINGHOLE (25). Cite: GameObject.cpp:1911; interactObject requires the fishing line. */
470
+ export function isGoFishingSchool(go: Pick<GameObjectDef, 'type' | 'fishinghole'>): boolean {
471
+ return go.type === GAMEOBJECT_TYPE_FISHINGHOLE || go.fishinghole != null;
472
+ }
473
+
474
+ /** chest.data8 / goober.data1 / spellFocus.data4. Cite: GameObject.h:99, :166, :151. */
475
+ export function goUseQuestId(go: Pick<GameObjectDef, 'chest' | 'goober' | 'spellFocus'>): number {
476
+ return (go.chest?.questId ?? go.goober?.questId ?? go.spellFocus?.questId ?? 0) | 0;
477
+ }
478
+
479
+ /** Every row is ChanceOrQuestChance-gated. Empty table is not. Cite: LootMgr quest chance. */
480
+ export function goLootIsQuestOnly(loot: readonly LootEntryDef[] | undefined): boolean {
481
+ if (!loot || loot.length === 0) return false;
482
+ return loot.every((e) => isQuestRequiredLootEntry(e));
483
+ }
484
+
485
+ /** Player facts for `goVisibleForPlayer`. Built once per paint. */
486
+ export interface GoPlayerVisibility {
487
+ incompleteQuestIds: ReadonlySet<number>;
488
+ neededItems: ReadonlySet<number>;
489
+ /** Active objectTargets (HasQuestForGO). Cite: GameObject.cpp:1172. */
490
+ neededGoEntries?: ReadonlySet<number>;
491
+ hasFishing: boolean;
492
+ }
493
+
494
+ export type GoLootLookup = (lootId: number) => readonly LootEntryDef[];
495
+
496
+ /** Hide when Use would refuse (quest / no fishing). Cite: GameObject.cpp:1628-1633. */
497
+ export function goVisibleForPlayer(
498
+ go: GameObjectDef,
499
+ player: GoPlayerVisibility,
500
+ lootFor?: GoLootLookup,
501
+ ): boolean {
502
+ if (isGoFishingSchool(go) && !player.hasFishing) return false;
503
+ // A type-2 giver is a dialog examine, not a loot open. Cite: professions.ts skipLootGate.
504
+ if (go.type === GAMEOBJECT_TYPE_QUESTGIVER) return true;
505
+ const questId = goUseQuestId(go);
506
+ if (questId > 0 && !player.incompleteQuestIds.has(questId)) return false;
507
+ const lootId = (go.lootId ?? 0) | 0;
508
+ if (lootId > 0 && lootFor) {
509
+ const table = lootFor(lootId);
510
+ if (goLootIsQuestOnly(table)) {
511
+ const neededGo = player.neededGoEntries?.has(go.entry) === true;
512
+ if (!neededGo && !table.some((e) => player.neededItems.has(e.item))) return false;
513
+ }
514
+ }
515
+ return true;
516
+ }
517
+
518
+ /** What a Use can reach beyond the GO row itself, read by the caller from its own tables. */
519
+ export interface GoUseOutcomeDeps {
520
+ /** Some quest names this entry as an objective target, a goStarter or a goEnder. */
521
+ questReferenced: boolean;
522
+ /** firstPageForGo — a TEXT/goober page the Use opens. */
523
+ hasPageText: boolean;
524
+ /** A herb / vein / fishing node row: the Use is a gather. */
525
+ isGatherNode: boolean;
526
+ /** dbscripts_on_go_template_use rows, a ported ScriptDev goUse, or any other scripted Use host. */
527
+ hasScriptedUse: boolean;
528
+ }
529
+
530
+ /**
531
+ * True when a successful Use hands the player something: loot, a page, a quest link, a spell, a
532
+ * fired script, or a surface of its own. Only the five types a world row resolves are judged.
533
+ */
534
+ export function goUseHasOutcome(go: GameObjectDef, deps: GoUseOutcomeDeps): boolean {
535
+ if (deps.questReferenced || deps.hasPageText || deps.isGatherNode || deps.hasScriptedUse) return true;
536
+ if ((go.lootId ?? 0) > 0) return true;
537
+ if (questsStartedAtGo(go).length > 0 || questsEndedAtGo(go).length > 0) return true;
538
+ switch (go.type) {
539
+ case GAMEOBJECT_TYPE_CHEST: {
540
+ const c = go.chest;
541
+ return (c?.questId ?? 0) > 0 || (c?.eventId ?? 0) > 0 || (c?.linkedTrapId ?? 0) > 0;
542
+ }
543
+ case GAMEOBJECT_TYPE_GOOBER: {
544
+ const g = go.goober;
545
+ return (g?.questId ?? 0) > 0 || (g?.spellId ?? 0) > 0
546
+ || (g?.eventId ?? 0) > 0 || (g?.linkedTrapId ?? 0) > 0 || (g?.pageId ?? 0) > 0;
547
+ }
548
+ // A questgiver with no relations and no loot gossips at nothing; GENERIC and TEXT with no page
549
+ // fall through useGameObject to `unsupported`.
550
+ case GAMEOBJECT_TYPE_QUESTGIVER:
551
+ case GAMEOBJECT_TYPE_GENERIC:
552
+ case GAMEOBJECT_TYPE_TEXT:
553
+ return false;
554
+ default:
555
+ return true;
556
+ }
557
+ }
558
+
559
+ // Type-driven interact verb for world-panel rows, never hand-mapped per entry: a questgiver gossips,
560
+ // a chest or fishing hole opens, a text row reads, and everything else is Use.
561
+ export function interactVerbForGoType(type: number): string {
562
+ switch (type) {
563
+ case GAMEOBJECT_TYPE_QUESTGIVER:
564
+ return 'Examine';
565
+ case GAMEOBJECT_TYPE_CHEST:
566
+ case GAMEOBJECT_TYPE_FISHINGHOLE:
567
+ case GAMEOBJECT_TYPE_DOOR:
568
+ return 'Open';
569
+ case GAMEOBJECT_TYPE_TEXT:
570
+ return 'Read';
571
+ case GAMEOBJECT_TYPE_MAILBOX:
572
+ return 'Open';
573
+ case GAMEOBJECT_TYPE_GOOBER:
574
+ case GAMEOBJECT_TYPE_BUTTON:
575
+ case GAMEOBJECT_TYPE_SPELLCASTER:
576
+ case GAMEOBJECT_TYPE_GENERIC:
577
+ default:
578
+ return 'Use';
579
+ }
580
+ }
581
+
582
+ // World-panel availability for a zone-scoped GO runtime slot, the consumable multi-spawn proxy. A
583
+ // permanent despawn uses a readyAt of MAX_SAFE_INTEGER.
584
+ export type GoRuntimeAvailability =
585
+ | { kind: 'ready' }
586
+ | { kind: 'consumed' }
587
+ | { kind: 'restock'; readyAtMs: number };
588
+
589
+ export function goRuntimeAvailability(
590
+ runtime: GoRuntimeState | undefined,
591
+ nowMs: number,
592
+ ): GoRuntimeAvailability {
593
+ // DESPAWN_GO delay 0 → not spawned. Cite: ScriptMgr.cpp:2864–2871.
594
+ if (runtime?.spawned === false) return { kind: 'consumed' };
595
+ const readyAt = runtime?.readyAtMs;
596
+ if (readyAt == null || readyAt <= nowMs) return { kind: 'ready' };
597
+ if (readyAt >= Number.MAX_SAFE_INTEGER / 2) return { kind: 'consumed' };
598
+ return { kind: 'restock', readyAtMs: readyAt };
599
+ }
600
+
601
+ function useDoor(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
602
+ // data-union: door { startOpen, lockId, autoCloseTime } — GameObject.h:51–60
603
+ // Cite: SpellHandler.cpp:304-308 GO_FLAG_NO_INTERACT → Use refused (before lock open).
604
+ if (ctx.runtime?.noInteract) {
605
+ return { ok: false, reason: 'no_interact', kind: 'door' };
606
+ }
607
+ const lockCheck = checkGoLock(go, ctx);
608
+ if (!lockCheck.ok) {
609
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'door' };
610
+ }
611
+ const open = !(ctx.runtime?.open ?? go.door?.startOpen ?? false);
612
+ return {
613
+ ok: true,
614
+ kind: 'door',
615
+ state: open ? 'activated' : 'ready',
616
+ autoCloseSecs: go.door?.autoCloseSecs,
617
+ };
618
+ }
619
+
620
+ function useButton(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
621
+ // data-union: button { startOpen, lockId, autoCloseTime, linkedTrapId } — GameObject.h:61–73
622
+ const lockCheck = checkGoLock(go, ctx);
623
+ if (!lockCheck.ok) {
624
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'button' };
625
+ }
626
+ const open = !(ctx.runtime?.open ?? go.button?.startOpen ?? false);
627
+ return {
628
+ ok: true,
629
+ kind: 'button',
630
+ state: open ? 'activated' : 'ready',
631
+ autoCloseSecs: go.button?.autoCloseSecs,
632
+ linkedTrapId: go.button?.linkedTrapId,
633
+ };
634
+ }
635
+
636
+ function useChest(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
637
+ // data-union chest: lockId data0, lootId data1, restockTime data2, consumable data3,
638
+ // linkedTrapId data7, questId data8 — type-system.md; restock vs consumable GameObject.cpp:625–634
639
+ const lockCheck = checkGoLock(go, ctx);
640
+ if (!lockCheck.ok) {
641
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'chest' };
642
+ }
643
+
644
+ // Restock window: still not ready
645
+ if (ctx.runtime?.readyAtMs != null && ctx.runtime.readyAtMs > ctx.nowMs) {
646
+ return {
647
+ ok: false,
648
+ reason: 'not_ready',
649
+ kind: 'chest',
650
+ restockAtMs: ctx.runtime.readyAtMs,
651
+ state: 'not_ready',
652
+ };
653
+ }
654
+
655
+ const chest = go.chest;
656
+ // chest.data8: Use refuses without QUEST_STATUS_INCOMPLETE; goVisibleForPlayer hides the row.
657
+ // Cite: GameObject.h:99; GameObject.cpp:1628–1633 (goober; same gate on chest Use here).
658
+ const chestQuestId = chest?.questId ?? 0;
659
+ if (chestQuestId > 0 && !hasIncompleteQuest(ctx.incompleteQuestIds, chestQuestId)) {
660
+ return { ok: false, reason: 'quest_incomplete', kind: 'chest' };
661
+ }
662
+ const lootId = go.lootId;
663
+ const linkedTrapId = chest?.linkedTrapId;
664
+ const consumable = !!chest?.consumable;
665
+ const restockTime = chest?.restockTime ?? 0;
666
+ // chest data6 "lootedEvent" — fire after loot, never a pre-use calendar gate.
667
+ const firedEventId = chest?.eventId && chest.eventId > 0 ? chest.eventId : undefined;
668
+
669
+ // consumable overrides restock (GameObject.cpp:627–634)
670
+ if (consumable) {
671
+ return {
672
+ ok: true,
673
+ kind: 'chest',
674
+ lootId,
675
+ linkedTrapId,
676
+ firedEventId,
677
+ despawn: true,
678
+ state: 'just_deactivated',
679
+ };
680
+ }
681
+
682
+ if (restockTime > 0) {
683
+ const restockAtMs = ctx.nowMs + restockTime * 1000;
684
+ return {
685
+ ok: true,
686
+ kind: 'chest',
687
+ lootId,
688
+ linkedTrapId,
689
+ firedEventId,
690
+ restockAtMs,
691
+ state: 'not_ready',
692
+ };
693
+ }
694
+
695
+ // No restock, not consumable: open once; caller may still despawn spawn-side
696
+ return {
697
+ ok: true,
698
+ kind: 'chest',
699
+ lootId,
700
+ linkedTrapId,
701
+ firedEventId,
702
+ state: 'activated',
703
+ };
704
+ }
705
+
706
+ function useGoober(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
707
+ // data-union goober: lockId data0, questId data1, consumable data5, spellId data10,
708
+ // linkedTrapId data12 — GameObject.h:162–184; Use GameObject.cpp:1577–1651
709
+ const lockCheck = checkGoLock(go, ctx);
710
+ if (!lockCheck.ok) {
711
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'goober' };
712
+ }
713
+
714
+ // Multi-spawn consumable restock and permanent despawn, on the same readyAt gate as chests. The
715
+ // interact path restocks single-id proxies while objectTargets still need their clicks.
716
+ if (ctx.runtime?.readyAtMs != null && ctx.runtime.readyAtMs > ctx.nowMs) {
717
+ return {
718
+ ok: false,
719
+ reason: 'not_ready',
720
+ kind: 'goober',
721
+ restockAtMs: ctx.runtime.readyAtMs,
722
+ state: 'not_ready',
723
+ };
724
+ }
725
+
726
+ const goober = go.goober;
727
+ const questId = goober?.questId ?? 0;
728
+ // questId > 0 → must be QUEST_STATUS_INCOMPLETE (GameObject.cpp:1628–1633)
729
+ if (questId > 0 && !hasIncompleteQuest(ctx.incompleteQuestIds, questId)) {
730
+ return { ok: false, reason: 'quest_incomplete', kind: 'goober' };
731
+ }
732
+
733
+ // goober data2 eventId is scripted_event_id fired ON use (StartEvents_Event),
734
+ // not a calendar game_event prerequisite — surface as firedEventId only.
735
+ const firedEventId = goober?.eventId && goober.eventId > 0 ? goober.eventId : undefined;
736
+ const consumable = !!goober?.consumable;
737
+ return {
738
+ ok: true,
739
+ kind: 'goober',
740
+ // RewardPlayerAndGroupAtCast always on successful player Use (cpp:1635)
741
+ questCredit: true,
742
+ castSpellId: goober?.spellId,
743
+ linkedTrapId: goober?.linkedTrapId,
744
+ firedEventId,
745
+ despawn: consumable || undefined,
746
+ autoCloseSecs: goober?.autoCloseSecs,
747
+ state: consumable ? 'just_deactivated' : 'activated',
748
+ };
749
+ }
750
+
751
+ function useFishingNode(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
752
+ // FISHINGNODE Use GameObject.cpp:1672–1771; skill roll :1693–1708
753
+ const skill = ctx.fishingSkill;
754
+ const zoneSkill = ctx.zoneSkill;
755
+ if (skill == null || zoneSkill == null) {
756
+ return { ok: false, reason: 'missing_context', kind: 'fishingnode' };
757
+ }
758
+
759
+ let roll = ctx.fishingRoll1to100;
760
+ if (roll == null) {
761
+ if (!ctx.rng) {
762
+ return { ok: false, reason: 'missing_context', kind: 'fishingnode' };
763
+ }
764
+ roll = ctx.rng.int(1, 100);
765
+ }
766
+
767
+ if (!fishingBobberSuccess(skill, zoneSkill, roll)) {
768
+ return { ok: false, reason: 'fishing_failed', kind: 'fishingnode' };
769
+ }
770
+
771
+ // Bobber loot is LOOT_FISHING by zone; optional fishnode.lootId if baked
772
+ return {
773
+ ok: true,
774
+ kind: 'fishingnode',
775
+ lootId: go.fishnode?.lootId,
776
+ state: 'activated',
777
+ };
778
+ }
779
+
780
+ /** GAMEOBJECT_TYPE_MO_TRANSPORT Use — C++ has no type-15 case; Phonecraft Use is AddPassenger. Cite: GameObject.cpp:1948; Transports.cpp:271. */
781
+ function useMoTransport(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
782
+ const lockCheck = checkGoLock(go, ctx);
783
+ if (!lockCheck.ok) {
784
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'mo_transport' };
785
+ }
786
+ return { ok: true, kind: 'mo_transport', state: 'activated' };
787
+ }
788
+
789
+ // TRANSPORT Use — board the elevator or tram. The C++ has no type-11 Use case at all; boarding is
790
+ // walking on, so our Use is that board. Movement comes from ElevatorTransport and the travel bake.
791
+ function useTransport(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
792
+ const lockCheck = checkGoLock(go, ctx);
793
+ if (!lockCheck.ok) {
794
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'transport' };
795
+ }
796
+ return { ok: true, kind: 'transport', state: 'activated' };
797
+ }
798
+
799
+ // SUMMONING_RITUAL Use — the grouped channel. Cite: GameObject.cpp:1772–1829 AddUniqueUse, the
800
+ // animation and channel casts, and the participant count against reqParticipants.
801
+ function useSummoningRitual(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
802
+ const kind: UseGameObjectKind = 'summoning_ritual';
803
+ if (go.type !== GAMEOBJECT_TYPE_SUMMONING_RITUAL) {
804
+ return { ok: false, reason: 'unsupported', kind: 'unsupported' };
805
+ }
806
+ const ritual = go.summoningRitual ?? {};
807
+ const delayUntil = ctx.delayedActionUntilMs ?? ctx.runtime?.delayedActionUntilMs;
808
+ if (delayUntil != null && delayUntil > ctx.nowMs) {
809
+ return { ok: false, reason: 'not_ready', kind };
810
+ }
811
+
812
+ const userId = ctx.userId ?? 'player';
813
+ const unique = new Set(ctx.uniqueUserIds ?? ctx.runtime?.uniqueUsers ?? []);
814
+ const firstUser = ctx.firstUser ?? ctx.runtime?.firstUser;
815
+
816
+ if (ctx.hasOwner) {
817
+ // Owner already counted in EffectTransmitted; cannot Use again.
818
+ // Cite: GameObject.cpp:1791–1793; SpellEffects.cpp:5374 AddUniqueUse(caster).
819
+ if (ctx.isOwner) return { ok: false, reason: 'is_owner', kind };
820
+ if (ritual.castersGrouped && !ctx.inGroup) {
821
+ return { ok: false, reason: 'not_in_group', kind };
822
+ }
823
+ if (!ctx.ownerChanneling) {
824
+ return { ok: false, reason: 'owner_not_channeling', kind };
825
+ }
826
+ } else if (
827
+ firstUser
828
+ && firstUser !== userId
829
+ && ritual.castersGrouped
830
+ && !ctx.inGroup
831
+ ) {
832
+ // Cite: GameObject.cpp:1801–1810 — later users must share firstUser's group.
833
+ return { ok: false, reason: 'not_in_group', kind };
834
+ }
835
+
836
+ unique.add(userId);
837
+ const nextFirst = firstUser ?? userId;
838
+ const uniqueUseCount = unique.size;
839
+ const reqParticipants = (ritual.reqParticipants ?? 0) | 0;
840
+ const anim = (ritual.animSpell ?? 0) | 0;
841
+ const goSpell = (ctx.goSpellId ?? 0) | 0;
842
+ const channelSpellId = anim > 0 ? anim : goSpell > 0 ? goSpell : undefined;
843
+ const ready = uniqueUseCount >= reqParticipants;
844
+ const persist = ritual.ritualPersistent === true;
845
+ // Custom delay is CustomData1 — not baked. No delay → TriggerSummoningRitual now.
846
+ // Cite: GameObject.cpp:1824–1827; GameObject.h:359–363 summoningRitualCustom.delay.
847
+
848
+ return {
849
+ ok: true,
850
+ kind,
851
+ channelSpellId,
852
+ ritualSpellId: ready && ((ritual.spellId ?? 0) | 0) > 0 ? ritual.spellId : undefined,
853
+ uniqueUseCount,
854
+ reqParticipants,
855
+ ritualReady: ready,
856
+ uniqueUserIds: ready && persist ? [] : [...unique],
857
+ firstUser: ready && persist ? undefined : nextFirst,
858
+ despawn: ready && !persist ? true : undefined,
859
+ state: ready ? (persist ? 'ready' : 'just_deactivated') : 'activated',
860
+ };
861
+ }
862
+
863
+ // The player's Use plus the remaining group members as unique channelers. The C++ needs each player
864
+ // to click; companions have no click, so one Use joins the whole group.
865
+ export function useSummoningRitualParty(
866
+ go: GameObjectDef,
867
+ ctx: UseGameObjectCtx & { partyUserIds?: readonly string[] },
868
+ ): UseGameObjectResult {
869
+ const party = ctx.partyUserIds && ctx.partyUserIds.length > 0
870
+ ? ctx.partyUserIds
871
+ : [ctx.userId ?? 'player'];
872
+ let last = useGameObject(go, { ...ctx, userId: party[0] });
873
+ if (!last.ok || !go.summoningRitual?.castersGrouped) return last;
874
+ for (let i = 1; i < party.length; i++) {
875
+ if (last.ritualReady) break;
876
+ last = useGameObject(go, {
877
+ ...ctx,
878
+ userId: party[i],
879
+ inGroup: true,
880
+ uniqueUserIds: last.uniqueUserIds,
881
+ firstUser: last.firstUser,
882
+ });
883
+ if (!last.ok) return last;
884
+ }
885
+ return last;
886
+ }
887
+
888
+ /** GameObject.cpp:1569-1575 — Use is only TriggerLinkedGameObject (GetLinkedGameObjectEntry :474). */
889
+ function useSpellFocus(go: GameObjectDef): UseGameObjectResult {
890
+ return {
891
+ ok: true,
892
+ kind: 'spell_focus',
893
+ linkedTrapId: go.spellFocus?.linkedTrapId,
894
+ questCredit: false,
895
+ state: 'activated',
896
+ };
897
+ }
898
+
899
+ /** TriggerLinkedGameObject — Use the linked trap template. Cite: GameObject.cpp:1273-1303. */
900
+ export function applyLinkedTrap(
901
+ result: UseGameObjectResult,
902
+ trapGo: GameObjectDef | undefined,
903
+ ctx: Pick<UseGameObjectCtx, 'nowMs' | 'runtime'>,
904
+ ): UseGameObjectResult {
905
+ if (!result.ok || !result.linkedTrapId) return result;
906
+ if (!trapGo || trapGo.entry !== result.linkedTrapId || trapGo.type !== GAMEOBJECT_TYPE_TRAP) {
907
+ return result;
908
+ }
909
+ const trapUsed = triggerTrap(trapGo, ctx);
910
+ if (!trapUsed.ok) return result;
911
+ return { ...result, castSpellId: trapUsed.castSpellId ?? result.castSpellId };
912
+ }
913
+
914
+ function useFishingHole(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
915
+ // FISHINGHOLE: the loot id is data1. The school's open counter finishes it — AddUse, then a use
916
+ // count at or past urand(minSuccessOpens, maxSuccessOpens) deactivates the hole.
917
+ const lockCheck = checkGoLock(go, ctx);
918
+ if (!lockCheck.ok) {
919
+ return { ok: false, reason: lockRefuseReason(lockCheck), kind: 'fishinghole' };
920
+ }
921
+ // Already despawned / restocking (prior open hit min/maxSuccessOpens).
922
+ if (ctx.runtime?.readyAtMs != null && ctx.runtime.readyAtMs > ctx.nowMs) {
923
+ return {
924
+ ok: false,
925
+ reason: 'not_ready',
926
+ kind: 'fishinghole',
927
+ restockAtMs: ctx.runtime.readyAtMs,
928
+ state: 'not_ready',
929
+ };
930
+ }
931
+ const hole = go.fishinghole;
932
+ const minOpens = hole?.minSuccessOpens != null && hole.minSuccessOpens > 0 ? hole.minSuccessOpens : 1;
933
+ const maxOpens = hole?.maxSuccessOpens != null && hole.maxSuccessOpens >= minOpens
934
+ ? hole.maxSuccessOpens
935
+ : minOpens;
936
+ const prevUses = ctx.runtime?.uses ?? 0;
937
+ const newUses = prevUses + 1;
938
+ // Re-roll threshold each finish (exact CMaNGOS: urand each loot, not a fixed charge pool).
939
+ const threshold = ctx.rng ? ctx.rng.int(minOpens, maxOpens) : maxOpens;
940
+ const depleted = newUses >= threshold;
941
+ const lootId = hole?.lootId ?? go.lootId;
942
+ return {
943
+ ok: true,
944
+ kind: 'fishinghole',
945
+ lootId,
946
+ // Reuse trapUses slot for school open count (goRuntime.uses).
947
+ trapUses: newUses,
948
+ despawn: depleted || undefined,
949
+ state: depleted ? 'just_deactivated' : 'activated',
950
+ };
951
+ }
952
+
953
+ /** GAMEOBJECT_TYPE_SPELLCASTER Use — spellId + charges. Cite: GameObject.cpp:1831–1859, :1952–1970, :508–513. */
954
+ function useSpellcaster(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
955
+ const kind: UseGameObjectKind = 'spellcaster';
956
+ if (go.type !== GAMEOBJECT_TYPE_SPELLCASTER) {
957
+ return { ok: false, reason: 'unsupported', kind: 'unsupported' };
958
+ }
959
+ const info = go.spellcaster;
960
+ const spellId = info?.spellId ?? 0;
961
+ if (!spellId) {
962
+ return { ok: false, reason: 'unsupported', kind };
963
+ }
964
+ if (info?.partyOnly && ctx.inOwnerGroup === false) {
965
+ return { ok: false, reason: 'party_only', kind };
966
+ }
967
+ const maxCharges = info?.charges ?? 0;
968
+ const uses = ctx.runtime?.uses ?? 0;
969
+ if (maxCharges > 0 && uses >= maxCharges) {
970
+ return { ok: false, reason: 'no_charges', kind, trapUses: uses, despawn: true };
971
+ }
972
+ const newUses = uses + 1;
973
+ const exhausted = maxCharges > 0 && newUses >= maxCharges;
974
+ return {
975
+ ok: true,
976
+ kind,
977
+ castSpellId: spellId,
978
+ trapUses: newUses,
979
+ despawn: exhausted || undefined,
980
+ state: exhausted ? 'just_deactivated' : 'activated',
981
+ };
982
+ }
983
+
984
+ /** GAMEOBJECT_TYPE_MEETINGSTONE Use — group target + level gate, then spell 23598. Cite: GameObject.cpp:1864–1892. */
985
+ function useMeetingStone(go: GameObjectDef, ctx: UseGameObjectCtx): UseGameObjectResult {
986
+ const kind: UseGameObjectKind = 'meetingstone';
987
+ if (go.type !== GAMEOBJECT_TYPE_MEETINGSTONE || !go.meetingstone) {
988
+ return { ok: false, reason: 'unsupported', kind: 'unsupported' };
989
+ }
990
+ // Cite: GameObject.cpp:1876–1877 — !target || target == player || !IsInGroup → return.
991
+ if (!ctx.hasGroupTarget) {
992
+ return { ok: false, reason: 'no_target', kind };
993
+ }
994
+ const minL = go.meetingstone.minLevel ?? 0;
995
+ const maxL = go.meetingstone.maxLevel ?? 0;
996
+ const playerLevel = ctx.playerLevel;
997
+ const targetLevel = ctx.targetLevel;
998
+ if (playerLevel == null || targetLevel == null) {
999
+ return { ok: false, reason: 'missing_context', kind };
1000
+ }
1001
+ // Cite: GameObject.cpp:1880–1886 — both players must be within [minLevel, maxLevel].
1002
+ if (playerLevel < minL || playerLevel > maxL || targetLevel < minL || targetLevel > maxL) {
1003
+ return { ok: false, reason: 'level_out_of_range', kind };
1004
+ }
1005
+ return {
1006
+ ok: true,
1007
+ kind,
1008
+ castSpellId: MEETINGSTONE_SUMMON_SPELL_ID,
1009
+ state: 'activated',
1010
+ };
1011
+ }
1012
+
1013
+ /** Types not implemented in this pure engine (explicit gaps for H2+). Do not silently treat as chests. */
1014
+ export const UNSUPPORTED_GO_TYPES: ReadonlyArray<{ type: number; name: string }> = [
1015
+ // QUESTGIVER is implemented (FO2) — not listed here.
1016
+ { type: GAMEOBJECT_TYPE_BINDER, name: 'BINDER' },
1017
+ { type: GAMEOBJECT_TYPE_GENERIC, name: 'GENERIC' },
1018
+ { type: GAMEOBJECT_TYPE_CHAIR, name: 'CHAIR' },
1019
+ { type: GAMEOBJECT_TYPE_TEXT, name: 'TEXT' },
1020
+ { type: GAMEOBJECT_TYPE_AREADAMAGE, name: 'AREADAMAGE' },
1021
+ { type: GAMEOBJECT_TYPE_CAMERA, name: 'CAMERA' },
1022
+ { type: GAMEOBJECT_TYPE_MAP_OBJECT, name: 'MAP_OBJECT' },
1023
+ { type: GAMEOBJECT_TYPE_DUEL_ARBITER, name: 'DUEL_ARBITER' },
1024
+ { type: GAMEOBJECT_TYPE_MAILBOX, name: 'MAILBOX' },
1025
+ { type: GAMEOBJECT_TYPE_SUMMONING_RITUAL, name: 'SUMMONING_RITUAL' },
1026
+ { type: GAMEOBJECT_TYPE_AUCTIONHOUSE, name: 'AUCTIONHOUSE' },
1027
+ { type: GAMEOBJECT_TYPE_GUARDPOST, name: 'GUARDPOST' },
1028
+ { type: GAMEOBJECT_TYPE_FLAGSTAND, name: 'FLAGSTAND' },
1029
+ { type: GAMEOBJECT_TYPE_FLAGDROP, name: 'FLAGDROP' },
1030
+ ];