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.
- package/README.md +138 -2
- package/bin/azsh.mjs +19 -0
- package/docs/aifid/eventai-texts.json +4414 -0
- package/docs/dungeons/atlas/atlas-rows-dungeons.json +8989 -0
- package/docs/dungeons/survey/pack-id-migration.json +2418 -0
- package/package.json +35 -4
- package/src/autopilot/bossSkip.ts +26 -0
- package/src/autopilot/combatRotation.ts +824 -0
- package/src/autopilot/config.ts +533 -0
- package/src/autopilot/consumables.ts +58 -0
- package/src/autopilot/encounterStand.ts +121 -0
- package/src/autopilot/objectGatePlan.ts +53 -0
- package/src/autopilot/pathEngage.ts +229 -0
- package/src/autopilot/plan.ts +1643 -0
- package/src/autopilot/questPolicy.ts +274 -0
- package/src/autopilot/routeStep.ts +69 -0
- package/src/autopilot/sessionReport.ts +88 -0
- package/src/autopilot/topOffPower.ts +26 -0
- package/src/autopilot/view.ts +476 -0
- package/src/cli/bootCheck.mjs +34 -0
- package/src/cli/bootData.mjs +57 -0
- package/src/cli/combatLogFilter.ts +153 -0
- package/src/cli/combatLogFormat.ts +613 -0
- package/src/cli/fileRepository.mjs +105 -0
- package/src/cli/gzLoader.mjs +31 -0
- package/src/cli/liveGauntletEscort.ts +978 -0
- package/src/cli/liveStratUndead.ts +305 -0
- package/src/cli/macroHostCombat.ts +545 -0
- package/src/cli/macroHostWorld.ts +330 -0
- package/src/cli/prefs.mjs +31 -0
- package/src/cli/register.mjs +4 -0
- package/src/cli/repl.mjs +693 -0
- package/src/cli/rotationText.mjs +226 -0
- package/src/cli/squad.mjs +105 -0
- package/src/cli/term.mjs +144 -0
- package/src/cli/text.mjs +122 -0
- package/src/cli/tui.mjs +626 -0
- package/src/cli/tuiArena.mjs +109 -0
- package/src/cli/tuiAutopilotSettings.mjs +93 -0
- package/src/cli/tuiBags.mjs +180 -0
- package/src/cli/tuiBars.mjs +133 -0
- package/src/cli/tuiBg.mjs +243 -0
- package/src/cli/tuiBulk.mjs +162 -0
- package/src/cli/tuiCheck.mjs +1882 -0
- package/src/cli/tuiCity.mjs +396 -0
- package/src/cli/tuiCompanionKit.mjs +300 -0
- package/src/cli/tuiCompanions.mjs +471 -0
- package/src/cli/tuiDev.mjs +62 -0
- package/src/cli/tuiDungeon.mjs +606 -0
- package/src/cli/tuiEnchantTarget.mjs +120 -0
- package/src/cli/tuiFight.mjs +577 -0
- package/src/cli/tuiFightPanes.mjs +228 -0
- package/src/cli/tuiFloor.mjs +506 -0
- package/src/cli/tuiGear.mjs +158 -0
- package/src/cli/tuiHonor.mjs +74 -0
- package/src/cli/tuiLoot.mjs +97 -0
- package/src/cli/tuiMacros.mjs +144 -0
- package/src/cli/tuiOutfitter.mjs +115 -0
- package/src/cli/tuiPet.mjs +116 -0
- package/src/cli/tuiProfessions.mjs +800 -0
- package/src/cli/tuiRaid.mjs +127 -0
- package/src/cli/tuiRep.mjs +65 -0
- package/src/cli/tuiSaves.mjs +69 -0
- package/src/cli/tuiSearch.mjs +363 -0
- package/src/cli/tuiSettings.mjs +151 -0
- package/src/cli/tuiSimLab.mjs +80 -0
- package/src/cli/tuiTalents.mjs +60 -0
- package/src/cli/tuiViews.mjs +1178 -0
- package/src/cli/tuiWiki.mjs +181 -0
- package/src/cli/tuiWorld.mjs +361 -0
- package/src/cli/wikiIndex.ts +259 -0
- package/src/cli/wikiSources.ts +355 -0
- package/src/data/alteracValley.ts +176 -0
- package/src/data/appearanceOptions.ts +534 -0
- package/src/data/applyLootChanceSanity.ts +21 -0
- package/src/data/createFlavor.ts +96 -0
- package/src/data/customItems.ts +33 -0
- package/src/data/dataStore.ts +1904 -0
- package/src/data/dungeonGameObjects.ts +84 -0
- package/src/data/dungeonPlateCover.ts +66 -0
- package/src/data/dungeonSpawns.ts +294 -0
- package/src/data/dungeons/alterac-valley.ts +135 -0
- package/src/data/dungeons/apply-dungeon-rooms.ts +29 -0
- package/src/data/dungeons/apply-encounter-outdoors.ts +72 -0
- package/src/data/dungeons/apply-instance-geometry.ts +65 -0
- package/src/data/dungeons/apply-spawn-placement.ts +171 -0
- package/src/data/dungeons/blackfathom-deeps.ts +539 -0
- package/src/data/dungeons/blackrock-depths.ts +1410 -0
- package/src/data/dungeons/blackwing-lair.ts +129 -0
- package/src/data/dungeons/boss-eventai.ts +8 -0
- package/src/data/dungeons/deadmines.ts +410 -0
- package/src/data/dungeons/dire-maul-east.ts +980 -0
- package/src/data/dungeons/dire-maul-north.ts +661 -0
- package/src/data/dungeons/dire-maul-west.ts +785 -0
- package/src/data/dungeons/dungeon-rooms.json +5479 -0
- package/src/data/dungeons/encounter-outdoors.json +359 -0
- package/src/data/dungeons/eventai/blackfathom-deeps.ts +308 -0
- package/src/data/dungeons/eventai/blackrock-depths.ts +1257 -0
- package/src/data/dungeons/eventai/deadmines.ts +264 -0
- package/src/data/dungeons/eventai/dire-maul-east.ts +320 -0
- package/src/data/dungeons/eventai/gnomeregan.ts +213 -0
- package/src/data/dungeons/eventai/helpers.ts +79 -0
- package/src/data/dungeons/eventai/index.ts +133 -0
- package/src/data/dungeons/eventai/lbrs.ts +372 -0
- package/src/data/dungeons/eventai/maraudon.ts +323 -0
- package/src/data/dungeons/eventai/ragefire-chasm.ts +108 -0
- package/src/data/dungeons/eventai/razorfen-downs.ts +207 -0
- package/src/data/dungeons/eventai/razorfen-kraul.ts +326 -0
- package/src/data/dungeons/eventai/scholomance.ts +680 -0
- package/src/data/dungeons/eventai/shadowfang-keep.ts +230 -0
- package/src/data/dungeons/eventai/sm-cathedral.ts +75 -0
- package/src/data/dungeons/eventai/sm-graveyard.ts +150 -0
- package/src/data/dungeons/eventai/sm-library.ts +55 -0
- package/src/data/dungeons/eventai/stratholme-undead.ts +127 -0
- package/src/data/dungeons/eventai/sunken-temple.ts +582 -0
- package/src/data/dungeons/eventai/the-stockade.ts +228 -0
- package/src/data/dungeons/eventai/ubrs.ts +225 -0
- package/src/data/dungeons/eventai/uldaman.ts +355 -0
- package/src/data/dungeons/eventai/wailing-caverns.ts +396 -0
- package/src/data/dungeons/eventai/zul-farrak.ts +591 -0
- package/src/data/dungeons/gnomeregan.ts +909 -0
- package/src/data/dungeons/index.ts +126 -0
- package/src/data/dungeons/instance-geometry.json +5233 -0
- package/src/data/dungeons/key-sources.json +169 -0
- package/src/data/dungeons/lbrs.ts +996 -0
- package/src/data/dungeons/maraudon.ts +786 -0
- package/src/data/dungeons/molten-core.ts +194 -0
- package/src/data/dungeons/naxxramas.ts +173 -0
- package/src/data/dungeons/onyxias-lair.ts +71 -0
- package/src/data/dungeons/pack-from-clusters.ts +1256 -0
- package/src/data/dungeons/ragefire-chasm.ts +238 -0
- package/src/data/dungeons/razorfen-downs.ts +698 -0
- package/src/data/dungeons/razorfen-kraul.ts +766 -0
- package/src/data/dungeons/ruins-of-ahnqiraj.ts +121 -0
- package/src/data/dungeons/scholomance.ts +1076 -0
- package/src/data/dungeons/shadowfang-keep.ts +740 -0
- package/src/data/dungeons/sm-armory.ts +266 -0
- package/src/data/dungeons/sm-cathedral.ts +430 -0
- package/src/data/dungeons/sm-graveyard.ts +482 -0
- package/src/data/dungeons/sm-library.ts +337 -0
- package/src/data/dungeons/stratholme-live.ts +808 -0
- package/src/data/dungeons/stratholme-undead.ts +1164 -0
- package/src/data/dungeons/sunken-temple.ts +931 -0
- package/src/data/dungeons/temple-of-ahnqiraj.ts +119 -0
- package/src/data/dungeons/the-stockade.ts +282 -0
- package/src/data/dungeons/ubrs.ts +1286 -0
- package/src/data/dungeons/uldaman.ts +685 -0
- package/src/data/dungeons/wailing-caverns.ts +356 -0
- package/src/data/dungeons/zul-farrak.ts +686 -0
- package/src/data/dungeons/zul-gurub.ts +142 -0
- package/src/data/dungeons.ts +42 -0
- package/src/data/fixtures.ts +446 -0
- package/src/data/gameobject-data.json.gz +0 -0
- package/src/data/item-data.json.gz +0 -0
- package/src/data/loot-data.json.gz +0 -0
- package/src/data/maps/atlas-approach-maps.json +1425 -0
- package/src/data/maps/atlas-landmarks.json +1711 -0
- package/src/data/maps/dungeon-viewports.json +392 -0
- package/src/data/materializeModDamagePercentTaken.ts +70 -0
- package/src/data/materializeModHealthRegen.ts +89 -0
- package/src/data/materializeSpellReputation.ts +26 -0
- package/src/data/pageTexts.ts +19 -0
- package/src/data/profession-data.json.gz +0 -0
- package/src/data/raid-plans/blackfathom-deeps.json +86 -0
- package/src/data/raid-plans/blackrock-depths.json +419 -0
- package/src/data/raid-plans/blackwing-lair.json +328 -0
- package/src/data/raid-plans/deadmines.json +55 -0
- package/src/data/raid-plans/dire-maul-east.json +94 -0
- package/src/data/raid-plans/dire-maul-north.json +70 -0
- package/src/data/raid-plans/dire-maul-west.json +75 -0
- package/src/data/raid-plans/gnomeregan.json +131 -0
- package/src/data/raid-plans/lbrs.json +176 -0
- package/src/data/raid-plans/maraudon.json +102 -0
- package/src/data/raid-plans/molten-core.json +169 -0
- package/src/data/raid-plans/naxxramas.json +354 -0
- package/src/data/raid-plans/onyxias-lair.json +18 -0
- package/src/data/raid-plans/ragefire-chasm.json +30 -0
- package/src/data/raid-plans/razorfen-downs.json +75 -0
- package/src/data/raid-plans/razorfen-kraul.json +53 -0
- package/src/data/raid-plans/ruins-of-ahnqiraj.json +110 -0
- package/src/data/raid-plans/scholomance.json +170 -0
- package/src/data/raid-plans/shadowfang-keep.json +87 -0
- package/src/data/raid-plans/sm-armory.json +53 -0
- package/src/data/raid-plans/sm-cathedral.json +72 -0
- package/src/data/raid-plans/sm-graveyard.json +63 -0
- package/src/data/raid-plans/sm-library.json +23 -0
- package/src/data/raid-plans/stratholme-live.json +129 -0
- package/src/data/raid-plans/stratholme-undead.json +73 -0
- package/src/data/raid-plans/sunken-temple.json +159 -0
- package/src/data/raid-plans/temple-of-ahnqiraj.json +163 -0
- package/src/data/raid-plans/the-stockade.json +42 -0
- package/src/data/raid-plans/ubrs.json +53 -0
- package/src/data/raid-plans/uldaman.json +131 -0
- package/src/data/raid-plans/wailing-caverns.json +90 -0
- package/src/data/raid-plans/zul-farrak.json +156 -0
- package/src/data/raid-plans/zul-gurub.json +307 -0
- package/src/data/raidInstanceCreatures.mjs +473 -0
- package/src/data/rotations/index.ts +152 -0
- package/src/data/rotations/layout.mjs +72 -0
- package/src/data/rotations/pve/druid/balance.json +754 -0
- package/src/data/rotations/pve/druid/feral-tank.json +2448 -0
- package/src/data/rotations/pve/druid/feral.json +2660 -0
- package/src/data/rotations/pve/druid/restoration.json +424 -0
- package/src/data/rotations/pve/hunter/beast-mastery.json +1288 -0
- package/src/data/rotations/pve/hunter/marksmanship.json +1260 -0
- package/src/data/rotations/pve/hunter/survival.json +1373 -0
- package/src/data/rotations/pve/mage/arcane-leveling.json +1798 -0
- package/src/data/rotations/pve/mage/fire-leveling.json +2003 -0
- package/src/data/rotations/pve/mage/frost-leveling.json +1912 -0
- package/src/data/rotations/pve/paladin/holy.json +755 -0
- package/src/data/rotations/pve/paladin/protection.json +962 -0
- package/src/data/rotations/pve/paladin/retribution.json +924 -0
- package/src/data/rotations/pve/priest/discipline.json +772 -0
- package/src/data/rotations/pve/priest/holy.json +707 -0
- package/src/data/rotations/pve/priest/shadow.json +787 -0
- package/src/data/rotations/pve/rogue/assassination.json +2477 -0
- package/src/data/rotations/pve/rogue/combat.json +2483 -0
- package/src/data/rotations/pve/rogue/subtlety.json +2523 -0
- package/src/data/rotations/pve/shaman/elemental.json +1157 -0
- package/src/data/rotations/pve/shaman/enhancement.json +1085 -0
- package/src/data/rotations/pve/shaman/restoration.json +592 -0
- package/src/data/rotations/pve/warlock/affliction.json +1185 -0
- package/src/data/rotations/pve/warlock/demonology.json +1165 -0
- package/src/data/rotations/pve/warlock/destruction.json +1177 -0
- package/src/data/rotations/pve/warrior/arms.json +3020 -0
- package/src/data/rotations/pve/warrior/fury.json +2996 -0
- package/src/data/rotations/pve/warrior/protection.json +2509 -0
- package/src/data/rotations/pvp/druid/balance.json +593 -0
- package/src/data/rotations/pvp/druid/feral.json +3276 -0
- package/src/data/rotations/pvp/druid/restoration.json +662 -0
- package/src/data/rotations/pvp/hunter/beast-mastery.json +665 -0
- package/src/data/rotations/pvp/hunter/marksmanship.json +2406 -0
- package/src/data/rotations/pvp/hunter/survival.json +635 -0
- package/src/data/rotations/pvp/mage/arcane.json +574 -0
- package/src/data/rotations/pvp/mage/fire.json +570 -0
- package/src/data/rotations/pvp/mage/frost.json +4048 -0
- package/src/data/rotations/pvp/paladin/holy.json +1498 -0
- package/src/data/rotations/pvp/paladin/protection.json +567 -0
- package/src/data/rotations/pvp/paladin/retribution.json +1110 -0
- package/src/data/rotations/pvp/priest/discipline.json +1848 -0
- package/src/data/rotations/pvp/priest/holy.json +6340 -0
- package/src/data/rotations/pvp/priest/shadow.json +2329 -0
- package/src/data/rotations/pvp/rogue/assassination.json +1322 -0
- package/src/data/rotations/pvp/rogue/combat.json +5258 -0
- package/src/data/rotations/pvp/rogue/subtlety.json +586 -0
- package/src/data/rotations/pvp/shaman/elemental.json +1404 -0
- package/src/data/rotations/pvp/shaman/enhancement.json +1277 -0
- package/src/data/rotations/pvp/shaman/restoration.json +2490 -0
- package/src/data/rotations/pvp/warlock/affliction.json +1017 -0
- package/src/data/rotations/pvp/warlock/demonology.json +1503 -0
- package/src/data/rotations/pvp/warlock/destruction.json +638 -0
- package/src/data/rotations/pvp/warrior/arms.json +5665 -0
- package/src/data/rotations/pvp/warrior/fury.json +850 -0
- package/src/data/rotations/pvp/warrior/protection.json +777 -0
- package/src/data/schema/bundle.ts +511 -0
- package/src/data/schema/constants.ts +49 -0
- package/src/data/schema/creature.ts +454 -0
- package/src/data/schema/encounter.ts +155 -0
- package/src/data/schema/faction.ts +48 -0
- package/src/data/schema/item.ts +297 -0
- package/src/data/schema/itemEnchant.ts +105 -0
- package/src/data/schema/npc.ts +44 -0
- package/src/data/schema/primitives.ts +295 -0
- package/src/data/schema/profession.ts +226 -0
- package/src/data/schema/quest.ts +154 -0
- package/src/data/schema/spell.ts +1149 -0
- package/src/data/schema/talent.ts +74 -0
- package/src/data/schema/world.ts +124 -0
- package/src/data/schema.ts +19 -0
- package/src/data/skinNodeGapFill.ts +68 -0
- package/src/data/spell-data.json.gz +0 -0
- package/src/data/spell-script-targets.json +1 -0
- package/src/data/tables/ahItemValues.json.gz +0 -0
- package/src/data/tables/alteracValley.json.gz +0 -0
- package/src/data/tables/areatriggerTeleports.json.gz +0 -0
- package/src/data/tables/botNames.json.gz +0 -0
- package/src/data/tables/botPopulation.json.gz +0 -0
- package/src/data/tables/botSpecs.json.gz +0 -0
- package/src/data/tables/classLevelStats.json.gz +0 -0
- package/src/data/tables/combatConditions.json.gz +0 -0
- package/src/data/tables/combatSkillMeta.json.gz +0 -0
- package/src/data/tables/conditions.json.gz +0 -0
- package/src/data/tables/createInfo.json.gz +0 -0
- package/src/data/tables/creatureAggroGroups.json.gz +0 -0
- package/src/data/tables/creatureClassLevelStats.json.gz +0 -0
- package/src/data/tables/creaturePatrolPacks.json.gz +0 -0
- package/src/data/tables/creatureWeapons.json.gz +0 -0
- package/src/data/tables/creatures.json.gz +0 -0
- package/src/data/tables/dbScripts.json.gz +0 -0
- package/src/data/tables/dungeonAuthoredRoutes.json.gz +0 -0
- package/src/data/tables/dungeonCensus.json.gz +0 -0
- package/src/data/tables/dungeonGameObjects.json.gz +0 -0
- package/src/data/tables/dungeonPacks.json.gz +0 -0
- package/src/data/tables/dungeonPlateCover.json.gz +0 -0
- package/src/data/tables/dungeonSpawns.json.gz +0 -0
- package/src/data/tables/dungeonSurvey.json.gz +0 -0
- package/src/data/tables/durabilityCosts.json.gz +0 -0
- package/src/data/tables/durabilityQuality.json.gz +0 -0
- package/src/data/tables/enchantApplicators.json.gz +0 -0
- package/src/data/tables/entranceYards.json.gz +0 -0
- package/src/data/tables/explorationBasexp.json.gz +0 -0
- package/src/data/tables/factionTemplates.json.gz +0 -0
- package/src/data/tables/factions.json.gz +0 -0
- package/src/data/tables/gameEvents.json.gz +0 -0
- package/src/data/tables/gameObjects.json.gz +0 -0
- package/src/data/tables/gossipMenus.json.gz +0 -0
- package/src/data/tables/graveyards.json.gz +0 -0
- package/src/data/tables/instanceMaps.json.gz +0 -0
- package/src/data/tables/itemEnchantmentTemplates.json.gz +0 -0
- package/src/data/tables/itemEnchants.json.gz +0 -0
- package/src/data/tables/itemRandomProperties.json.gz +0 -0
- package/src/data/tables/itemSets.json.gz +0 -0
- package/src/data/tables/items.json.gz +0 -0
- package/src/data/tables/levelStats.json.gz +0 -0
- package/src/data/tables/locks.json.gz +0 -0
- package/src/data/tables/map-pin-overrides.json.gz +0 -0
- package/src/data/tables/nonCombatTrash.json.gz +0 -0
- package/src/data/tables/npcTexts.json.gz +0 -0
- package/src/data/tables/pageTexts.json.gz +0 -0
- package/src/data/tables/petAbilityTP.json.gz +0 -0
- package/src/data/tables/petGenericSpells.json.gz +0 -0
- package/src/data/tables/petLevelStats.json.gz +0 -0
- package/src/data/tables/playerbot-weightscales.json.gz +0 -0
- package/src/data/tables/pools.json.gz +0 -0
- package/src/data/tables/quests.json.gz +0 -0
- package/src/data/tables/races.json.gz +0 -0
- package/src/data/tables/reputationRanks.json.gz +0 -0
- package/src/data/tables/reputationRates.json.gz +0 -0
- package/src/data/tables/reputationSpillover.json.gz +0 -0
- package/src/data/tables/ridingSpells.json.gz +0 -0
- package/src/data/tables/scriptTexts.json.gz +0 -0
- package/src/data/tables/soundClipVolume.json.gz +0 -0
- package/src/data/tables/spellChain.json.gz +0 -0
- package/src/data/tables/spellTeleports.json.gz +0 -0
- package/src/data/tables/spells.json.gz +0 -0
- package/src/data/tables/talents.json.gz +0 -0
- package/src/data/tables/tavernTriggers.json.gz +0 -0
- package/src/data/tables/taxiNodes.json.gz +0 -0
- package/src/data/tables/taxiRoutes.json.gz +0 -0
- package/src/data/tables/trainers.json.gz +0 -0
- package/src/data/tables/transports.json.gz +0 -0
- package/src/data/tables/travelAnchors.json.gz +0 -0
- package/src/data/tables/travelEdges.json.gz +0 -0
- package/src/data/tables/unitConditions.json.gz +0 -0
- package/src/data/tables/vendors.json.gz +0 -0
- package/src/data/tables/weaponEnchantProcs.json.gz +0 -0
- package/src/data/tables/xp.json.gz +0 -0
- package/src/data/tables/zoneWeather.json.gz +0 -0
- package/src/data/tables/zones.json.gz +0 -0
- package/src/data/world-data.ts +56 -0
- package/src/data/zone-music-sets.json +2751 -0
- package/src/dev/etl/lib/loot-chance-sanity.mjs +180 -0
- package/src/domain/audioQuality.mjs +145 -0
- package/src/domain/bg/ab.ts +433 -0
- package/src/domain/bg/arenaComps.ts +644 -0
- package/src/domain/bg/arenaLab.ts +695 -0
- package/src/domain/bg/arenaPace.ts +31 -0
- package/src/domain/bg/arenaRating.ts +110 -0
- package/src/domain/bg/av.ts +758 -0
- package/src/domain/bg/avEnemyPush.ts +219 -0
- package/src/domain/bg/avField.ts +283 -0
- package/src/domain/bg/avInstanceNodes.ts +197 -0
- package/src/domain/bg/avInstanceScore.ts +123 -0
- package/src/domain/bg/avQuestItems.ts +55 -0
- package/src/domain/bg/avQuests.ts +210 -0
- package/src/domain/bg/avSession.ts +196 -0
- package/src/domain/bg/bgConsumes.ts +269 -0
- package/src/domain/bg/bgPrebuff.ts +153 -0
- package/src/domain/bg/bgRest.ts +91 -0
- package/src/domain/bg/bgRoster.ts +305 -0
- package/src/domain/bg/bgTier.ts +61 -0
- package/src/domain/bg/bgWorld.ts +862 -0
- package/src/domain/bg/match.ts +215 -0
- package/src/domain/bg/strategies.ts +552 -0
- package/src/domain/bg/types.ts +291 -0
- package/src/domain/bg/wsg.ts +264 -0
- package/src/domain/bots/actionProviderSpec.ts +38 -0
- package/src/domain/bots/autoConsumables.ts +285 -0
- package/src/domain/bots/betweenPullRest.ts +239 -0
- package/src/domain/bots/botGear.ts +248 -0
- package/src/domain/bots/botInventory.ts +486 -0
- package/src/domain/bots/botPet.ts +535 -0
- package/src/domain/bots/botPool.ts +291 -0
- package/src/domain/bots/botProfessions.ts +334 -0
- package/src/domain/bots/companionActionBar.ts +209 -0
- package/src/domain/bots/companionHireCost.ts +236 -0
- package/src/domain/bots/companionMissions.ts +582 -0
- package/src/domain/bots/companionPrep.ts +254 -0
- package/src/domain/bots/companionQuests.ts +270 -0
- package/src/domain/bots/companionRep.ts +75 -0
- package/src/domain/bots/companionRotation.ts +708 -0
- package/src/domain/bots/companionXp.ts +66 -0
- package/src/domain/bots/consumableShare.ts +811 -0
- package/src/domain/bots/dpsMate.ts +1072 -0
- package/src/domain/bots/groupCompReport.ts +132 -0
- package/src/domain/bots/healthstoneSupply.ts +198 -0
- package/src/domain/bots/outfitter.ts +1056 -0
- package/src/domain/bots/paladinPrePull.ts +231 -0
- package/src/domain/bots/partyRole.ts +40 -0
- package/src/domain/bots/playerbotEquipCache.ts +412 -0
- package/src/domain/bots/playerbotItemEligibility.ts +60 -0
- package/src/domain/bots/playerbotStatWeight.ts +853 -0
- package/src/domain/bots/playerbotUnavailableItems.ts +147 -0
- package/src/domain/bots/prePullBuffs.ts +219 -0
- package/src/domain/bots/prePullStealth.ts +82 -0
- package/src/domain/bots/runSupply.ts +251 -0
- package/src/domain/bots/runSupplyPrefs.ts +28 -0
- package/src/domain/bots/sendTradeGoods.ts +394 -0
- package/src/domain/bots/soulShardCap.ts +35 -0
- package/src/domain/bots/squad.ts +842 -0
- package/src/domain/bots/squadRun.ts +81 -0
- package/src/domain/character/actionbar.ts +346 -0
- package/src/domain/character/appearance.ts +165 -0
- package/src/domain/character/buildCombatant.ts +1726 -0
- package/src/domain/character/character.ts +356 -0
- package/src/domain/character/characterName.ts +43 -0
- package/src/domain/character/characterRatings.ts +424 -0
- package/src/domain/character/characterSpells.ts +282 -0
- package/src/domain/character/characterStats.ts +1559 -0
- package/src/domain/character/characterTalents.ts +398 -0
- package/src/domain/character/combatSkills.ts +994 -0
- package/src/domain/character/displayForm.ts +72 -0
- package/src/domain/character/formTalentAuras.ts +171 -0
- package/src/domain/character/forms.ts +499 -0
- package/src/domain/character/races.ts +40 -0
- package/src/domain/character/resurrectionSickness.ts +49 -0
- package/src/domain/character/spellbook.ts +169 -0
- package/src/domain/character/stanceBar.ts +354 -0
- package/src/domain/character/stancePrereq.ts +70 -0
- package/src/domain/character/talentBuilds.ts +63 -0
- package/src/domain/character/talentImport.ts +130 -0
- package/src/domain/character/talentLink.ts +123 -0
- package/src/domain/character/talents.ts +201 -0
- package/src/domain/core/conditionSnapshot.ts +92 -0
- package/src/domain/core/hover.ts +14 -0
- package/src/domain/core/ids.ts +58 -0
- package/src/domain/core/internalNameTags.ts +5 -0
- package/src/domain/core/runtimeDataPatches.ts +357 -0
- package/src/domain/creature/aiTargeting.ts +588 -0
- package/src/domain/creature/combatCondition.ts +157 -0
- package/src/domain/creature/creatureAggro.ts +804 -0
- package/src/domain/creature/creatureAi.ts +206 -0
- package/src/domain/creature/creatureAiConstants.ts +661 -0
- package/src/domain/creature/creatureCastList.ts +1007 -0
- package/src/domain/creature/creatureEventAi.ts +1409 -0
- package/src/domain/creature/creatureGroups.ts +144 -0
- package/src/domain/creature/creatureLinking.ts +333 -0
- package/src/domain/creature/creatureScaling.ts +320 -0
- package/src/domain/creature/creatureTrigger.ts +53 -0
- package/src/domain/creature/creatureWander.ts +74 -0
- package/src/domain/creature/eventAiTexts.ts +145 -0
- package/src/domain/creature/faction.ts +287 -0
- package/src/domain/creature/forcedReaction.ts +48 -0
- package/src/domain/creature/outdoorHuntable.ts +74 -0
- package/src/domain/creature/patrolPacks.ts +210 -0
- package/src/domain/creature/reputation.ts +967 -0
- package/src/domain/creature/unitFlags.ts +74 -0
- package/src/domain/creature/worldBosses.ts +393 -0
- package/src/domain/dungeonMusic.mjs +48 -0
- package/src/domain/economy/auction.ts +282 -0
- package/src/domain/economy/auctionBot.ts +1060 -0
- package/src/domain/economy/honorPrice.ts +100 -0
- package/src/domain/economy/mail.ts +958 -0
- package/src/domain/economy/money.ts +42 -0
- package/src/domain/economy/syntheticClassTrainers.ts +62 -0
- package/src/domain/economy/trading.ts +296 -0
- package/src/domain/economy/vendorSellAll.ts +252 -0
- package/src/domain/economy/vendorStock.ts +146 -0
- package/src/domain/items/ammo.ts +817 -0
- package/src/domain/items/bank.ts +162 -0
- package/src/domain/items/consumableFamily.ts +205 -0
- package/src/domain/items/craftUpgrades.ts +83 -0
- package/src/domain/items/createItem.ts +93 -0
- package/src/domain/items/durability.ts +581 -0
- package/src/domain/items/equipment.ts +441 -0
- package/src/domain/items/equipmentHelper.ts +767 -0
- package/src/domain/items/inventory.ts +561 -0
- package/src/domain/items/itemBonding.ts +93 -0
- package/src/domain/items/itemContainer.ts +245 -0
- package/src/domain/items/itemDisplayName.ts +33 -0
- package/src/domain/items/itemInstance.ts +181 -0
- package/src/domain/items/itemRandomEnchantOutcomes.ts +315 -0
- package/src/domain/items/itemRandomProps.ts +77 -0
- package/src/domain/items/itemRestrictions.ts +329 -0
- package/src/domain/items/itemTeaches.ts +82 -0
- package/src/domain/items/itemUseCooldown.ts +52 -0
- package/src/domain/items/itemUseTarget.ts +90 -0
- package/src/domain/items/junkCategories.ts +174 -0
- package/src/domain/items/junkFilter.ts +368 -0
- package/src/domain/items/keyring.ts +131 -0
- package/src/domain/items/loot.ts +221 -0
- package/src/domain/items/mounts.ts +190 -0
- package/src/domain/items/onUsePayload.ts +102 -0
- package/src/domain/items/pendingLoot.ts +107 -0
- package/src/domain/items/relic.ts +105 -0
- package/src/domain/items/rocketBoots.ts +36 -0
- package/src/domain/items/sortContainer.ts +139 -0
- package/src/domain/items/spareContainers.ts +71 -0
- package/src/domain/items/spellReagentIndex.ts +131 -0
- package/src/domain/items/staleConsumables.ts +66 -0
- package/src/domain/items/weaponSpender.ts +110 -0
- package/src/domain/listDungeonIds.mjs +28 -0
- package/src/domain/macro/compose.ts +239 -0
- package/src/domain/macro/conditions.ts +260 -0
- package/src/domain/macro/creatureTypes.ts +40 -0
- package/src/domain/macro/describe.ts +169 -0
- package/src/domain/macro/icon.ts +60 -0
- package/src/domain/macro/index.ts +20 -0
- package/src/domain/macro/normalize.ts +112 -0
- package/src/domain/macro/parse.ts +316 -0
- package/src/domain/macro/plan.ts +288 -0
- package/src/domain/macro/rotation.ts +590 -0
- package/src/domain/macro/rotationEnv.ts +173 -0
- package/src/domain/macro/slots.ts +101 -0
- package/src/domain/macro/snapshot.ts +114 -0
- package/src/domain/macro/templates.ts +446 -0
- package/src/domain/macro/types.ts +70 -0
- package/src/domain/macro/units.ts +93 -0
- package/src/domain/macro/weaponTypes.ts +83 -0
- package/src/domain/nav/cityTeleports.ts +10 -0
- package/src/domain/nav/mounting.ts +113 -0
- package/src/domain/nav/nav.ts +43 -0
- package/src/domain/nav/navCollision.ts +606 -0
- package/src/domain/nav/navOutdoors.ts +91 -0
- package/src/domain/nav/navRegistry.ts +179 -0
- package/src/domain/nav/navRoomGraph.ts +302 -0
- package/src/domain/nav/navTypes.ts +43 -0
- package/src/domain/nav/navmesh.ts +1715 -0
- package/src/domain/nav/speed.ts +200 -0
- package/src/domain/nav/storey.ts +10 -0
- package/src/domain/nav/travel.ts +725 -0
- package/src/domain/nav/travelTypes.ts +75 -0
- package/src/domain/pet/pet.ts +1150 -0
- package/src/domain/pet/petActionBar.ts +180 -0
- package/src/domain/pet/petSpellbook.ts +39 -0
- package/src/domain/pet/petStable.ts +81 -0
- package/src/domain/professions/autoDisenchant.ts +236 -0
- package/src/domain/professions/characterEnchants.ts +176 -0
- package/src/domain/professions/craftCooldown.ts +52 -0
- package/src/domain/professions/enchantApply.ts +62 -0
- package/src/domain/professions/enchantTargets.ts +114 -0
- package/src/domain/professions/enchanting.ts +236 -0
- package/src/domain/professions/gatherFilter.ts +149 -0
- package/src/domain/professions/gearEnchant.ts +137 -0
- package/src/domain/professions/heldTools.ts +29 -0
- package/src/domain/professions/learnAllRecipes.ts +146 -0
- package/src/domain/professions/miningHarvest.ts +69 -0
- package/src/domain/professions/partyDisenchant.ts +294 -0
- package/src/domain/professions/partyWork.ts +83 -0
- package/src/domain/professions/pickpocket.ts +172 -0
- package/src/domain/professions/poisons.ts +240 -0
- package/src/domain/professions/professions.ts +677 -0
- package/src/domain/professions/rareNodes.ts +45 -0
- package/src/domain/professions/skinLoot.ts +27 -0
- package/src/domain/professions/vendorReagents.ts +152 -0
- package/src/domain/professions/weaponImbueHand.ts +171 -0
- package/src/domain/questFarmFilter.mjs +42 -0
- package/src/domain/quests/doQuest.ts +1204 -0
- package/src/domain/quests/gossip.ts +308 -0
- package/src/domain/quests/gossipTalk.ts +298 -0
- package/src/domain/quests/interpreter/canComplete.ts +150 -0
- package/src/domain/quests/interpreter/claim.ts +137 -0
- package/src/domain/quests/interpreter/dbscript/handlers.ts +1371 -0
- package/src/domain/quests/interpreter/dbscript/handlersBatch.ts +1251 -0
- package/src/domain/quests/interpreter/dbscript/hooks.ts +331 -0
- package/src/domain/quests/interpreter/dbscript/index.ts +212 -0
- package/src/domain/quests/interpreter/dbscript/opcodes.ts +257 -0
- package/src/domain/quests/interpreter/dbscript/registry.ts +1194 -0
- package/src/domain/quests/interpreter/dbscript/registryAreatriggerScripts.ts +539 -0
- package/src/domain/quests/interpreter/dbscript/registryAshenvale.ts +553 -0
- package/src/domain/quests/interpreter/dbscript/registryAzshara.ts +272 -0
- package/src/domain/quests/interpreter/dbscript/registryDarkshore.ts +637 -0
- package/src/domain/quests/interpreter/dbscript/registryDesolace.ts +501 -0
- package/src/domain/quests/interpreter/dbscript/registryDustwallowMarsh.ts +735 -0
- package/src/domain/quests/interpreter/dbscript/registryFelwood.ts +493 -0
- package/src/domain/quests/interpreter/dbscript/registryFeralas.ts +485 -0
- package/src/domain/quests/interpreter/dbscript/registryGoScripts.ts +203 -0
- package/src/domain/quests/interpreter/dbscript/registryMoonglade.ts +288 -0
- package/src/domain/quests/interpreter/dbscript/registryNpcProfessions.ts +230 -0
- package/src/domain/quests/interpreter/dbscript/registryNpcsSpecial.ts +545 -0
- package/src/domain/quests/interpreter/dbscript/registryRazorfenDowns.ts +293 -0
- package/src/domain/quests/interpreter/dbscript/registryRazorfenKraul.ts +221 -0
- package/src/domain/quests/interpreter/dbscript/registryRedridge.ts +112 -0
- package/src/domain/quests/interpreter/dbscript/registrySearingGorge.ts +125 -0
- package/src/domain/quests/interpreter/dbscript/registrySiblings.ts +51 -0
- package/src/domain/quests/interpreter/dbscript/registrySilverpineForest.ts +172 -0
- package/src/domain/quests/interpreter/dbscript/registryStonetalonMountains.ts +180 -0
- package/src/domain/quests/interpreter/dbscript/registryStormwindCity.ts +369 -0
- package/src/domain/quests/interpreter/dbscript/registryStranglethornVale.ts +115 -0
- package/src/domain/quests/interpreter/dbscript/registryStratholme.ts +146 -0
- package/src/domain/quests/interpreter/dbscript/registrySunkenTemple.ts +149 -0
- package/src/domain/quests/interpreter/dbscript/registrySwampOfSorrows.ts +163 -0
- package/src/domain/quests/interpreter/dbscript/registryTanaris.ts +318 -0
- package/src/domain/quests/interpreter/dbscript/registryTeldrassil.ts +120 -0
- package/src/domain/quests/interpreter/dbscript/registryTheBarrens.ts +603 -0
- package/src/domain/quests/interpreter/dbscript/registryThousandNeedles.ts +499 -0
- package/src/domain/quests/interpreter/dbscript/registryTirisfalGlades.ts +222 -0
- package/src/domain/quests/interpreter/dbscript/registryUngoroCrater.ts +291 -0
- package/src/domain/quests/interpreter/dbscript/registryWarEffort.ts +773 -0
- package/src/domain/quests/interpreter/dbscript/registryWesternPlaguelands.ts +206 -0
- package/src/domain/quests/interpreter/dbscript/registryWestfall.ts +190 -0
- package/src/domain/quests/interpreter/dbscript/registryWetlands.ts +186 -0
- package/src/domain/quests/interpreter/dbscript/registryWinterspring.ts +235 -0
- package/src/domain/quests/interpreter/dbscript/types.ts +817 -0
- package/src/domain/quests/interpreter/dbscript/vm.ts +171 -0
- package/src/domain/quests/interpreter/diff.ts +349 -0
- package/src/domain/quests/interpreter/fixtures/oracle-questlog-qi2.json +2417 -0
- package/src/domain/quests/interpreter/flags.ts +101 -0
- package/src/domain/quests/interpreter/index.ts +113 -0
- package/src/domain/quests/interpreter/live.ts +178 -0
- package/src/domain/quests/interpreter/types.ts +81 -0
- package/src/domain/quests/interpreter/updaters.ts +412 -0
- package/src/domain/quests/questCorpseUse.ts +155 -0
- package/src/domain/quests/questDialog.ts +43 -0
- package/src/domain/quests/questFight.ts +34 -0
- package/src/domain/quests/questObjectiveLabel.ts +39 -0
- package/src/domain/quests/questRewardChoice.ts +85 -0
- package/src/domain/quests/questScriptCredit.ts +26 -0
- package/src/domain/quests/questScriptItemUse.ts +74 -0
- package/src/domain/quests/questTameRods.ts +79 -0
- package/src/domain/quests/questlog.ts +1545 -0
- package/src/domain/quests/talkDeliver.ts +170 -0
- package/src/domain/raid/globalActionBar.ts +195 -0
- package/src/domain/raid/instanceRoster.ts +194 -0
- package/src/domain/raid/partySummon.ts +198 -0
- package/src/domain/raid/partyVault.ts +320 -0
- package/src/domain/raid/raidBossAbilities.ts +268 -0
- package/src/domain/raid/raidComp.ts +335 -0
- package/src/domain/raid/raidCustomRows.ts +453 -0
- package/src/domain/raid/raidEncounterGear.ts +298 -0
- package/src/domain/raid/raidEncounterTactics.ts +412 -0
- package/src/domain/raid/raidPlan.ts +509 -0
- package/src/domain/raid/raidPlanEdits.ts +98 -0
- package/src/domain/raid/raidPlanPacks.ts +480 -0
- package/src/domain/raid/raidRecovery.ts +183 -0
- package/src/domain/raid/raidRosterTemplate.ts +138 -0
- package/src/domain/rotation/auraSide.ts +68 -0
- package/src/domain/rotation/build.ts +3031 -0
- package/src/domain/rotation/classes/druid.ts +58 -0
- package/src/domain/rotation/classes/hooks.ts +59 -0
- package/src/domain/rotation/classes/hunter.ts +156 -0
- package/src/domain/rotation/classes/index.ts +104 -0
- package/src/domain/rotation/classes/mage.ts +99 -0
- package/src/domain/rotation/classes/paladin.ts +296 -0
- package/src/domain/rotation/classes/priest.ts +94 -0
- package/src/domain/rotation/classes/pullOpener.ts +92 -0
- package/src/domain/rotation/classes/rogue.ts +69 -0
- package/src/domain/rotation/classes/shaman.ts +29 -0
- package/src/domain/rotation/classes/supportSpec.ts +94 -0
- package/src/domain/rotation/classes/warlock.ts +81 -0
- package/src/domain/rotation/classes/warrior.ts +402 -0
- package/src/domain/rotation/classify.ts +1381 -0
- package/src/domain/rotation/condMetricPicker.ts +379 -0
- package/src/domain/rotation/consumables.ts +242 -0
- package/src/domain/rotation/evaluate.ts +1115 -0
- package/src/domain/rotation/finisherLadder.ts +145 -0
- package/src/domain/rotation/invent.ts +938 -0
- package/src/domain/rotation/killOrder.ts +30 -0
- package/src/domain/rotation/openerForm.ts +22 -0
- package/src/domain/rotation/paladinBuffs.ts +568 -0
- package/src/domain/rotation/prebuff.ts +283 -0
- package/src/domain/rotation/raidRowTuning.ts +34 -0
- package/src/domain/rotation/rotation.ts +11 -0
- package/src/domain/rotation/rotationProfiles.ts +180 -0
- package/src/domain/rotation/rotationSuggestions.ts +851 -0
- package/src/domain/rotation/ruleAfterChain.ts +49 -0
- package/src/domain/rotation/spec.ts +70 -0
- package/src/domain/rotation/spellPicker.ts +140 -0
- package/src/domain/rotation/stand.ts +143 -0
- package/src/domain/rotation/types.ts +718 -0
- package/src/domain/run/battlegroundRun.ts +111 -0
- package/src/domain/run/canEnterContext.ts +32 -0
- package/src/domain/run/death.ts +561 -0
- package/src/domain/run/deathRecovery.ts +289 -0
- package/src/domain/run/duel.ts +141 -0
- package/src/domain/run/dungeonRun.ts +344 -0
- package/src/domain/run/floorRest.ts +159 -0
- package/src/domain/run/honor.ts +557 -0
- package/src/domain/run/honorWeek.ts +180 -0
- package/src/domain/run/whenMap.ts +977 -0
- package/src/domain/scriptdev/arathiHighlands.ts +445 -0
- package/src/domain/scriptdev/ashenvale.ts +635 -0
- package/src/domain/scriptdev/ashenvaleHelpers.ts +1215 -0
- package/src/domain/scriptdev/azshara.ts +892 -0
- package/src/domain/scriptdev/blackfathomDeeps.ts +212 -0
- package/src/domain/scriptdev/blackrockDepths.ts +1434 -0
- package/src/domain/scriptdev/blackrockSpire.ts +730 -0
- package/src/domain/scriptdev/blackwingLair.ts +521 -0
- package/src/domain/scriptdev/burningSteppes.ts +62 -0
- package/src/domain/scriptdev/classFilter.ts +43 -0
- package/src/domain/scriptdev/darkshore.ts +817 -0
- package/src/domain/scriptdev/darkshoreHelpers.ts +853 -0
- package/src/domain/scriptdev/deadmines.ts +331 -0
- package/src/domain/scriptdev/desolace.ts +1239 -0
- package/src/domain/scriptdev/direMaul.ts +859 -0
- package/src/domain/scriptdev/durotar.ts +532 -0
- package/src/domain/scriptdev/dustwallowMarsh.ts +758 -0
- package/src/domain/scriptdev/dustwallowMarshHelpers.ts +994 -0
- package/src/domain/scriptdev/easternPlaguelands.ts +21 -0
- package/src/domain/scriptdev/felwood.ts +1055 -0
- package/src/domain/scriptdev/feralas.ts +571 -0
- package/src/domain/scriptdev/feralasHelpers.ts +838 -0
- package/src/domain/scriptdev/gnomeregan.ts +466 -0
- package/src/domain/scriptdev/guards.ts +616 -0
- package/src/domain/scriptdev/hinterlands.ts +693 -0
- package/src/domain/scriptdev/host.ts +1134 -0
- package/src/domain/scriptdev/index.ts +123 -0
- package/src/domain/scriptdev/instanceRaids.ts +136 -0
- package/src/domain/scriptdev/itemScripts.ts +37 -0
- package/src/domain/scriptdev/lochModan.ts +283 -0
- package/src/domain/scriptdev/maraudon.ts +232 -0
- package/src/domain/scriptdev/moltenCore.ts +831 -0
- package/src/domain/scriptdev/moonglade.ts +659 -0
- package/src/domain/scriptdev/moongladeHelpers.ts +933 -0
- package/src/domain/scriptdev/naxxramas.ts +577 -0
- package/src/domain/scriptdev/naxxramasConstruct.ts +364 -0
- package/src/domain/scriptdev/naxxramasFrostwyrm.ts +378 -0
- package/src/domain/scriptdev/naxxramasMilitary.ts +276 -0
- package/src/domain/scriptdev/npcProfessions.ts +1025 -0
- package/src/domain/scriptdev/npcsSpecial.ts +1379 -0
- package/src/domain/scriptdev/onyxiasLair.ts +313 -0
- package/src/domain/scriptdev/orgrimmar.ts +147 -0
- package/src/domain/scriptdev/professionSpecConsumer.ts +481 -0
- package/src/domain/scriptdev/razorfenDowns.ts +468 -0
- package/src/domain/scriptdev/razorfenKraul.ts +410 -0
- package/src/domain/scriptdev/redridgeMountains.ts +163 -0
- package/src/domain/scriptdev/registry.ts +945 -0
- package/src/domain/scriptdev/ruinsOfAhnqiraj.ts +356 -0
- package/src/domain/scriptdev/scarletMonastery.ts +713 -0
- package/src/domain/scriptdev/scholomance.ts +682 -0
- package/src/domain/scriptdev/searingGorge.ts +295 -0
- package/src/domain/scriptdev/shadowfangKeep.ts +181 -0
- package/src/domain/scriptdev/silithus.ts +71 -0
- package/src/domain/scriptdev/silverpineForest.ts +662 -0
- package/src/domain/scriptdev/stonetalonMountains.ts +493 -0
- package/src/domain/scriptdev/stormwindCity.ts +1192 -0
- package/src/domain/scriptdev/stranglethornVale.ts +402 -0
- package/src/domain/scriptdev/stratholme.ts +650 -0
- package/src/domain/scriptdev/stratholmeScripts.ts +505 -0
- package/src/domain/scriptdev/sunkenTemple.ts +736 -0
- package/src/domain/scriptdev/swampOfSorrows.ts +22 -0
- package/src/domain/scriptdev/tanaris.ts +391 -0
- package/src/domain/scriptdev/tanarisHelpers.ts +661 -0
- package/src/domain/scriptdev/teldrassil.ts +143 -0
- package/src/domain/scriptdev/templeOfAhnqiraj.ts +1013 -0
- package/src/domain/scriptdev/theBarrens.ts +709 -0
- package/src/domain/scriptdev/theBarrensHelpers.ts +1026 -0
- package/src/domain/scriptdev/thousandNeedles.ts +426 -0
- package/src/domain/scriptdev/thousandNeedlesHelpers.ts +566 -0
- package/src/domain/scriptdev/tirisfalGlades.ts +533 -0
- package/src/domain/scriptdev/types.ts +1026 -0
- package/src/domain/scriptdev/uldaman.ts +437 -0
- package/src/domain/scriptdev/ungoroCrater.ts +549 -0
- package/src/domain/scriptdev/ungoroCraterHelpers.ts +1006 -0
- package/src/domain/scriptdev/wailingCaverns.ts +700 -0
- package/src/domain/scriptdev/warEffort.ts +371 -0
- package/src/domain/scriptdev/westernPlaguelands.ts +952 -0
- package/src/domain/scriptdev/westfall.ts +767 -0
- package/src/domain/scriptdev/wetlands.ts +660 -0
- package/src/domain/scriptdev/winterspring.ts +482 -0
- package/src/domain/scriptdev/winterspringHelpers.ts +801 -0
- package/src/domain/scriptdev/worldBosses.ts +605 -0
- package/src/domain/scriptdev/zulfarrak.ts +478 -0
- package/src/domain/scriptdev/zulgurub.ts +1152 -0
- package/src/domain/sim/dummySim.ts +408 -0
- package/src/domain/sim/targetDummy.ts +29 -0
- package/src/domain/social/guild.ts +148 -0
- package/src/domain/spells/areaAuraMembership.ts +93 -0
- package/src/domain/spells/breakableStunCc.ts +166 -0
- package/src/domain/spells/cancelAura.ts +80 -0
- package/src/domain/spells/diminishing.ts +167 -0
- package/src/domain/spells/dispel.ts +149 -0
- package/src/domain/spells/dispelMechanic.ts +105 -0
- package/src/domain/spells/equipSpells.ts +247 -0
- package/src/domain/spells/learnOnTargets.ts +260 -0
- package/src/domain/spells/mergeSchoolImmunityFromRaw.ts +66 -0
- package/src/domain/spells/resurrectSpell.ts +124 -0
- package/src/domain/spells/spellPushback.ts +39 -0
- package/src/domain/spells/spellReflect.ts +43 -0
- package/src/domain/spells/stealth.ts +183 -0
- package/src/domain/spells/totem.ts +394 -0
- package/src/domain/spells/worldCast.ts +187 -0
- package/src/domain/world/areaTriggerLocks.ts +177 -0
- package/src/domain/world/dungeonMusic.ts +108 -0
- package/src/domain/world/gameEvents.ts +119 -0
- package/src/domain/world/gameObjects.ts +1030 -0
- package/src/domain/world/goEventFire.ts +234 -0
- package/src/domain/world/goMoTransport.ts +74 -0
- package/src/domain/world/goTransport.ts +81 -0
- package/src/domain/world/hazards.ts +459 -0
- package/src/domain/world/openLock.ts +398 -0
- package/src/domain/world/pools.ts +470 -0
- package/src/domain/world/restArea.ts +37 -0
- package/src/domain/world/weather.ts +201 -0
- package/src/domain/zoneAmbience.mjs +87 -0
- package/src/domain/zoneMusic.mjs +62 -0
- package/src/domain/zoneMusicQueue.mjs +7 -0
- package/src/engine/combat/activeSeal.ts +39 -0
- package/src/engine/combat/aiTargetResolve.ts +64 -0
- package/src/engine/combat/aoeCast.ts +289 -0
- package/src/engine/combat/applyConsumeAura.ts +74 -0
- package/src/engine/combat/applyDemonicSacrifice.ts +70 -0
- package/src/engine/combat/applyDispelMechanic.ts +30 -0
- package/src/engine/combat/applyHealEffect.ts +301 -0
- package/src/engine/combat/applySchoolAbsorb.ts +114 -0
- package/src/engine/combat/applySpell.ts +3169 -0
- package/src/engine/combat/applySpellLate.ts +2026 -0
- package/src/engine/combat/applySpellLateBag.ts +144 -0
- package/src/engine/combat/areaAura.ts +283 -0
- package/src/engine/combat/attackTable.ts +508 -0
- package/src/engine/combat/battleRez.ts +87 -0
- package/src/engine/combat/castAction.ts +36 -0
- package/src/engine/combat/castTargetGates.ts +75 -0
- package/src/engine/combat/castableKit.ts +68 -0
- package/src/engine/combat/ccMirrorUpgrade.ts +39 -0
- package/src/engine/combat/chainFan.ts +210 -0
- package/src/engine/combat/channel.ts +423 -0
- package/src/engine/combat/chaseCloseness.ts +95 -0
- package/src/engine/combat/cmangosCastGates.ts +129 -0
- package/src/engine/combat/combatFlag.ts +77 -0
- package/src/engine/combat/combatGeometry.ts +1329 -0
- package/src/engine/combat/combustion.ts +68 -0
- package/src/engine/combat/context.ts +730 -0
- package/src/engine/combat/createSession.ts +1165 -0
- package/src/engine/combat/creatureLeash.ts +38 -0
- package/src/engine/combat/crowdControl.ts +1259 -0
- package/src/engine/combat/dispelDuty.ts +54 -0
- package/src/engine/combat/dispelReflect.ts +609 -0
- package/src/engine/combat/displaceFloor.ts +113 -0
- package/src/engine/combat/duelBounds.ts +47 -0
- package/src/engine/combat/equippedItemGate.ts +297 -0
- package/src/engine/combat/evadeLifecycle.ts +63 -0
- package/src/engine/combat/eventAi.ts +2220 -0
- package/src/engine/combat/facing.ts +74 -0
- package/src/engine/combat/fearFlee.ts +137 -0
- package/src/engine/combat/fighterFactory.ts +1144 -0
- package/src/engine/combat/forceDespawnAction.ts +51 -0
- package/src/engine/combat/formulas.ts +807 -0
- package/src/engine/combat/friendlyFan.ts +55 -0
- package/src/engine/combat/groundPoolTick.ts +210 -0
- package/src/engine/combat/hazards.ts +114 -0
- package/src/engine/combat/healTargets.ts +226 -0
- package/src/engine/combat/heartbeatResist.ts +49 -0
- package/src/engine/combat/hostileItemUse.ts +75 -0
- package/src/engine/combat/interruptAuras.ts +66 -0
- package/src/engine/combat/itemRescue.ts +49 -0
- package/src/engine/combat/itemUse.ts +260 -0
- package/src/engine/combat/kitById.ts +23 -0
- package/src/engine/combat/knockBack.ts +201 -0
- package/src/engine/combat/leap.ts +89 -0
- package/src/engine/combat/mitigation.ts +587 -0
- package/src/engine/combat/modTaunt.ts +43 -0
- package/src/engine/combat/motionClaim.ts +268 -0
- package/src/engine/combat/motionGate.ts +150 -0
- package/src/engine/combat/motionGenerator.ts +27 -0
- package/src/engine/combat/navSight.ts +138 -0
- package/src/engine/combat/perfSink.ts +28 -0
- package/src/engine/combat/periodicDue.ts +55 -0
- package/src/engine/combat/petAuras.ts +86 -0
- package/src/engine/combat/pickAction.ts +3449 -0
- package/src/engine/combat/powerForm.ts +735 -0
- package/src/engine/combat/powerPools.ts +49 -0
- package/src/engine/combat/predicates.ts +538 -0
- package/src/engine/combat/procsDamage.ts +1823 -0
- package/src/engine/combat/reactiveGates.ts +135 -0
- package/src/engine/combat/roles.ts +389 -0
- package/src/engine/combat/rotationSubject.ts +78 -0
- package/src/engine/combat/ruleAfter.ts +106 -0
- package/src/engine/combat/seedDisplayAuras.ts +203 -0
- package/src/engine/combat/seedOocEffects.ts +317 -0
- package/src/engine/combat/seedSchoolImmunities.ts +45 -0
- package/src/engine/combat/session-types.ts +458 -0
- package/src/engine/combat/sessionApi.ts +1785 -0
- package/src/engine/combat/sessionCharge.ts +124 -0
- package/src/engine/combat/sessionChase.ts +869 -0
- package/src/engine/combat/sessionDeaths.ts +469 -0
- package/src/engine/combat/sessionFocus.ts +506 -0
- package/src/engine/combat/sessionFollow.ts +167 -0
- package/src/engine/combat/sessionGeometry.ts +188 -0
- package/src/engine/combat/sessionHome.ts +75 -0
- package/src/engine/combat/sessionInject.ts +719 -0
- package/src/engine/combat/sessionMechanicMove.ts +555 -0
- package/src/engine/combat/sessionMotion.ts +1553 -0
- package/src/engine/combat/sessionMotionKit.ts +247 -0
- package/src/engine/combat/sessionMoveIntent.ts +49 -0
- package/src/engine/combat/sessionMoveOrder.ts +200 -0
- package/src/engine/combat/sessionPathTo.ts +657 -0
- package/src/engine/combat/sessionPools.ts +688 -0
- package/src/engine/combat/sessionSteer.ts +144 -0
- package/src/engine/combat/sessionStepBack.ts +151 -0
- package/src/engine/combat/sessionStepWrap.ts +116 -0
- package/src/engine/combat/sessionView.ts +442 -0
- package/src/engine/combat/simEffects.ts +32 -0
- package/src/engine/combat/simFacade.ts +620 -0
- package/src/engine/combat/simPump.ts +264 -0
- package/src/engine/combat/simSnapshot.ts +165 -0
- package/src/engine/combat/simThreadPool.ts +35 -0
- package/src/engine/combat/skeramImages.ts +57 -0
- package/src/engine/combat/slowUpdate.ts +178 -0
- package/src/engine/combat/snapToFloor.ts +42 -0
- package/src/engine/combat/speedAura.ts +29 -0
- package/src/engine/combat/spellReagents.ts +71 -0
- package/src/engine/combat/stealthDetect.ts +93 -0
- package/src/engine/combat/stepBackMotion.ts +171 -0
- package/src/engine/combat/stepSession.ts +3102 -0
- package/src/engine/combat/summonCast.ts +243 -0
- package/src/engine/combat/thaddiusPolarity.ts +97 -0
- package/src/engine/combat/threat.ts +388 -0
- package/src/engine/combat/threatOps.ts +272 -0
- package/src/engine/combat/tickWorkerBody.ts +211 -0
- package/src/engine/combat/totemAuras.ts +122 -0
- package/src/engine/combat/triggerPayload.ts +42 -0
- package/src/engine/combat/triggeredCompanion.ts +63 -0
- package/src/engine/combat/types.ts +1897 -0
- package/src/engine/combat/useObjectTrap.ts +140 -0
- package/src/engine/combat/walkSurface.ts +54 -0
- package/src/engine/combat/weapon.ts +1248 -0
- package/src/engine/combat/worldFrame.ts +43 -0
- package/src/engine/combat.solo-golden.json +2242 -0
- package/src/engine/combat.ts +84 -0
- package/src/engine/core/detMath.ts +289 -0
- package/src/engine/core/events.ts +357 -0
- package/src/engine/core/rng.ts +36 -0
- package/src/engine/game/actionBars.ts +124 -0
- package/src/engine/game/activateObjectFromSpell.ts +320 -0
- package/src/engine/game/applyActiveObjectFromDbScript.ts +98 -0
- package/src/engine/game/applyDeathAndSpellScripts.ts +268 -0
- package/src/engine/game/applyDoorFromDbScript.ts +388 -0
- package/src/engine/game/applyEscortFromDbScript.ts +290 -0
- package/src/engine/game/applyGoSpellcasterCast.ts +40 -0
- package/src/engine/game/applyHoverFromDbScript.ts +110 -0
- package/src/engine/game/applyOocResurrect.ts +71 -0
- package/src/engine/game/applySpellDurability.ts +115 -0
- package/src/engine/game/applyTailFromDbScript.ts +478 -0
- package/src/engine/game/applyTerminateFromDbScript.ts +95 -0
- package/src/engine/game/auctionMail.ts +269 -0
- package/src/engine/game/bagOverflow.ts +130 -0
- package/src/engine/game/bank.ts +110 -0
- package/src/engine/game/barAutofill.ts +26 -0
- package/src/engine/game/battleground.ts +369 -0
- package/src/engine/game/combatEnemySpec.ts +216 -0
- package/src/engine/game/combatObjectTraps.ts +167 -0
- package/src/engine/game/combatSeed.ts +320 -0
- package/src/engine/game/combatSession.ts +3241 -0
- package/src/engine/game/combatSessionClock.ts +62 -0
- package/src/engine/game/companionQuestActions.ts +242 -0
- package/src/engine/game/companionTraining.ts +40 -0
- package/src/engine/game/consumables.ts +624 -0
- package/src/engine/game/context.ts +53 -0
- package/src/engine/game/createHealthstone.ts +45 -0
- package/src/engine/game/deathFlow.ts +127 -0
- package/src/engine/game/devGrant.ts +117 -0
- package/src/engine/game/dynamicObject.ts +365 -0
- package/src/engine/game/enchantItem.ts +177 -0
- package/src/engine/game/equipmentHelper.ts +806 -0
- package/src/engine/game/factionState.ts +108 -0
- package/src/engine/game/garmentsOoc.ts +69 -0
- package/src/engine/game/globalActionBar.ts +179 -0
- package/src/engine/game/goInteractQuestCredit.ts +51 -0
- package/src/engine/game/goMoTransportUse.ts +61 -0
- package/src/engine/game/goTransportUse.ts +60 -0
- package/src/engine/game/healthstoneUpkeep.ts +59 -0
- package/src/engine/game/killSkin.ts +124 -0
- package/src/engine/game/learnFromItem.ts +118 -0
- package/src/engine/game/loadReconcile.ts +551 -0
- package/src/engine/game/loot.ts +294 -0
- package/src/engine/game/macros.ts +125 -0
- package/src/engine/game/mail.ts +293 -0
- package/src/engine/game/meetingStoneQueue.ts +75 -0
- package/src/engine/game/meetingStoneUse.ts +54 -0
- package/src/engine/game/newGameState.ts +363 -0
- package/src/engine/game/oocAuraInterrupt.ts +92 -0
- package/src/engine/game/oocCast.ts +241 -0
- package/src/engine/game/oocCastEffects.ts +803 -0
- package/src/engine/game/oocCastMethods.ts +1077 -0
- package/src/engine/game/openLockFromSpell.ts +174 -0
- package/src/engine/game/outdoorPvp.ts +187 -0
- package/src/engine/game/outfitter.ts +644 -0
- package/src/engine/game/paladinBoard.ts +393 -0
- package/src/engine/game/partyAuras.ts +121 -0
- package/src/engine/game/persistCombatAuras.ts +91 -0
- package/src/engine/game/pets.ts +459 -0
- package/src/engine/game/prePullHealthstones.ts +154 -0
- package/src/engine/game/professions.ts +2227 -0
- package/src/engine/game/pruneStaleRuntime.ts +39 -0
- package/src/engine/game/questFightCredit.ts +36 -0
- package/src/engine/game/questItemOnCorpse.ts +166 -0
- package/src/engine/game/questItemOnCreature.ts +103 -0
- package/src/engine/game/questLog.ts +879 -0
- package/src/engine/game/questSpellComplete.ts +21 -0
- package/src/engine/game/questTurnIn.ts +598 -0
- package/src/engine/game/raidParty.ts +32 -0
- package/src/engine/game/reagentBuyIn.ts +39 -0
- package/src/engine/game/regenRest.ts +186 -0
- package/src/engine/game/rotation.ts +425 -0
- package/src/engine/game/runFullDungeon.ts +611 -0
- package/src/engine/game/runSupply.ts +80 -0
- package/src/engine/game/sanitizeDriftedItems.ts +135 -0
- package/src/engine/game/scriptDevGoUse.ts +397 -0
- package/src/engine/game/scriptDevInnkeeper.ts +150 -0
- package/src/engine/game/scriptDevProfessionSpec.ts +99 -0
- package/src/engine/game/sendEventFromSpell.ts +87 -0
- package/src/engine/game/sortContainers.ts +85 -0
- package/src/engine/game/spellReputation.ts +69 -0
- package/src/engine/game/squad/squadDungeonSeating.ts +197 -0
- package/src/engine/game/squadDungeon.ts +4222 -0
- package/src/engine/game/squadQuestShare.ts +260 -0
- package/src/engine/game/summonObjectSlot.ts +69 -0
- package/src/engine/game/summonObjectWild.ts +73 -0
- package/src/engine/game/summoningRitualUse.ts +141 -0
- package/src/engine/game/talents.ts +356 -0
- package/src/engine/game/tamingRodUse.ts +66 -0
- package/src/engine/game/tempSpawnCreature.ts +136 -0
- package/src/engine/game/tickDungeonPatrolScripts.ts +205 -0
- package/src/engine/game/tickTimedQuests.ts +28 -0
- package/src/engine/game/trade.ts +586 -0
- package/src/engine/game/travel.ts +1155 -0
- package/src/engine/game/types.ts +1855 -0
- package/src/engine/game/vendorOffers.ts +244 -0
- package/src/engine/game/weaponImbueItem.ts +281 -0
- package/src/engine/game/worldSession.ts +183 -0
- package/src/engine/game/worldState.ts +166 -0
- package/src/engine/game.ts +968 -0
- package/src/engine/spells/GAP.md +67 -0
- package/src/engine/spells/absorbs.ts +376 -0
- package/src/engine/spells/addTargetTrigger.ts +53 -0
- package/src/engine/spells/auraPerSecondCost.ts +50 -0
- package/src/engine/spells/auraStacking.ts +497 -0
- package/src/engine/spells/cmangos-special-cases-combustion.ts +13 -0
- package/src/engine/spells/cmangos-special-cases-s18.ts +445 -0
- package/src/engine/spells/cmangos-special-cases-s19.ts +324 -0
- package/src/engine/spells/cmangos-special-cases-s20.ts +385 -0
- package/src/engine/spells/cmangos-special-cases-s21.ts +116 -0
- package/src/engine/spells/cmangos-special-cases-s22.ts +24 -0
- package/src/engine/spells/cmangos-special-cases-s23.ts +52 -0
- package/src/engine/spells/cmangos-special-cases.ts +1570 -0
- package/src/engine/spells/conditions.ts +718 -0
- package/src/engine/spells/effects.ts +203 -0
- package/src/engine/spells/fixtures/oracle-effects-lock9a.json +1 -0
- package/src/engine/spells/immunity.ts +942 -0
- package/src/engine/spells/intentEffects.ts +351 -0
- package/src/engine/spells/interpreter/GAPS.md +21 -0
- package/src/engine/spells/interpreter/amount.ts +109 -0
- package/src/engine/spells/interpreter/class-scripts-kit.ts +478 -0
- package/src/engine/spells/interpreter/diff.ts +246 -0
- package/src/engine/spells/interpreter/duration.ts +90 -0
- package/src/engine/spells/interpreter/form-attrs.json +1 -0
- package/src/engine/spells/interpreter/form-attrs.ts +95 -0
- package/src/engine/spells/interpreter/handlers/aura-remove.ts +113 -0
- package/src/engine/spells/interpreter/handlers/auras-control.ts +1547 -0
- package/src/engine/spells/interpreter/handlers/auras-core.ts +1583 -0
- package/src/engine/spells/interpreter/handlers/auras-misc.ts +1774 -0
- package/src/engine/spells/interpreter/handlers/effect-disenchant.ts +17 -0
- package/src/engine/spells/interpreter/handlers/effect-skinning.ts +20 -0
- package/src/engine/spells/interpreter/handlers/effects-action-utility.ts +1455 -0
- package/src/engine/spells/interpreter/handlers/effects-core.ts +432 -0
- package/src/engine/spells/interpreter/handlers/effects-remainder.ts +105 -0
- package/src/engine/spells/interpreter/handlers/effects-summon-item.ts +687 -0
- package/src/engine/spells/interpreter/handlers/mod-increase-energy-percent.ts +36 -0
- package/src/engine/spells/interpreter/handlers/mod-increase-energy.ts +36 -0
- package/src/engine/spells/interpreter/handlers/periodic-trigger-zero.ts +327 -0
- package/src/engine/spells/interpreter/handlers/procs.ts +131 -0
- package/src/engine/spells/interpreter/handlers/registry.ts +975 -0
- package/src/engine/spells/interpreter/handlers/shared.ts +667 -0
- package/src/engine/spells/interpreter/handlers.ts +9 -0
- package/src/engine/spells/interpreter/hunter-kit.ts +202 -0
- package/src/engine/spells/interpreter/index.ts +525 -0
- package/src/engine/spells/interpreter/item-triggers.ts +1121 -0
- package/src/engine/spells/interpreter/lift-consume-energy.ts +37 -0
- package/src/engine/spells/interpreter/mage-portals.ts +37 -0
- package/src/engine/spells/interpreter/materialize-charm.ts +88 -0
- package/src/engine/spells/interpreter/materialize-dispel-mechanic.ts +25 -0
- package/src/engine/spells/interpreter/materialize-rating-buffs.ts +81 -0
- package/src/engine/spells/interpreter/materialize-speed.ts +109 -0
- package/src/engine/spells/interpreter/materialize-spell-magnet.ts +22 -0
- package/src/engine/spells/interpreter/opcodes.ts +789 -0
- package/src/engine/spells/interpreter/paladin-kit.ts +95 -0
- package/src/engine/spells/interpreter/paladin-seals.ts +499 -0
- package/src/engine/spells/interpreter/priest-warlock-kit.ts +135 -0
- package/src/engine/spells/interpreter/proc.ts +443 -0
- package/src/engine/spells/interpreter/registry/helpers.ts +16 -0
- package/src/engine/spells/interpreter/registry/index.ts +216 -0
- package/src/engine/spells/interpreter/registry/packs/class-abilities.ts +304 -0
- package/src/engine/spells/interpreter/registry/packs/dire-maul.ts +44 -0
- package/src/engine/spells/interpreter/registry/packs/dummy-script-tail.ts +1065 -0
- package/src/engine/spells/interpreter/registry/packs/ex-wave-m.ts +70 -0
- package/src/engine/spells/interpreter/registry/packs/life-tap.ts +107 -0
- package/src/engine/spells/interpreter/registry/packs/paladin.ts +246 -0
- package/src/engine/spells/interpreter/registry/packs/raid-script-summons.ts +26 -0
- package/src/engine/spells/interpreter/registry/packs/raid-threat-wipe.ts +22 -0
- package/src/engine/spells/interpreter/registry/packs/shaman.ts +214 -0
- package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-a.ts +269 -0
- package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-b.ts +370 -0
- package/src/engine/spells/interpreter/registry/packs/si4-dummy-generic-c.ts +172 -0
- package/src/engine/spells/interpreter/registry/packs/si4-dummy-hunter.ts +60 -0
- package/src/engine/spells/interpreter/registry/packs/si4-dummy-warrior.ts +31 -0
- package/src/engine/spells/interpreter/registry/packs/si4-script-generic-a.ts +114 -0
- package/src/engine/spells/interpreter/registry/packs/si4-script-generic-b.ts +249 -0
- package/src/engine/spells/interpreter/registry/packs/si4-script-generic-c.ts +233 -0
- package/src/engine/spells/interpreter/registry/types.ts +48 -0
- package/src/engine/spells/interpreter/talent-scripted.ts +329 -0
- package/src/engine/spells/interpreter/targeting.ts +90 -0
- package/src/engine/spells/interpreter/types-intent.ts +1501 -0
- package/src/engine/spells/interpreter/types.ts +419 -0
- package/src/engine/spells/interpreter/warrior-druid-kit.ts +314 -0
- package/src/engine/spells/interpreter/weapon-imbue-kit.ts +384 -0
- package/src/engine/spells/interrupt.ts +217 -0
- package/src/engine/spells/meleeAttackReset.ts +60 -0
- package/src/engine/spells/oocTriggerSpell.ts +49 -0
- package/src/engine/spells/overrideClassScripts.ts +319 -0
- package/src/engine/spells/parryHaste.ts +20 -0
- package/src/engine/spells/procs.ts +300 -0
- package/src/engine/spells/recovery.ts +203 -0
- package/src/engine/spells/scriptTargetDest.ts +76 -0
- package/src/engine/spells/scriptTargets.ts +85 -0
- package/src/engine/spells/singleTargetAura.ts +82 -0
- package/src/engine/spells/specialCasePayloads.ts +57 -0
- package/src/engine/spells/spellAttributes.ts +249 -0
- package/src/engine/spells/spellBonus.ts +143 -0
- package/src/engine/spells/spellModIntents.ts +419 -0
- package/src/engine/spells/spellMods.ts +283 -0
- package/src/engine/spells/spellRadius.ts +15 -0
- package/src/engine/spells/trapObjects.ts +26 -0
- package/src/json.d.ts +7 -0
- package/src/persistence/memoryRepository.ts +23 -0
- package/src/persistence/saveBackups.ts +162 -0
- package/src/persistence/saveFile.ts +68 -0
- package/src/persistence/saveRepository.ts +11 -0
- package/src/persistence/saveShape.ts +668 -0
- package/src/progression/leveling.ts +89 -0
- package/src/progression/rest.ts +1434 -0
- package/src/progression/training.ts +226 -0
- package/src/progression/xpGain.ts +369 -0
- package/src/quests/quests.ts +1580 -0
- package/src/world/aoePull.ts +198 -0
- package/src/world/areaTableDbc.ts +39 -0
- package/src/world/areaTableMapIdPairs.ts +141 -0
- package/src/world/bakeSlug.ts +43 -0
- package/src/world/continuousDungeon.ts +1250 -0
- package/src/world/dungeonBakeProjection.ts +190 -0
- package/src/world/dungeonMapDensity.ts +342 -0
- package/src/world/dungeonMapProjection.ts +135 -0
- package/src/world/dungeonNav.ts +904 -0
- package/src/world/dungeonNpcSim.ts +147 -0
- package/src/world/dungeonObjectives.ts +234 -0
- package/src/world/dungeonPreset.ts +35 -0
- package/src/world/dungeonRoute.ts +311 -0
- package/src/world/dungeonRouteGeometry.ts +732 -0
- package/src/world/dungeonRouteOrder.ts +1037 -0
- package/src/world/dungeonWingRooms.ts +426 -0
- package/src/world/escort.ts +296 -0
- package/src/world/goPoolRoll.ts +75 -0
- package/src/world/instanceObjects.ts +785 -0
- package/src/world/instances.ts +1572 -0
- package/src/world/meetingStones.ts +56 -0
- package/src/world/navmeshFloors.ts +145 -0
- package/src/world/nearGrid.ts +167 -0
- package/src/world/packBudget.ts +613 -0
- package/src/world/rareRoll.ts +335 -0
- package/src/world/routeAuthoring.ts +132 -0
- package/src/world/routeEdit.ts +209 -0
- package/src/world/world.ts +812 -0
- package/src/world/zoneHazards.ts +47 -0
|
@@ -0,0 +1,1121 @@
|
|
|
1
|
+
// Pure spell-effect resolution plus item trigger routing: on-use, on-equip and chance-on-hit take the
|
|
2
|
+
// same resolver. It never invents an effect and never rolls without an injected rng.
|
|
3
|
+
|
|
4
|
+
import type { ItemDef, Mechanic, SpellDef, SpellEffect, BuffMod } from '../../../data/schema.ts';
|
|
5
|
+
import type { Rng } from '../../core/rng.ts';
|
|
6
|
+
import type { ProcEventContext } from '../procs.ts';
|
|
7
|
+
import { MECHANIC_ID } from '../../../domain/creature/creatureAiConstants.ts';
|
|
8
|
+
import {
|
|
9
|
+
EFFECT_HANDLERS,
|
|
10
|
+
createHandlerState,
|
|
11
|
+
finalizeResult,
|
|
12
|
+
} from './handlers.ts';
|
|
13
|
+
|
|
14
|
+
/** SharedDefines Mechanics id → name (inverse of MECHANIC_ID). */
|
|
15
|
+
const MECHANIC_NAME_FROM_ID: Readonly<Record<number, Mechanic>> = Object.freeze(
|
|
16
|
+
Object.fromEntries(
|
|
17
|
+
Object.entries(MECHANIC_ID)
|
|
18
|
+
.filter(([, id]) => id != null && id > 0)
|
|
19
|
+
.map(([name, id]) => [id as number, name as Mechanic]),
|
|
20
|
+
),
|
|
21
|
+
);
|
|
22
|
+
import {
|
|
23
|
+
buildProcTriggerSpellMeta,
|
|
24
|
+
resolveProcTriggerSpellId,
|
|
25
|
+
tryProcTriggerSpell,
|
|
26
|
+
type ProcTriggerSpellMeta,
|
|
27
|
+
} from './proc.ts';
|
|
28
|
+
import { effectAmountRange } from './amount.ts';
|
|
29
|
+
import {
|
|
30
|
+
applyWeaponImbueKit,
|
|
31
|
+
applyWeaponImbueKitFromItemEnchant,
|
|
32
|
+
weaponImbueHasCombatKit,
|
|
33
|
+
} from './weapon-imbue-kit.ts';
|
|
34
|
+
import { SPELL_ATTR_EX2, hasAttrEx2 } from '../spellAttributes.ts';
|
|
35
|
+
// The extracted enchantment table. The resolver fills thin weapon-imbue rows from it so poisons,
|
|
36
|
+
// stones and oils work without re-running the docker-only enricher. Cite: extract-item-enchants.mjs.
|
|
37
|
+
import itemEnchantsTable from '../../../data/tables/itemEnchants.json' with { type: 'json' };
|
|
38
|
+
|
|
39
|
+
// Baked roles no effect payload can imply, so role inference never returns them: the two auto-attack
|
|
40
|
+
// toggles, the tame channel, and the pet heal — which must be rescued or combat heals the owner.
|
|
41
|
+
const NON_DERIVABLE_ROLES: ReadonlySet<string> = new Set(['shoot', 'attack', 'pet_tame', 'pet_heal']);
|
|
42
|
+
import {
|
|
43
|
+
SPELL_AURA_PROC_TRIGGER_SPELL,
|
|
44
|
+
SPELL_EFFECT_APPLY_AURA,
|
|
45
|
+
} from './opcodes.ts';
|
|
46
|
+
import type { InterpretContext, InterpretResult } from './types.ts';
|
|
47
|
+
import {
|
|
48
|
+
materializeOverrideClassScriptIntents,
|
|
49
|
+
materializeSpellModIntents,
|
|
50
|
+
talentScriptedEffects,
|
|
51
|
+
talentScriptedAppendEffects,
|
|
52
|
+
} from './talent-scripted.ts';
|
|
53
|
+
import { materializePaladinSeal, sealMaterializedEffects } from './paladin-seals.ts';
|
|
54
|
+
import {
|
|
55
|
+
applyExecuteRageToEffects,
|
|
56
|
+
materializeWarriorDruidKitEffects,
|
|
57
|
+
} from './warrior-druid-kit.ts';
|
|
58
|
+
import { materializeHunterKitEffects } from './hunter-kit.ts';
|
|
59
|
+
import { materializePriestWarlockKitEffects } from './priest-warlock-kit.ts';
|
|
60
|
+
import { materializePaladinKitEffects } from './paladin-kit.ts';
|
|
61
|
+
import { applyFormAttrPatch } from './form-attrs.ts';
|
|
62
|
+
import { materializeAuraRemoveEffects } from './handlers/aura-remove.ts';
|
|
63
|
+
import { liftConsumeEnergyIntents } from './lift-consume-energy.ts';
|
|
64
|
+
import {
|
|
65
|
+
materializeMissingSpeedFromRaw,
|
|
66
|
+
stampMissingSpeedFromRaw,
|
|
67
|
+
} from './materialize-speed.ts';
|
|
68
|
+
import {
|
|
69
|
+
materializeMissingRatingBuffsFromRaw,
|
|
70
|
+
stampMissingRatingBuffsFromRaw,
|
|
71
|
+
} from './materialize-rating-buffs.ts';
|
|
72
|
+
import {
|
|
73
|
+
materializeMissingCharmFromRaw,
|
|
74
|
+
stampMissingCharmFromRaw,
|
|
75
|
+
} from './materialize-charm.ts';
|
|
76
|
+
import { withHostile } from './targeting.ts';
|
|
77
|
+
import { materializeDispelMechanicIntents } from './materialize-dispel-mechanic.ts';
|
|
78
|
+
import { materializeSpellMagnetIntents } from './materialize-spell-magnet.ts';
|
|
79
|
+
|
|
80
|
+
// Local interpret entry (same body as index.interpretSpell) — avoids circular import with index.ts
|
|
81
|
+
// re-exports of this module.
|
|
82
|
+
function interpretSpellLocal(spell: SpellDef, ctx: InterpretContext = {}): InterpretResult {
|
|
83
|
+
const resolvedCtx: InterpretContext = {
|
|
84
|
+
...ctx,
|
|
85
|
+
spellLevel:
|
|
86
|
+
ctx.spellLevel
|
|
87
|
+
?? (ctx.casterLevel != null ? (spell.spellLevel ?? spell.reqLevel ?? 0) : undefined),
|
|
88
|
+
};
|
|
89
|
+
const state = createHandlerState(spell, resolvedCtx);
|
|
90
|
+
const rawList = spell.rawEffects;
|
|
91
|
+
if (!rawList || rawList.length === 0) {
|
|
92
|
+
return finalizeResult(state);
|
|
93
|
+
}
|
|
94
|
+
for (let slot = 0; slot < rawList.length; slot++) {
|
|
95
|
+
const raw = rawList[slot]!;
|
|
96
|
+
const effect = raw.effect | 0;
|
|
97
|
+
if (!effect) continue;
|
|
98
|
+
const handler = EFFECT_HANDLERS[effect];
|
|
99
|
+
if (!handler) {
|
|
100
|
+
state.unhandled.push({
|
|
101
|
+
slot,
|
|
102
|
+
effect,
|
|
103
|
+
auraName: raw.auraName | 0,
|
|
104
|
+
reason: `unhandled effect ${effect} (SI3+)`,
|
|
105
|
+
});
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const before = state.effects.length;
|
|
109
|
+
handler(state, raw, slot);
|
|
110
|
+
// Stamp the DBC slot on everything this handler appended — the coefficient index.
|
|
111
|
+
// Same stamp as index.interpretSpell; this is the copy the combat path actually calls.
|
|
112
|
+
for (let i = before; i < state.effects.length; i++) {
|
|
113
|
+
const e = state.effects[i]!;
|
|
114
|
+
if (e.effectSlot == null) e.effectSlot = slot;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return finalizeResult(state);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Spell id → SpellDef lookup (DataStore.spell / combatant spell list). */
|
|
121
|
+
export type SpellLookup = (id: number) => SpellDef | undefined | null;
|
|
122
|
+
|
|
123
|
+
/** ItemDef.procs row shape (FI2 bake). */
|
|
124
|
+
export type ItemProcRow = NonNullable<ItemDef['procs']>[number];
|
|
125
|
+
|
|
126
|
+
export interface ResolveSpellEffectsOpts extends InterpretContext {
|
|
127
|
+
// Force interpreter even when the SI gate is off. SI5 default already prefers interpreter when rawEffects
|
|
128
|
+
// exist.
|
|
129
|
+
forceInterpreter?: boolean;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** True when bake synthesized no usable SpellEffect list. */
|
|
133
|
+
export function isBakeEffectsEmpty(spell: SpellDef): boolean {
|
|
134
|
+
return !spell.effects || spell.effects.length === 0;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Catalog materializer for a hollow baked effect list that still has raw effects. Allowlisted opcodes
|
|
138
|
+
// only: a full-catalog materialize would flip rotation's "empty bake means skip the keep-up" gate.
|
|
139
|
+
const FILL_EMPTY_EFFECT_OPCODES = new Set([
|
|
140
|
+
2, // SCHOOL_DAMAGE
|
|
141
|
+
3, // SPELL_EFFECT_DUMMY — Holy Shock parent ranks (materializePaladinKit)
|
|
142
|
+
5, // SPELL_EFFECT_TELEPORT_UNITS
|
|
143
|
+
8, // POWER_DRAIN
|
|
144
|
+
9, // HEALTH_LEECH (Death Coil)
|
|
145
|
+
10, // HEAL
|
|
146
|
+
17, // WEAPON_DAMAGE_NOSCHOOL (Heroic Strike / Overpower)
|
|
147
|
+
22, // SPELL_EFFECT_PARRY — Parry 3127 SetCanParry; KI-818
|
|
148
|
+
23, // SPELL_EFFECT_BLOCK — Block 107 SetCanBlock
|
|
149
|
+
28, // SUMMON (pet family)
|
|
150
|
+
31, // WEAPON_PERCENT_DAMAGE
|
|
151
|
+
33, // SPELL_EFFECT_OPEN_LOCK — Pick Lock 1804 / Opening (catalog + OOC; KI-613)
|
|
152
|
+
38, // SPELL_EFFECT_DISPEL — Cleanse / Cure / Remove Curse
|
|
153
|
+
41, // SPELL_EFFECT_SUMMON_WILD
|
|
154
|
+
50, // SPELL_EFFECT_TRANS_DOOR — mage capital Portals only materialize teleport (handleTransDoor)
|
|
155
|
+
56, // SUMMON_PET
|
|
156
|
+
58, // WEAPON_DAMAGE
|
|
157
|
+
59, // SPELL_EFFECT_OPEN_LOCK_ITEM — shared EffectOpenLock with 33
|
|
158
|
+
64, // TRIGGER_SPELL
|
|
159
|
+
67, // HEAL_MAX_HEALTH (Lay on Hands)
|
|
160
|
+
69, // SPELL_EFFECT_DISTRACT
|
|
161
|
+
71, // SPELL_EFFECT_PICKPOCKET
|
|
162
|
+
95, // SPELL_EFFECT_SKINNING — 8613/8617/8618/10768; KI must-impl #18
|
|
163
|
+
99, // SPELL_EFFECT_DISENCHANT — Disenchant 13262 / 10694 (PT); KI must-impl #18
|
|
164
|
+
73, // SUMMON_POSSESSED (Eye of Kilrogg)
|
|
165
|
+
77, // SCRIPT_EFFECT (healthstone / friend-heal)
|
|
166
|
+
112, // SUMMON_DEMON (Inferno)
|
|
167
|
+
121, // NORMALIZED_WEAPON_DMG
|
|
168
|
+
]);
|
|
169
|
+
/** Aura opcodes safe to materialize on the catalog surface. */
|
|
170
|
+
const FILL_EMPTY_AURA_OPCODES = new Set([
|
|
171
|
+
1, // SPELL_AURA_BIND_SIGHT (Mind Vision)
|
|
172
|
+
4, // SPELL_AURA_DUMMY — seals / VE / soulstone / scripted holders (resolveCombatSpell kits)
|
|
173
|
+
5, // MOD_CONFUSE / polymorph (higher ranks)
|
|
174
|
+
2, // SPELL_AURA_MOD_POSSESS — Mind Control; KI-801 family
|
|
175
|
+
6, // SPELL_AURA_MOD_CHARM — Enslave Demon / Dominate Mind; KI-801
|
|
176
|
+
177, // SPELL_AURA_AOE_CHARM — TakeCharmOf advertised=false; HandleAoECharm :2348
|
|
177
|
+
7, // SPELL_AURA_MOD_FEAR — creature/player fear (Terrify 7399); KI-448
|
|
178
|
+
9, // MOD_ATTACKSPEED
|
|
179
|
+
10, // MOD_THREAT (Blessing of Salvation / Greater)
|
|
180
|
+
13, // MOD_DAMAGE_DONE (Tiger's Fury)
|
|
181
|
+
14, // MOD_DAMAGE_TAKEN (Blessing of Sanctuary)
|
|
182
|
+
15, // DAMAGE_SHIELD (Thorns / Retribution)
|
|
183
|
+
17, // SPELL_AURA_MOD_STEALTH_DETECT (Catseye Elixir) — KI-593 catalog surface
|
|
184
|
+
18, // SPELL_AURA_MOD_INVISIBILITY (Lesser/Greater Invis pots) — KI-592
|
|
185
|
+
19, // SPELL_AURA_MOD_INVISIBILITY_DETECTION (Detect Lesser/Greater Invisibility)
|
|
186
|
+
22, // MOD_RESISTANCE
|
|
187
|
+
23, // PERIODIC_TRIGGER_SPELL
|
|
188
|
+
28, // SPELL_AURA_REFLECT_SPELLS (Sheen of Zanza when bake drops parent aura) — KI-625
|
|
189
|
+
29, // MOD_STAT
|
|
190
|
+
31, // MOD_INCREASE_SPEED (Dash / Ghost Wolf)
|
|
191
|
+
32, // MOD_INCREASE_MOUNTED_SPEED
|
|
192
|
+
33, // MOD_DECREASE_SPEED
|
|
193
|
+
36, // MOD_SHAPESHIFT
|
|
194
|
+
42, // PROC_TRIGGER_SPELL
|
|
195
|
+
44, // SPELL_AURA_TRACK_CREATURES (Detect Undead / Beast) — KI-592
|
|
196
|
+
45, // TRACK_RESOURCES (Find Treasure)
|
|
197
|
+
47, // MOD_PARRY_PERCENT
|
|
198
|
+
49, // MOD_DODGE_PERCENT
|
|
199
|
+
51, // MOD_BLOCK_PERCENT (Shield Block / Holy Shield)
|
|
200
|
+
52, // MOD_CRIT_PERCENT
|
|
201
|
+
56, // TRANSFORM (Polymorph variants)
|
|
202
|
+
65, // MOD_CASTING_SPEED
|
|
203
|
+
67, // MOD_DISARM
|
|
204
|
+
68, // SPELL_AURA_MOD_STALKED — track flag (Hunter's Mark effect 1); KI-849
|
|
205
|
+
69, // SPELL_AURA_SCHOOL_ABSORB — PW:S / Fire Ward / Frost Ward; KI-426
|
|
206
|
+
77, // MECHANIC_IMMUNITY (Fear Ward)
|
|
207
|
+
78, // MOUNTED (Warhorse / Felsteed)
|
|
208
|
+
79, // MOD_DAMAGE_PERCENT_DONE (Power Infusion)
|
|
209
|
+
80, // SPELL_AURA_MOD_PERCENT_STAT (BoK)
|
|
210
|
+
82, // SPELL_AURA_WATER_BREATHING (Water Breathing / Unending Breath)
|
|
211
|
+
91, // SPELL_AURA_MOD_DETECT_RANGE (Mind Soothe)
|
|
212
|
+
93, // MOD_UNATTACKABLE (Phase Shift)
|
|
213
|
+
97, // SPELL_AURA_MANA_SHIELD — Mana Shield ranks; KI-423
|
|
214
|
+
98, // SPELL_AURA_MOD_SKILL_TALENT — racial weapon/eng skill (Gun/Axe/Sword/Mace Spec, Eng Spec)
|
|
215
|
+
99, // MOD_ATTACK_POWER
|
|
216
|
+
100, // SPELL_AURA_AURAS_VISIBLE (Detect Magic)
|
|
217
|
+
104, // SPELL_AURA_WATER_WALK (Water Walking)
|
|
218
|
+
105, // FEATHER_FALL
|
|
219
|
+
107, // ADD_FLAT_MODIFIER → next_cast_mod (Inner Focus / Combustion)
|
|
220
|
+
108, // ADD_PCT_MODIFIER → next_cast_mod
|
|
221
|
+
110, // SPELL_AURA_MOD_POWER_REGEN_PERCENT — Evocation / Innervate; KI-424
|
|
222
|
+
88, // SPELL_AURA_MOD_HEALTH_REGEN_PERCENT — Troll Regeneration OOC +10%; KI-876
|
|
223
|
+
116, // SPELL_AURA_MOD_REGEN_DURING_COMBAT — Troll Regeneration combat 10%; KI-876
|
|
224
|
+
117, // SPELL_AURA_MOD_MECHANIC_RESISTANCE — Orc Hardiness stun resist
|
|
225
|
+
127, // SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS — Hunter's Mark +RAP; KI-849
|
|
226
|
+
134, // SPELL_AURA_MOD_MANA_REGEN_INTERRUPT — channel full spirit (Evocation/Innervate)
|
|
227
|
+
136, // MOD_HEALING_DONE_PERCENT (Power Infusion)
|
|
228
|
+
137, // SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE (GBK)
|
|
229
|
+
138, // MOD_MELEE_HASTE (Curse of Tongues)
|
|
230
|
+
144, // SAFE_FALL
|
|
231
|
+
149, // SPELL_AURA_RESIST_PUSHBACK — Concentration Aura 19746 (35%); Barkskin uses same aura
|
|
232
|
+
153, // SPELL_AURA_SPLIT_DAMAGE_FLAT — Blessing of Sacrifice; KI-821
|
|
233
|
+
155, // MOD_WATER_BREATHING (Undead racial)
|
|
234
|
+
156, // SPELL_AURA_MOD_REPUTATION_GAIN — Human Diplomacy
|
|
235
|
+
165, // SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS — melee twin of 127
|
|
236
|
+
168, // SPELL_AURA_MOD_DAMAGE_DONE_VERSUS — Beast Slaying / Echoes; KI-875
|
|
237
|
+
30, // SPELL_AURA_MOD_SKILL — equip/temp skill auras (same surface as 98)
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
/** Blessing of Sanctuary ranks — empty effects[] + aura 14/43; catalog must match combat (KI-180). */
|
|
241
|
+
const FILL_EMPTY_SPELL_IDS = new Set([20911, 20912, 20913, 20914, 25899]);
|
|
242
|
+
|
|
243
|
+
export function fillEmptyEffectsFromRaw(
|
|
244
|
+
spell: SpellDef,
|
|
245
|
+
ctx: ResolveSpellEffectsOpts = {},
|
|
246
|
+
): SpellDef {
|
|
247
|
+
if (!isBakeEffectsEmpty(spell)) return spell;
|
|
248
|
+
const raw = spell.rawEffects;
|
|
249
|
+
if (!raw?.length) return spell;
|
|
250
|
+
const eligible = FILL_EMPTY_SPELL_IDS.has(spell.id | 0) || raw.some((r) => {
|
|
251
|
+
const eff = r.effect | 0;
|
|
252
|
+
const aura = r.auraName | 0;
|
|
253
|
+
return FILL_EMPTY_EFFECT_OPCODES.has(eff) || FILL_EMPTY_AURA_OPCODES.has(aura);
|
|
254
|
+
});
|
|
255
|
+
if (!eligible) return spell;
|
|
256
|
+
const resolved = resolveCombatSpell(spell, ctx);
|
|
257
|
+
if (!resolved.effects.length) return spell;
|
|
258
|
+
// Warriors never use combo points — DBC ATTR_EX_FINISH on Overpower is not NeedsComboPoints.
|
|
259
|
+
// Cite: SpellMgr.h NeedsComboPoints energy/rogue finishers; KI-569.
|
|
260
|
+
if (resolved.requiresComboPoints && resolved.powerType === 'rage') {
|
|
261
|
+
const out = { ...resolved };
|
|
262
|
+
delete (out as { requiresComboPoints?: boolean }).requiresComboPoints;
|
|
263
|
+
delete (out as { finishingScalesDamage?: boolean }).finishingScalesDamage;
|
|
264
|
+
return out;
|
|
265
|
+
}
|
|
266
|
+
return resolved;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// The interpreter gate, kept local to avoid a circular import. Read once: the env lookup goes through
|
|
270
|
+
// a V8 interceptor and ran per spell resolution per cast — 2.3% of a 40-unit tick profile.
|
|
271
|
+
const ENV_INTERPRETER_OFF = typeof process !== 'undefined'
|
|
272
|
+
&& process.env?.PHONECRAFT_SI_INTERPRETER === '0';
|
|
273
|
+
function interpreterGateOn(ctx?: InterpretContext): boolean {
|
|
274
|
+
if (ctx?.useInterpreter === false) return false;
|
|
275
|
+
if (ctx?.useInterpreter === true) return true;
|
|
276
|
+
return !ENV_INTERPRETER_OFF;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Resolve spell effects for the combat and item paths: raw effects with the gate on are interpreted,
|
|
280
|
+
// otherwise the baked list stands. No Math.random or wall clock — callers pass an injected rng.
|
|
281
|
+
export function resolveSpellEffects(
|
|
282
|
+
spell: SpellDef,
|
|
283
|
+
ctx: ResolveSpellEffectsOpts = {},
|
|
284
|
+
): InterpretResult {
|
|
285
|
+
const rawLen = spell.rawEffects?.length ?? 0;
|
|
286
|
+
const preferInterp =
|
|
287
|
+
ctx.forceInterpreter === true ||
|
|
288
|
+
(rawLen > 0 && interpreterGateOn(ctx));
|
|
289
|
+
|
|
290
|
+
if (preferInterp && rawLen > 0) {
|
|
291
|
+
const { forceInterpreter: _f, ...rest } = ctx;
|
|
292
|
+
return interpretSpellLocal(spell, { ...rest, useInterpreter: true });
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return {
|
|
296
|
+
effects: spell.effects ? spell.effects.slice() : [],
|
|
297
|
+
unhandled: [],
|
|
298
|
+
...(spell.strikeBonus != null ? { strikeBonus: spell.strikeBonus } : {}),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Spell ids whose hollow effect list hid the duration-scale surface. Mass-filling every hollow spell
|
|
303
|
+
// belongs to its own lane, since it re-classifies situational CC as a rotation keep-up.
|
|
304
|
+
export const DURATION_SURFACE_HOLLOW_SPELL_IDS: ReadonlySet<number> = new Set([
|
|
305
|
+
// Turn Undead — creature 19725 (20s di=18), player ranks 2878 (10s di=1), 10326 (20s di=18)
|
|
306
|
+
19725, 2878, 10326, 5627,
|
|
307
|
+
// Rapid Fire 3045 — 15s di=8
|
|
308
|
+
3045,
|
|
309
|
+
// Volley ranks — 6s di=32 (often already filled; materialize is no-op then)
|
|
310
|
+
1510, 14294, 14295, 14296,
|
|
311
|
+
// Creature Psychic Scream 13704 — same 6s di=32 pattern as KI-152 notes
|
|
312
|
+
13704,
|
|
313
|
+
]);
|
|
314
|
+
|
|
315
|
+
// Fill a bake-hollow effect list in place from the raw effects, for the duration-surface ids only:
|
|
316
|
+
// combat re-resolves, but data-store consumers and repros read the effect list for its duration.
|
|
317
|
+
export function materializeHollowSpellsInPlace(
|
|
318
|
+
spells: Iterable<SpellDef>,
|
|
319
|
+
ctx: ResolveSpellEffectsOpts = {},
|
|
320
|
+
opts: { onlyIds?: ReadonlySet<number> } = {},
|
|
321
|
+
): number {
|
|
322
|
+
const only = opts.onlyIds ?? DURATION_SURFACE_HOLLOW_SPELL_IDS;
|
|
323
|
+
let n = 0;
|
|
324
|
+
for (const spell of spells) {
|
|
325
|
+
if (!only.has(spell.id | 0)) continue;
|
|
326
|
+
if (spell.passive) continue;
|
|
327
|
+
if (!isBakeEffectsEmpty(spell)) continue;
|
|
328
|
+
if (!(spell.rawEffects?.length)) continue;
|
|
329
|
+
const resolved = resolveCombatSpell(spell, ctx);
|
|
330
|
+
if (!resolved.effects.length) continue;
|
|
331
|
+
spell.effects = resolved.effects.map((e) => ({ ...e }));
|
|
332
|
+
if (resolved.role && !spell.role) spell.role = resolved.role;
|
|
333
|
+
if (resolved.strikeBonus != null && spell.strikeBonus == null) {
|
|
334
|
+
spell.strikeBonus = resolved.strikeBonus;
|
|
335
|
+
}
|
|
336
|
+
if (resolved.rageGenerated != null && spell.rageGenerated == null) {
|
|
337
|
+
spell.rageGenerated = resolved.rageGenerated;
|
|
338
|
+
}
|
|
339
|
+
if (resolved.aoe != null && spell.aoe == null) spell.aoe = resolved.aoe;
|
|
340
|
+
n += 1;
|
|
341
|
+
}
|
|
342
|
+
return n;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// The combat materializer: a SpellDef with effects and strike bonus from the interpreter when raw
|
|
346
|
+
// effects exist. A shallow copy, so the bake row is not mutated; without raw it returns the input.
|
|
347
|
+
export function resolveCombatSpell(
|
|
348
|
+
spell: SpellDef,
|
|
349
|
+
ctx: ResolveSpellEffectsOpts = {},
|
|
350
|
+
): SpellDef {
|
|
351
|
+
if (!interpreterGateOn(ctx)) {
|
|
352
|
+
// Still stamp form attrs (notShapeshift / costPct) — independent of effect opcodes.
|
|
353
|
+
return applyFormAttrPatch(spell);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const rawLen = spell.rawEffects?.length ?? 0;
|
|
357
|
+
// Scripted talent residuals, the port of the talent-actives enricher. Filled only when the baked
|
|
358
|
+
// effects are empty, so a hand-built fixture or an already-resolved def is never clobbered.
|
|
359
|
+
const scripted = talentScriptedEffects(spell.id);
|
|
360
|
+
|
|
361
|
+
if (rawLen === 0) {
|
|
362
|
+
if (scripted && isBakeEffectsEmpty(spell)) {
|
|
363
|
+
return applyFormAttrPatch({ ...spell, effects: scripted.map((e) => ({ ...e })) });
|
|
364
|
+
}
|
|
365
|
+
return applyFormAttrPatch(spell);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const result = resolveSpellEffects(spell, { ...ctx, forceInterpreter: true });
|
|
369
|
+
let effects = result.effects.slice();
|
|
370
|
+
// Prefer the concrete scripted effects when the generic path left the list empty. Deep Wounds
|
|
371
|
+
// materializes intermediate dummy triggers that the C++ rewrites, so keep the holder.
|
|
372
|
+
if (
|
|
373
|
+
scripted
|
|
374
|
+
&& (
|
|
375
|
+
effects.length === 0
|
|
376
|
+
|| scripted.some((e) =>
|
|
377
|
+
e.kind === 'deep_wounds'
|
|
378
|
+
|| e.kind === 'pyroclasm'
|
|
379
|
+
|| e.kind === 'sweeping_strikes'
|
|
380
|
+
// C++ rewrites these dummy/proc holders (generic aura-42 would double-fire without the gate).
|
|
381
|
+
// Cite: UnitAuraProcHandler.cpp Cheat Death 28845; Adaptive Warding 28764; set/talent s20.
|
|
382
|
+
|| e.kind === 'cheat_death'
|
|
383
|
+
|| e.kind === 'adaptive_warding'
|
|
384
|
+
|| e.kind === 'class_power_set'
|
|
385
|
+
|| e.kind === 'vestments_greater_heal'
|
|
386
|
+
|| e.kind === 'dreamwalker_healing_touch'
|
|
387
|
+
|| e.kind === 'idol_healing_touch_refund'
|
|
388
|
+
|| e.kind === 'totem_lesser_healing_wave'
|
|
389
|
+
|| e.kind === 'master_of_elements'
|
|
390
|
+
|| e.kind === 'magic_absorption'
|
|
391
|
+
|| e.kind === 'oracle_healing_bonus'
|
|
392
|
+
|| e.kind === 'obsidian_armor'
|
|
393
|
+
|| e.kind === 'eye_for_an_eye'
|
|
394
|
+
|| e.kind === 'ignite'
|
|
395
|
+
// Aura 109 Improved Sprint stays scripted so generic add_target_trigger does not replace it.
|
|
396
|
+
// Cite: Spell.cpp:7433–7468; SpellEffects.cpp:4140–4147 case 30918.
|
|
397
|
+
|| e.kind === 'improved_sprint'
|
|
398
|
+
// Vampiric Embrace and Demonic Sacrifice leave a bare holder on the generic path, so the
|
|
399
|
+
// scripted payload is kept or the pickers classify them as utility rather than castable.
|
|
400
|
+
|| e.kind === 'vampiric_embrace'
|
|
401
|
+
|| e.kind === 'demonic_sacrifice',
|
|
402
|
+
)
|
|
403
|
+
)
|
|
404
|
+
) {
|
|
405
|
+
effects = scripted.map((e) => ({ ...e }));
|
|
406
|
+
}
|
|
407
|
+
{
|
|
408
|
+
// Combustion and kin: the DBC slots are real, so the C++ payload rides alongside them.
|
|
409
|
+
const extra = talentScriptedAppendEffects(spell.id);
|
|
410
|
+
if (extra?.length) {
|
|
411
|
+
const have = new Set(effects.map((e) => e.kind));
|
|
412
|
+
effects = [...effects, ...extra.filter((e) => !have.has(e.kind))];
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Runtime speed merge: when the bake dropped a speed aura the raw effects still carry, append it to
|
|
416
|
+
// both the resolved list and the shared bake row, so inspection sees the snare without a re-bake.
|
|
417
|
+
effects = materializeMissingSpeedFromRaw(spell, effects);
|
|
418
|
+
stampMissingSpeedFromRaw(spell);
|
|
419
|
+
// Second-slot rating buffs (Mongoose crit aura 52) when bake only mapped the first aura.
|
|
420
|
+
// Cite: materialize-rating-buffs.ts; KI-591.
|
|
421
|
+
effects = materializeMissingRatingBuffsFromRaw(spell, effects);
|
|
422
|
+
stampMissingRatingBuffsFromRaw(spell);
|
|
423
|
+
// Charm/possess (Enslave Demon / Mind Control) when bake only mapped the haste rider.
|
|
424
|
+
// Cite: materialize-charm.ts; SpellAuras HandleModCharm; KI-801.
|
|
425
|
+
effects = materializeMissingCharmFromRaw(spell, effects);
|
|
426
|
+
stampMissingCharmFromRaw(spell);
|
|
427
|
+
// Will of the Forsaken and Escape Artist: the seed layers stamp a cleanse for the control-breaker
|
|
428
|
+
// path, which the mechanic-immunity interpretation would drop, so it is merged back.
|
|
429
|
+
{
|
|
430
|
+
const bakeCleanses = (spell.effects ?? []).filter((e) => e.kind === 'cleanse');
|
|
431
|
+
if (bakeCleanses.length > 0 && !effects.some((e) => e.kind === 'cleanse')) {
|
|
432
|
+
effects = [...bakeCleanses.map((e) => ({ ...e })), ...effects];
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
// Spell-mod residuals such as a free cost or a crit bonus become a next-cast modifier, rank-generic
|
|
436
|
+
// from the intents. The scripted table wins above when it has a row.
|
|
437
|
+
effects = materializeSpellModIntents(result.intents, effects, spell);
|
|
438
|
+
effects = materializeOverrideClassScriptIntents(result.intents, effects, spell);
|
|
439
|
+
// The Orc Command racial is a permanent 5% pet damage buff, and the generic modifier materialize
|
|
440
|
+
// turns it into a 15-second self buff — the wrong target and the wrong duration.
|
|
441
|
+
if (spell.id === 20575 || spell.id === 20576) {
|
|
442
|
+
let amount = 5;
|
|
443
|
+
for (const r of spell.rawEffects ?? []) {
|
|
444
|
+
const aura = r.auraName | 0;
|
|
445
|
+
if (aura !== 107 && aura !== 108) continue;
|
|
446
|
+
const { min } = effectAmountRange(r, ctx);
|
|
447
|
+
if (min !== 0) { amount = min; break; }
|
|
448
|
+
}
|
|
449
|
+
effects = [{
|
|
450
|
+
kind: 'buff',
|
|
451
|
+
mod: 'damage_done_pct',
|
|
452
|
+
amount,
|
|
453
|
+
durationMs: 0,
|
|
454
|
+
applyTo: 'pet',
|
|
455
|
+
}];
|
|
456
|
+
}
|
|
457
|
+
// A resistance-percent intent on a physical mask becomes a live armor buff or debuff, and hostility
|
|
458
|
+
// comes from targetA: without the flag, Death Wish's own -20% armor read as a foe debuff.
|
|
459
|
+
for (const intent of result.intents ?? []) {
|
|
460
|
+
if (intent.kind !== 'mod_resistance_pct') continue;
|
|
461
|
+
if ((intent.schoolMask & 1) === 0) continue; // armor is the physical bit only
|
|
462
|
+
const rawSlot = (spell.rawEffects ?? []).find(
|
|
463
|
+
(r) => r.effect === 6 && r.auraName === 101,
|
|
464
|
+
);
|
|
465
|
+
const tgtA = (rawSlot?.targetA ?? 0) | 0;
|
|
466
|
+
effects.push(withHostile(
|
|
467
|
+
{
|
|
468
|
+
kind: 'buff' as const,
|
|
469
|
+
mod: 'armor_pct' as const,
|
|
470
|
+
amount: intent.amount,
|
|
471
|
+
durationMs: intent.durationMs,
|
|
472
|
+
},
|
|
473
|
+
tgtA,
|
|
474
|
+
intent.amount,
|
|
475
|
+
));
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// SESSION 3 — Warrior/Druid kit: block%, cleanse, Retaliation, Barkskin, FR, Execute.
|
|
479
|
+
// Cite: warrior-druid-kit.ts; SPELL-FIDELITY-RUNSHEET SESSION 3.
|
|
480
|
+
effects = materializeWarriorDruidKitEffects(spell, result, effects);
|
|
481
|
+
effects = materializeDispelMechanicIntents(result.intents, effects);
|
|
482
|
+
effects = materializeSpellMagnetIntents(result.intents, effects, spell);
|
|
483
|
+
if (ctx.rage != null) {
|
|
484
|
+
effects = applyExecuteRageToEffects(spell, effects, ctx.rage);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// SESSION 4 — Hunter kit: traps (armed proc), Feign Death, Aspect of the Beast.
|
|
488
|
+
// Cite: hunter-kit.ts; SPELL-FIDELITY-RUNSHEET SESSION 4.
|
|
489
|
+
effects = materializeHunterKitEffects(spell, result, effects);
|
|
490
|
+
|
|
491
|
+
// SESSION 5 — Priest/Warlock kit: Life Tap (health→mana), Lightwell ranks.
|
|
492
|
+
// Cite: priest-warlock-kit.ts; Warlock.cpp LifeTap; SPELL-FIDELITY-RUNSHEET SESSION 5.
|
|
493
|
+
effects = materializePriestWarlockKitEffects(spell, result, effects);
|
|
494
|
+
|
|
495
|
+
// SESSION 11 — Paladin kit: Blessing of Sacrifice / Light / Concentration Aura.
|
|
496
|
+
// Cite: paladin-kit.ts; SPELL-FIDELITY-RUNSHEET SESSION 11.
|
|
497
|
+
effects = materializePaladinKitEffects(spell, result, effects);
|
|
498
|
+
|
|
499
|
+
// Paladin seals replace their dummy and proc shells with a real seal effect so the active seal arms.
|
|
500
|
+
// Cite: paladin-seals.ts; enrich-paladin-seals.mjs.
|
|
501
|
+
const sealFx = materializePaladinSeal(spell);
|
|
502
|
+
if (sealFx) effects = sealMaterializedEffects(sealFx, spell, effects);
|
|
503
|
+
|
|
504
|
+
// Preserve a totem's ability kit through re-resolution: the handler emits only the slot, creature,
|
|
505
|
+
// health and duration, while the kit comes from the creature spell list.
|
|
506
|
+
for (let i = 0; i < effects.length; i++) {
|
|
507
|
+
const e = effects[i]!;
|
|
508
|
+
if (e.kind !== 'summon_totem') continue;
|
|
509
|
+
const bake = (spell.effects ?? []).find(
|
|
510
|
+
(be) => be.kind === 'summon_totem'
|
|
511
|
+
&& be.creature === e.creature
|
|
512
|
+
&& be.slot === e.slot,
|
|
513
|
+
);
|
|
514
|
+
if (!bake || bake.kind !== 'summon_totem') continue;
|
|
515
|
+
const hasKit = !!(bake.abilities && bake.abilities.length);
|
|
516
|
+
const hasTrigs = !!(bake.triggerAbilities && bake.triggerAbilities.length);
|
|
517
|
+
if (!hasKit && !hasTrigs && !bake.name) continue;
|
|
518
|
+
effects[i] = {
|
|
519
|
+
...e,
|
|
520
|
+
...(bake.name ? { name: bake.name } : {}),
|
|
521
|
+
...(hasKit
|
|
522
|
+
? { abilities: bake.abilities!.map((a) => ({ ...a, effects: a.effects.map((x) => ({ ...x })) })) }
|
|
523
|
+
: {}),
|
|
524
|
+
// The trigger abilities must survive re-resolution too, or every periodic totem loses its
|
|
525
|
+
// payload the moment combat re-resolves the spell and goes back to summoning a decoration.
|
|
526
|
+
...(hasTrigs
|
|
527
|
+
? { triggerAbilities: bake.triggerAbilities!.map((a) => ({ ...a, effects: a.effects.map((x) => ({ ...x })) })) }
|
|
528
|
+
: {}),
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Weapon imbue: prefer the offline kit, then merge the richer baked fields, then fill from the
|
|
533
|
+
// extracted enchantment table — so re-resolving never strips the combat payload.
|
|
534
|
+
for (let i = 0; i < effects.length; i++) {
|
|
535
|
+
const e = effects[i]!;
|
|
536
|
+
if (e.kind !== 'weapon_imbue') continue;
|
|
537
|
+
applyWeaponImbueKit(e);
|
|
538
|
+
if (!weaponImbueHasCombatKit(e)) {
|
|
539
|
+
const bake = (spell.effects ?? []).find(
|
|
540
|
+
(be) => be.kind === 'weapon_imbue' && be.enchantId === e.enchantId,
|
|
541
|
+
);
|
|
542
|
+
if (bake && bake.kind === 'weapon_imbue' && weaponImbueHasCombatKit(bake)) {
|
|
543
|
+
effects[i] = {
|
|
544
|
+
...e,
|
|
545
|
+
...(bake.attackPower != null ? { attackPower: bake.attackPower } : {}),
|
|
546
|
+
...(bake.equipSpellId != null ? { equipSpellId: bake.equipSpellId } : {}),
|
|
547
|
+
...(bake.combatSpellId != null ? { combatSpellId: bake.combatSpellId } : {}),
|
|
548
|
+
...(bake.combatChancePct != null ? { combatChancePct: bake.combatChancePct } : {}),
|
|
549
|
+
...(bake.combatPpm != null ? { combatPpm: bake.combatPpm } : {}),
|
|
550
|
+
...(bake.damageFlat != null ? { damageFlat: bake.damageFlat } : {}),
|
|
551
|
+
...(bake.rockbiterAmount != null ? { rockbiterAmount: bake.rockbiterAmount } : {}),
|
|
552
|
+
...(bake.combat
|
|
553
|
+
? {
|
|
554
|
+
combat: {
|
|
555
|
+
...bake.combat,
|
|
556
|
+
...(bake.combat.direct ? { direct: { ...bake.combat.direct } } : {}),
|
|
557
|
+
...(bake.combat.dot ? { dot: { ...bake.combat.dot } } : {}),
|
|
558
|
+
},
|
|
559
|
+
}
|
|
560
|
+
: {}),
|
|
561
|
+
...(bake.family && !e.family ? { family: bake.family } : {}),
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
// itemEnchant fallback — poisons (chance-only), stones (damageFlat), oils (equipSpellId).
|
|
566
|
+
// spellLookup fills combat.direct so Instant Poison actually deals nature damage on swing.
|
|
567
|
+
const cur = effects[i]!;
|
|
568
|
+
if (cur.kind !== 'weapon_imbue') continue;
|
|
569
|
+
const ench =
|
|
570
|
+
(ctx as { itemEnchantLookup?: (id: number) => unknown }).itemEnchantLookup?.(cur.enchantId)
|
|
571
|
+
?? (itemEnchantsTable as Record<string, { effects: unknown[] }>)[String(cur.enchantId)];
|
|
572
|
+
if (ench) {
|
|
573
|
+
applyWeaponImbueKitFromItemEnchant(
|
|
574
|
+
cur,
|
|
575
|
+
ench as Parameters<typeof applyWeaponImbueKitFromItemEnchant>[1],
|
|
576
|
+
ctx.spellLookup,
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
const bakeRole = spell.role;
|
|
582
|
+
// Safety net: an opcode with NO HANDLER AT ALL means the resolution is incomplete, not empty, and
|
|
583
|
+
// returning it erases a row the ETL got right. Gated on unhandled, so a real empty answer stands.
|
|
584
|
+
if (effects.length === 0 && (spell.effects?.length ?? 0) > 0 && result.unhandled.length > 0) {
|
|
585
|
+
return applyFormAttrPatch(spell);
|
|
586
|
+
}
|
|
587
|
+
// Pet-management rows survive regardless, because the ETL SYNTHESIZES them onto learn-spell rows
|
|
588
|
+
// whose opcode is handled and correctly emits nothing — so the guard above cannot see the drop.
|
|
589
|
+
{
|
|
590
|
+
const PET_KINDS = new Set(['summon_pet', 'dismiss_pet', 'revive_pet']);
|
|
591
|
+
// A guardian summon covers the same creature, so do not re-add a bake stamp of a plain pet summon
|
|
592
|
+
// on top of it. Cite: SpellEffects.cpp:2820-2992 EffectSummonGuardian.
|
|
593
|
+
const missing = (spell.effects ?? []).filter((b) => {
|
|
594
|
+
if (!PET_KINDS.has(b.kind)) return false;
|
|
595
|
+
if (effects.some((e) => e.kind === b.kind)) return false;
|
|
596
|
+
if (
|
|
597
|
+
b.kind === 'summon_pet'
|
|
598
|
+
&& effects.some(
|
|
599
|
+
(e) => e.kind === 'summon_guardian' && e.creature === b.creature,
|
|
600
|
+
)
|
|
601
|
+
) {
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
return true;
|
|
605
|
+
});
|
|
606
|
+
if (missing.length) effects = [...effects, ...missing.map((e) => ({ ...e }))];
|
|
607
|
+
}
|
|
608
|
+
// Aura-removal bodies, last so no earlier rewrite drops the holder. Cite: handlers/aura-remove.ts.
|
|
609
|
+
effects = materializeAuraRemoveEffects(spell, effects);
|
|
610
|
+
// interpretSpellLocal skips finalizeInterpret — lift consume/energy on this path too.
|
|
611
|
+
effects = liftConsumeEnergyIntents(result.intents, effects);
|
|
612
|
+
const out: SpellDef = {
|
|
613
|
+
...spell,
|
|
614
|
+
effects,
|
|
615
|
+
};
|
|
616
|
+
if (result.strikeBonus != null) {
|
|
617
|
+
out.strikeBonus = result.strikeBonus;
|
|
618
|
+
}
|
|
619
|
+
// A rage energize becomes generated rage in display units. The ETL stamps it from the spell's power
|
|
620
|
+
// type, but Bloodrage's spell is mana while the EFFECT is rage, so the bake never stamped it.
|
|
621
|
+
{
|
|
622
|
+
const POWER_RAGE = 1;
|
|
623
|
+
let fromEnergize = 0;
|
|
624
|
+
for (const e of effects) {
|
|
625
|
+
if (e.kind === 'energize' && e.powerType === POWER_RAGE) {
|
|
626
|
+
fromEnergize = Math.max(fromEnergize, Math.round((e.min ?? 0) / 10));
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (fromEnergize > 0) {
|
|
630
|
+
out.rageGenerated = Math.max(out.rageGenerated ?? 0, fromEnergize);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
// ADD_COMBO_POINTS is stamped as the top-level generated count: strike riders never re-apply the
|
|
634
|
+
// effect, so a thin raw-only row would land the damage and drop the combo point.
|
|
635
|
+
{
|
|
636
|
+
let fromCp = 0;
|
|
637
|
+
for (const e of effects) {
|
|
638
|
+
if (e.kind === 'combo_points') fromCp = Math.max(fromCp, e.amount | 0);
|
|
639
|
+
}
|
|
640
|
+
if (fromCp > 0) {
|
|
641
|
+
out.comboPointsGenerated = Math.max(out.comboPointsGenerated ?? 0, fromCp);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
// Drop the bake-time role when the effects were replaced: enrichers often stamped utility while the
|
|
645
|
+
// interpreter yields combat-usable kinds. Consumers re-derive it from the resolved list.
|
|
646
|
+
if (effects !== spell.effects) {
|
|
647
|
+
delete (out as { role?: string }).role;
|
|
648
|
+
}
|
|
649
|
+
// Phase Shift's combat stop is on APPLY, not a cast-time gate: the peaceful-only attribute on the
|
|
650
|
+
// bake row made the cast a no-op mid-fight, so pet AI never autocast it.
|
|
651
|
+
if (effects.some((e) => e.kind === 'mod_unattackable')) {
|
|
652
|
+
delete (out as { notInCombatOnly?: boolean }).notInCombatOnly;
|
|
653
|
+
delete (out as { outOfCombatOnly?: boolean }).outOfCombatOnly;
|
|
654
|
+
}
|
|
655
|
+
// A weapon-damage slot sets the strike role, preferred over a later buff-slot stamp — but NEVER over
|
|
656
|
+
// a non-derivable bake role: effect 58 says nothing about melee versus ranged, only SpellRange does.
|
|
657
|
+
if (
|
|
658
|
+
(result.role === 'strike' || (result.strikeBonus != null && result.strikeBonus > 0))
|
|
659
|
+
&& !(bakeRole && NON_DERIVABLE_ROLES.has(bakeRole))
|
|
660
|
+
) {
|
|
661
|
+
// Ranged weapon sample (Multi/Aimed, dmgClass RANGED) is not a melee strike.
|
|
662
|
+
// Cite: SpellEffects.cpp EffectWeaponDmg RANGED_ATTACK; KI-745.
|
|
663
|
+
if ((spell.dmgClass ?? -1) === 3) {
|
|
664
|
+
out.role = (spell.castTimeMs ?? 0) > 0 ? 'nuke' : 'instant_nuke';
|
|
665
|
+
} else {
|
|
666
|
+
out.role = 'strike';
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
// Seal materialization is the combat role (rotation classify / AI seal upkeep).
|
|
670
|
+
if (sealFx) {
|
|
671
|
+
out.role = 'seal';
|
|
672
|
+
}
|
|
673
|
+
// Preserve baked roles that are NOT a function of the resolved effects. For those the bake is the
|
|
674
|
+
// only source there will ever be, so discarding one drops the spell out of the spellbook entirely.
|
|
675
|
+
if (!out.role && bakeRole && NON_DERIVABLE_ROLES.has(bakeRole)) {
|
|
676
|
+
out.role = bakeRole;
|
|
677
|
+
}
|
|
678
|
+
// Paid role=shoot casts (Multi/Aimed) are not Auto Shot toggles — reclass after preserve.
|
|
679
|
+
// Pure Auto Shot / Shoot / Throw stay shoot (cost 0, cast 0, gcd 0). Cite: KI-745.
|
|
680
|
+
if (
|
|
681
|
+
out.role === 'shoot'
|
|
682
|
+
&& ((out.cost ?? 0) > 0 || (out.castTimeMs ?? 0) > 0 || (out.gcdMs ?? 0) > 0)
|
|
683
|
+
) {
|
|
684
|
+
out.role = (out.castTimeMs ?? 0) > 0 ? 'nuke' : 'instant_nuke';
|
|
685
|
+
}
|
|
686
|
+
// The spell mechanic: prefer the bake, else fold the raw slots. Template immunity masks and the
|
|
687
|
+
// diminishing-returns key both read this field. Cite: SharedDefines.h Mechanics.
|
|
688
|
+
if (!out.mechanic || out.mechanic === 'none') {
|
|
689
|
+
// Adopt a slot mechanic ONLY when every real slot carries the same one. Taking any slot's made
|
|
690
|
+
// Frostbolt's snare the SPELL's mechanic, and 146 damage spells went unusable on snare immunes.
|
|
691
|
+
const slots = (spell.rawEffects ?? []).filter((r) => (r.effect | 0) > 0);
|
|
692
|
+
const mechs = slots.map((r) => r.mechanic | 0);
|
|
693
|
+
const distinct = [...new Set(mechs.filter((m) => m > 0))];
|
|
694
|
+
if (distinct.length === 1 && mechs.every((m) => m === distinct[0])) {
|
|
695
|
+
const named = MECHANIC_NAME_FROM_ID[distinct[0]!];
|
|
696
|
+
if (named) out.mechanic = named;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// Warriors never use combo points: the finisher attribute on Overpower is not the combo-point one,
|
|
700
|
+
// so clear it or the ability list is unusable after a dodge. Cite: SpellMgr.h NeedsComboPoints.
|
|
701
|
+
if (out.requiresComboPoints && out.powerType === 'rage') {
|
|
702
|
+
delete (out as { requiresComboPoints?: boolean }).requiresComboPoints;
|
|
703
|
+
delete (out as { finishingScalesDamage?: boolean }).finishingScalesDamage;
|
|
704
|
+
}
|
|
705
|
+
// The interpreter can set the pet-heal role from a pet target even with no bake role — keep that
|
|
706
|
+
// stamp, or combat's health restore heals the owner instead of the pet.
|
|
707
|
+
if (!out.role && result.role && NON_DERIVABLE_ROLES.has(result.role)) {
|
|
708
|
+
out.role = result.role;
|
|
709
|
+
}
|
|
710
|
+
// AoE: enemy-area ImplicitTarget on raw slots (enrich-spell-aoe retired).
|
|
711
|
+
// Cite: SharedDefines Targets 15/16/22/24/28; combat castOnTargets.
|
|
712
|
+
if (out.aoe == null) {
|
|
713
|
+
const AREA_ENEMY = new Set([15, 16, 22, 24, 28]);
|
|
714
|
+
for (const r of spell.rawEffects ?? []) {
|
|
715
|
+
const a = r.targetA | 0;
|
|
716
|
+
const b = r.targetB | 0;
|
|
717
|
+
if (AREA_ENEMY.has(a) || AREA_ENEMY.has(b)) {
|
|
718
|
+
out.aoe = true;
|
|
719
|
+
break;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
// The not-shapeshift and allow-while-not attributes plus the form cost percent, from the ClassicDB
|
|
724
|
+
// map: the bake keeps only the stance columns, and the form attributes were lost with the enricher.
|
|
725
|
+
return applyFormAttrPatch(out);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// On-use: resolve ItemDef.useSpell through resolveSpellEffects. Returns null when the item has no useSpell
|
|
729
|
+
// or the spell is missing.
|
|
730
|
+
export function resolveItemOnUse(
|
|
731
|
+
item: Pick<ItemDef, 'useSpell'>,
|
|
732
|
+
lookup: SpellLookup,
|
|
733
|
+
ctx: ResolveSpellEffectsOpts = {},
|
|
734
|
+
): { spellId: number; spell: SpellDef; result: InterpretResult } | null {
|
|
735
|
+
const spellId = item.useSpell;
|
|
736
|
+
if (spellId == null) return null;
|
|
737
|
+
const spell = lookup(spellId) ?? undefined;
|
|
738
|
+
if (!spell) return null;
|
|
739
|
+
return { spellId, spell, result: resolveSpellEffects(spell, ctx) };
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// Combat bag-item surface: first buff or instant heal from an interpret result. Same shapes as
|
|
743
|
+
// character.combatItems today (apply_buff / restore_health).
|
|
744
|
+
export function combatUseEffectFromInterpret(
|
|
745
|
+
result: InterpretResult,
|
|
746
|
+
spellId: number,
|
|
747
|
+
):
|
|
748
|
+
| {
|
|
749
|
+
kind: 'apply_buff';
|
|
750
|
+
mod: BuffMod;
|
|
751
|
+
amount: number;
|
|
752
|
+
durationMs: number;
|
|
753
|
+
spellId: number;
|
|
754
|
+
}
|
|
755
|
+
| { kind: 'restore_health'; min: number; max: number }
|
|
756
|
+
| null {
|
|
757
|
+
for (const e of result.effects) {
|
|
758
|
+
if (e.kind === 'buff') {
|
|
759
|
+
return {
|
|
760
|
+
kind: 'apply_buff',
|
|
761
|
+
mod: e.mod,
|
|
762
|
+
amount: e.amount,
|
|
763
|
+
durationMs: e.durationMs,
|
|
764
|
+
spellId,
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
for (const e of result.effects) {
|
|
769
|
+
if (e.kind === 'heal') {
|
|
770
|
+
return { kind: 'restore_health', min: e.min, max: e.max };
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// On-use → combatItems effect when bake path is empty/inert but interpreter yields buff/heal. Skips
|
|
777
|
+
// food/drink restore_* (OOC only) when those appear on bake effects.
|
|
778
|
+
export function resolveCombatUseFromItem(
|
|
779
|
+
item: Pick<ItemDef, 'useSpell' | 'requiredLevel'>,
|
|
780
|
+
lookup: SpellLookup,
|
|
781
|
+
opts: { level: number; ctx?: ResolveSpellEffectsOpts } = { level: 1 },
|
|
782
|
+
):
|
|
783
|
+
| {
|
|
784
|
+
kind: 'apply_buff';
|
|
785
|
+
mod: BuffMod;
|
|
786
|
+
amount: number;
|
|
787
|
+
durationMs: number;
|
|
788
|
+
spellId: number;
|
|
789
|
+
cooldownMs: number;
|
|
790
|
+
}
|
|
791
|
+
| {
|
|
792
|
+
kind: 'restore_health';
|
|
793
|
+
min: number;
|
|
794
|
+
max: number;
|
|
795
|
+
cooldownMs: number;
|
|
796
|
+
spellId: number;
|
|
797
|
+
}
|
|
798
|
+
| null {
|
|
799
|
+
const resolved = resolveItemOnUse(item, lookup, opts.ctx);
|
|
800
|
+
if (!resolved) return null;
|
|
801
|
+
const { spell, spellId, result } = resolved;
|
|
802
|
+
|
|
803
|
+
// Skip OOC food/drink when bake still tags them (interpreter may not re-emit restore_*)
|
|
804
|
+
const hasFoodDrinkRestore = (spell.effects ?? []).some(
|
|
805
|
+
(e) => e.kind === 'restore_health' || e.kind === 'restore_power',
|
|
806
|
+
);
|
|
807
|
+
if (hasFoodDrinkRestore) return null;
|
|
808
|
+
|
|
809
|
+
// Item.RequiredLevel only — spell.reqLevel over-gates pots (KI-855); alone under-gates (KI-837).
|
|
810
|
+
// Cite: Player.cpp:9797 CanUseItem.
|
|
811
|
+
const req = (item.requiredLevel | 0) || 1;
|
|
812
|
+
if (opts.level < req) return null;
|
|
813
|
+
|
|
814
|
+
const use = combatUseEffectFromInterpret(result, spellId);
|
|
815
|
+
if (!use) return null;
|
|
816
|
+
const cooldownMs = spell.cooldownMs ?? 0;
|
|
817
|
+
if (use.kind === 'apply_buff') {
|
|
818
|
+
return { ...use, cooldownMs };
|
|
819
|
+
}
|
|
820
|
+
return { ...use, cooldownMs, spellId };
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// On-equip: resolve each equipSpells[] id through the interpreter. Additive path for previously inert
|
|
824
|
+
// empty-effects equip auras (does not replace equipMods).
|
|
825
|
+
export function resolveEquipSpells(
|
|
826
|
+
equipSpellIds: number[] | undefined | null,
|
|
827
|
+
lookup: SpellLookup,
|
|
828
|
+
ctx: ResolveSpellEffectsOpts = {},
|
|
829
|
+
): Array<{ spellId: number; spell: SpellDef; result: InterpretResult }> {
|
|
830
|
+
const out: Array<{ spellId: number; spell: SpellDef; result: InterpretResult }> = [];
|
|
831
|
+
if (!equipSpellIds?.length) return out;
|
|
832
|
+
for (const spellId of equipSpellIds) {
|
|
833
|
+
const spell = lookup(spellId) ?? undefined;
|
|
834
|
+
if (!spell) continue;
|
|
835
|
+
out.push({ spellId, spell, result: resolveSpellEffects(spell, ctx) });
|
|
836
|
+
}
|
|
837
|
+
return out;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// Buff mods from equip spells (interpreter when bake empty). Non-hostile buff only. Caller may merge with
|
|
841
|
+
// ItemDef.equipMods without dropping either side.
|
|
842
|
+
export function resolveEquipBuffMods(
|
|
843
|
+
equipSpellIds: number[] | undefined | null,
|
|
844
|
+
lookup: SpellLookup,
|
|
845
|
+
ctx: ResolveSpellEffectsOpts = {},
|
|
846
|
+
): Array<{ mod: string; amount: number; spellId: number }> {
|
|
847
|
+
const mods: Array<{ mod: string; amount: number; spellId: number }> = [];
|
|
848
|
+
for (const { spellId, result } of resolveEquipSpells(equipSpellIds, lookup, ctx)) {
|
|
849
|
+
for (const e of result.effects) {
|
|
850
|
+
if (e.kind !== 'buff') continue;
|
|
851
|
+
if (e.hostile) continue;
|
|
852
|
+
mods.push({ mod: e.mod, amount: e.amount, spellId });
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return mods;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// Build the proc metadata from an item's proc row and an optional holder spell. The rates and flags
|
|
859
|
+
// come from the item first, then the holder's proc event and spell row — never invented.
|
|
860
|
+
export function buildItemProcMeta(
|
|
861
|
+
proc: ItemProcRow,
|
|
862
|
+
holderSpell?: SpellDef | null,
|
|
863
|
+
): ProcTriggerSpellMeta {
|
|
864
|
+
const holderId = (holderSpell?.id ?? proc.spell) | 0;
|
|
865
|
+
const pe = holderSpell?.spellProcEvent;
|
|
866
|
+
|
|
867
|
+
// Aura-42 trigger chain when holder rawEffects expose it.
|
|
868
|
+
let triggerSpellId = proc.spell | 0;
|
|
869
|
+
let amount = 0;
|
|
870
|
+
let fromAura42 = false;
|
|
871
|
+
if (holderSpell?.rawEffects?.length) {
|
|
872
|
+
for (const raw of holderSpell.rawEffects) {
|
|
873
|
+
if ((raw.effect | 0) !== SPELL_EFFECT_APPLY_AURA) continue;
|
|
874
|
+
if ((raw.auraName | 0) !== SPELL_AURA_PROC_TRIGGER_SPELL) continue;
|
|
875
|
+
fromAura42 = true;
|
|
876
|
+
const rawTrig = raw.triggerSpell | 0;
|
|
877
|
+
triggerSpellId = resolveProcTriggerSpellId(
|
|
878
|
+
holderId,
|
|
879
|
+
rawTrig,
|
|
880
|
+
holderSpell.spellFamilyName,
|
|
881
|
+
holderSpell.spellFamilyFlags,
|
|
882
|
+
);
|
|
883
|
+
const { min } = effectAmountRange(raw);
|
|
884
|
+
amount = min;
|
|
885
|
+
break;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
// Prefer full meta builder when aura-42 raw is present (Lightning Shield specials, etc.).
|
|
889
|
+
if (fromAura42 && holderSpell?.rawEffects) {
|
|
890
|
+
const raw42 = holderSpell.rawEffects.find(
|
|
891
|
+
(r) =>
|
|
892
|
+
(r.effect | 0) === SPELL_EFFECT_APPLY_AURA &&
|
|
893
|
+
(r.auraName | 0) === SPELL_AURA_PROC_TRIGGER_SPELL,
|
|
894
|
+
);
|
|
895
|
+
if (raw42) {
|
|
896
|
+
const { min, max } = effectAmountRange(raw42);
|
|
897
|
+
const built = buildProcTriggerSpellMeta(
|
|
898
|
+
holderSpell,
|
|
899
|
+
raw42,
|
|
900
|
+
min,
|
|
901
|
+
max || min,
|
|
902
|
+
0,
|
|
903
|
+
holderSpell.school ?? 'physical',
|
|
904
|
+
);
|
|
905
|
+
if (built) {
|
|
906
|
+
// Overlay the item row's rates when the bake exposes them — the same sourced numbers. Flags
|
|
907
|
+
// come from the item row only, so a fight with no item filters stays seed-stable.
|
|
908
|
+
return {
|
|
909
|
+
...built,
|
|
910
|
+
// ITEM/enchant proc: `chancePct > 100` is the "use GetWeaponProcChance()" sentinel here,
|
|
911
|
+
// not "always". Cite: Player.cpp:7388. Aura procs must NOT carry this.
|
|
912
|
+
isItemProc: true,
|
|
913
|
+
chancePct:
|
|
914
|
+
proc.chancePct != null && proc.chancePct > 0
|
|
915
|
+
? proc.chancePct
|
|
916
|
+
: built.chancePct,
|
|
917
|
+
ppmRate:
|
|
918
|
+
proc.ppm != null && proc.ppm > 0
|
|
919
|
+
? proc.ppm
|
|
920
|
+
: built.ppmRate,
|
|
921
|
+
cooldownMs:
|
|
922
|
+
proc.cooldownMs != null && proc.cooldownMs > 0
|
|
923
|
+
? proc.cooldownMs
|
|
924
|
+
: built.cooldownMs,
|
|
925
|
+
procFlags: (proc.flags ?? 0) | 0,
|
|
926
|
+
procEx:
|
|
927
|
+
proc.procEx != null && proc.procEx !== 0
|
|
928
|
+
? proc.procEx
|
|
929
|
+
: undefined,
|
|
930
|
+
schoolMask: proc.schoolMask,
|
|
931
|
+
spellFamilyName: proc.spellFamilyName,
|
|
932
|
+
spellFamilyMask: proc.spellFamilyMask,
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// Flat ItemDef-driven meta (no aura-42 body, or builder returned null).
|
|
939
|
+
let chancePct = 0;
|
|
940
|
+
if (proc.chancePct != null && proc.chancePct > 0) {
|
|
941
|
+
chancePct = proc.chancePct;
|
|
942
|
+
} else if (pe?.customChance != null && pe.customChance > 0) {
|
|
943
|
+
chancePct = pe.customChance;
|
|
944
|
+
} else if (holderSpell?.procChance != null && holderSpell.procChance > 0) {
|
|
945
|
+
chancePct = holderSpell.procChance;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
const ppmRate =
|
|
949
|
+
proc.ppm != null && proc.ppm > 0
|
|
950
|
+
? proc.ppm
|
|
951
|
+
: pe?.ppmRate != null && pe.ppmRate > 0
|
|
952
|
+
? pe.ppmRate
|
|
953
|
+
: undefined;
|
|
954
|
+
|
|
955
|
+
// ICD: ItemDef.cooldownMs first; else spell_proc_event.Cooldown (sourced bake).
|
|
956
|
+
const cooldownMs =
|
|
957
|
+
proc.cooldownMs != null && proc.cooldownMs > 0
|
|
958
|
+
? proc.cooldownMs
|
|
959
|
+
: pe?.cooldownMs != null && pe.cooldownMs > 0
|
|
960
|
+
? pe.cooldownMs
|
|
961
|
+
: undefined;
|
|
962
|
+
|
|
963
|
+
return {
|
|
964
|
+
holderSpellId: holderId,
|
|
965
|
+
triggerSpellId,
|
|
966
|
+
amount,
|
|
967
|
+
// ITEM/enchant proc: `chancePct > 100` is the "use GetWeaponProcChance()" sentinel on this path,
|
|
968
|
+
// not "always". Cite: Player.cpp:7388. Aura procs must NOT carry this.
|
|
969
|
+
isItemProc: true,
|
|
970
|
+
// ItemDef.flags only — 0 = no ProcFlags filter (legacy gear path).
|
|
971
|
+
procFlags: (proc.flags ?? 0) | 0,
|
|
972
|
+
procEx:
|
|
973
|
+
proc.procEx != null && proc.procEx !== 0
|
|
974
|
+
? proc.procEx
|
|
975
|
+
: undefined,
|
|
976
|
+
chancePct,
|
|
977
|
+
ppmRate,
|
|
978
|
+
cooldownMs,
|
|
979
|
+
schoolMask: proc.schoolMask,
|
|
980
|
+
spellFamilyName: proc.spellFamilyName,
|
|
981
|
+
spellFamilyMask: proc.spellFamilyMask,
|
|
982
|
+
cooldownOnFailure: holderSpell ? (hasAttrEx2(holderSpell, SPELL_ATTR_EX2.PROC_COOLDOWN_ON_FAILURE) ? true : undefined) : undefined,
|
|
983
|
+
bakeKind: 'proc_trigger_spell',
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Chance-on-hit roll via SI-PROC subsystem (PPM / flat chance + ICD). Does not apply effects — caller
|
|
988
|
+
// resolves trigger on fire.
|
|
989
|
+
export function tryItemChanceOnHit(
|
|
990
|
+
proc: ItemProcRow,
|
|
991
|
+
holderSpell: SpellDef | undefined | null,
|
|
992
|
+
eventCtx: ProcEventContext,
|
|
993
|
+
rng: Rng,
|
|
994
|
+
opts?: { cooldownReadyAt?: number },
|
|
995
|
+
): { fired: boolean; cooldownReadyAt: number | null; meta: ProcTriggerSpellMeta } {
|
|
996
|
+
const meta = buildItemProcMeta(proc, holderSpell);
|
|
997
|
+
const roll = tryProcTriggerSpell(meta, eventCtx, rng, opts);
|
|
998
|
+
return { fired: roll.fired, cooldownReadyAt: roll.cooldownReadyAt, meta };
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// After a successful gear-proc roll, produce a SpellDef whose `effects` are applyable. Empty bake holders:
|
|
1002
|
+
// interpret → follow aura-42 triggerSpell when present.
|
|
1003
|
+
export function resolveGearProcApplySpell(
|
|
1004
|
+
holderSpell: SpellDef,
|
|
1005
|
+
lookup: SpellLookup,
|
|
1006
|
+
ctx: ResolveSpellEffectsOpts = {},
|
|
1007
|
+
): SpellDef | null {
|
|
1008
|
+
// Non-empty bake: legacy path (unchanged surface).
|
|
1009
|
+
if (!isBakeEffectsEmpty(holderSpell)) {
|
|
1010
|
+
return holderSpell;
|
|
1011
|
+
}
|
|
1012
|
+
if (!holderSpell.rawEffects?.length) return null;
|
|
1013
|
+
|
|
1014
|
+
const result = resolveSpellEffects(holderSpell, ctx);
|
|
1015
|
+
|
|
1016
|
+
const hasDirect = result.effects.some(
|
|
1017
|
+
(e) =>
|
|
1018
|
+
e.kind === 'direct_damage' ||
|
|
1019
|
+
e.kind === 'dot' ||
|
|
1020
|
+
e.kind === 'heal' ||
|
|
1021
|
+
e.kind === 'buff' ||
|
|
1022
|
+
e.kind === 'cc' ||
|
|
1023
|
+
e.kind === 'conjure',
|
|
1024
|
+
);
|
|
1025
|
+
if (hasDirect) {
|
|
1026
|
+
return withEffects(holderSpell, result.effects);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
// Aura-42 / intent: cast the trigger spell's effects.
|
|
1030
|
+
let triggerId: number | undefined;
|
|
1031
|
+
for (const e of result.effects) {
|
|
1032
|
+
if (e.kind === 'proc_trigger_spell') {
|
|
1033
|
+
triggerId = e.triggerSpellId;
|
|
1034
|
+
break;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
if (triggerId == null && result.intents) {
|
|
1038
|
+
for (const i of result.intents) {
|
|
1039
|
+
if (i.kind === 'proc_trigger_spell') {
|
|
1040
|
+
triggerId = i.triggerSpellId;
|
|
1041
|
+
break;
|
|
1042
|
+
}
|
|
1043
|
+
if (i.kind === 'proc_triggered_cast') {
|
|
1044
|
+
triggerId = i.triggerSpellId;
|
|
1045
|
+
break;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
// Raw trigger when interpret only left unhandled/empty secondary.
|
|
1050
|
+
if (triggerId == null) {
|
|
1051
|
+
for (const raw of holderSpell.rawEffects) {
|
|
1052
|
+
if (
|
|
1053
|
+
(raw.effect | 0) === SPELL_EFFECT_APPLY_AURA &&
|
|
1054
|
+
(raw.auraName | 0) === SPELL_AURA_PROC_TRIGGER_SPELL &&
|
|
1055
|
+
(raw.triggerSpell | 0) > 0
|
|
1056
|
+
) {
|
|
1057
|
+
triggerId = resolveProcTriggerSpellId(
|
|
1058
|
+
holderSpell.id,
|
|
1059
|
+
raw.triggerSpell | 0,
|
|
1060
|
+
holderSpell.spellFamilyName,
|
|
1061
|
+
holderSpell.spellFamilyFlags,
|
|
1062
|
+
);
|
|
1063
|
+
break;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
if (triggerId != null && triggerId > 0) {
|
|
1069
|
+
const trig = lookup(triggerId) ?? undefined;
|
|
1070
|
+
if (!trig) return null;
|
|
1071
|
+
const trigResult = resolveSpellEffects(trig, ctx);
|
|
1072
|
+
const effects =
|
|
1073
|
+
trigResult.effects.length > 0 ? trigResult.effects : (trig.effects ?? []);
|
|
1074
|
+
if (!effects.length) return null;
|
|
1075
|
+
return withEffects(trig, effects);
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
if (result.effects.length > 0) {
|
|
1079
|
+
return withEffects(holderSpell, result.effects);
|
|
1080
|
+
}
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
function withEffects(spell: SpellDef, effects: SpellEffect[]): SpellDef {
|
|
1085
|
+
return { ...spell, effects };
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// Nested trigger spell ids for gear procs (aura-42 holders) so combat kits can resolve them. Pure; does not
|
|
1089
|
+
// invent ids.
|
|
1090
|
+
export function gearProcTriggerSpellIds(
|
|
1091
|
+
procs: ItemProcRow[] | undefined | null,
|
|
1092
|
+
lookup: SpellLookup,
|
|
1093
|
+
): number[] {
|
|
1094
|
+
const ids: number[] = [];
|
|
1095
|
+
const seen = new Set<number>();
|
|
1096
|
+
for (const p of procs ?? []) {
|
|
1097
|
+
if (!p.spell || seen.has(p.spell)) continue;
|
|
1098
|
+
seen.add(p.spell);
|
|
1099
|
+
ids.push(p.spell);
|
|
1100
|
+
const holder = lookup(p.spell) ?? undefined;
|
|
1101
|
+
if (!holder?.rawEffects) continue;
|
|
1102
|
+
for (const raw of holder.rawEffects) {
|
|
1103
|
+
if (
|
|
1104
|
+
(raw.effect | 0) === SPELL_EFFECT_APPLY_AURA &&
|
|
1105
|
+
(raw.auraName | 0) === SPELL_AURA_PROC_TRIGGER_SPELL
|
|
1106
|
+
) {
|
|
1107
|
+
const tid = resolveProcTriggerSpellId(
|
|
1108
|
+
holder.id,
|
|
1109
|
+
raw.triggerSpell | 0,
|
|
1110
|
+
holder.spellFamilyName,
|
|
1111
|
+
holder.spellFamilyFlags,
|
|
1112
|
+
);
|
|
1113
|
+
if (tid > 0 && !seen.has(tid)) {
|
|
1114
|
+
seen.add(tid);
|
|
1115
|
+
ids.push(tid);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
return ids;
|
|
1121
|
+
}
|