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,1583 @@
|
|
|
1
|
+
/** SI2.5 / SI3 handlers — auras-core (split from handlers.ts, pure move). */
|
|
2
|
+
|
|
3
|
+
import type { BuffMod, RawSpellEffect, School, SpellEffect } from '../../../../data/schema.ts';
|
|
4
|
+
import {
|
|
5
|
+
buildModStunCcEffect,
|
|
6
|
+
resolveModStunMechanicId,
|
|
7
|
+
} from '../../../../domain/spells/breakableStunCc.ts';
|
|
8
|
+
import { effectAmountRange, clampPositiveRange } from '../amount.ts';
|
|
9
|
+
import type {
|
|
10
|
+
InterpretIntent,
|
|
11
|
+
} from '../types.ts';
|
|
12
|
+
import { STAT_MOD, TARGET_PET, withHostile, HOSTILE_IMPLICIT } from '../targeting.ts';
|
|
13
|
+
import {
|
|
14
|
+
SPELL_AURA_MOD_DECREASE_SPEED,
|
|
15
|
+
SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED,
|
|
16
|
+
SPELL_AURA_MOD_INCREASE_SPEED,
|
|
17
|
+
SPELL_AURA_MOD_STAT,
|
|
18
|
+
SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT,
|
|
19
|
+
} from '../opcodes.ts';
|
|
20
|
+
import type {
|
|
21
|
+
HandlerState,
|
|
22
|
+
} from './shared.ts';
|
|
23
|
+
import {
|
|
24
|
+
POWER_RAGE,
|
|
25
|
+
SPELLFAMILY_GENERIC,
|
|
26
|
+
SPELLFAMILY_MAGE,
|
|
27
|
+
SPELLFAMILY_WARRIOR,
|
|
28
|
+
SPELLFAMILY_PRIEST,
|
|
29
|
+
SPELLFAMILY_DRUID,
|
|
30
|
+
SPELLFAMILY_ROGUE,
|
|
31
|
+
SPELLFAMILY_HUNTER,
|
|
32
|
+
SPELLFAMILY_PALADIN,
|
|
33
|
+
CLASSMASK_WAND_USERS,
|
|
34
|
+
TRANSFORM_MISSING_CREATURE_DISPLAY,
|
|
35
|
+
IN_MILLISECONDS,
|
|
36
|
+
RIP_FLAGS,
|
|
37
|
+
RUPTURE_FLAGS,
|
|
38
|
+
SCORPID_STING_FLAGS,
|
|
39
|
+
SPELL_SCHOOL_MASK_NORMAL,
|
|
40
|
+
MECHANIC_BANISH,
|
|
41
|
+
MOD_DMG_PCT_EXPIRE_CAST,
|
|
42
|
+
SCHOOLS,
|
|
43
|
+
WYVERN_STING_SLEEP,
|
|
44
|
+
WYVERN_STING_FAMILY_FLAGS,
|
|
45
|
+
SEAL_OF_THE_CRUSADER_IDS,
|
|
46
|
+
QUEST_TAME_FINAL,
|
|
47
|
+
BURNING_ADRENALINE_REMOVE_CASTS,
|
|
48
|
+
schoolOf,
|
|
49
|
+
familyOf,
|
|
50
|
+
flagsOf,
|
|
51
|
+
iconIdOf,
|
|
52
|
+
durationMsResolved,
|
|
53
|
+
withPpc,
|
|
54
|
+
trunc,
|
|
55
|
+
schoolFromSingleBitMask,
|
|
56
|
+
pushModSkillIntent,
|
|
57
|
+
pushAddModifierIntent,
|
|
58
|
+
pushOrMergePolymorphIncapacitate,
|
|
59
|
+
} from './shared.ts';
|
|
60
|
+
import { emitPeriodicTriggerSpellZero } from './periodic-trigger-zero.ts';
|
|
61
|
+
import {
|
|
62
|
+
HEALING_WAY_BUFF_SPELL_ID,
|
|
63
|
+
HEALING_WAY_MAX_STACKS,
|
|
64
|
+
} from '../class-scripts-kit.ts';
|
|
65
|
+
// ── SPELL_AURA_NONE (0) ── a no-op: no modifier and no combat effect. The only classic castable is
|
|
66
|
+
// the Orc racial Command stub; the real pet-damage Command uses auras 107 and 108.
|
|
67
|
+
export function handleAuraNone(
|
|
68
|
+
state: HandlerState,
|
|
69
|
+
_raw: RawSpellEffect,
|
|
70
|
+
_slot: number,
|
|
71
|
+
_effectType: number,
|
|
72
|
+
): void {
|
|
73
|
+
// C++ HandleNULL — intentionally empty body; still a held aura (Command 21563 stub).
|
|
74
|
+
// Cite: SpellAuras.cpp:61 HandleNULL; AURA_SLOT_DISPOSITIONS[0].
|
|
75
|
+
state.effects.push({
|
|
76
|
+
kind: 'script_handled_noop',
|
|
77
|
+
spellId: state.spell.id | 0,
|
|
78
|
+
} as never);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ── SPELL_AURA_PERIODIC_DAMAGE (3) ──────────────────────────────────────────
|
|
82
|
+
// Cite: SpellAuras.cpp:3156–3228 HandlePeriodicDamage
|
|
83
|
+
export function handlePeriodicDamage(
|
|
84
|
+
state: HandlerState,
|
|
85
|
+
raw: RawSpellEffect,
|
|
86
|
+
_slot: number,
|
|
87
|
+
_effectType: number,
|
|
88
|
+
): void {
|
|
89
|
+
const { min, pointsPerComboPoint } = effectAmountRange(raw, state.ctx);
|
|
90
|
+
let amount = min;
|
|
91
|
+
const fam = familyOf(state.spell);
|
|
92
|
+
const flags = flagsOf(state.spell);
|
|
93
|
+
const ctx = state.ctx;
|
|
94
|
+
|
|
95
|
+
// Rip / Rupture AP terms when AP+CP supplied. Cite: SpellAuras.cpp:3182–3210.
|
|
96
|
+
if (ctx.attackPower != null && ctx.comboPoints != null && ctx.comboPoints > 0) {
|
|
97
|
+
if (fam === SPELLFAMILY_DRUID && (flags & RIP_FLAGS) !== 0) {
|
|
98
|
+
// AP * min(cp, 4) / 100
|
|
99
|
+
let cp = ctx.comboPoints | 0;
|
|
100
|
+
if (cp > 4) cp = 4;
|
|
101
|
+
amount += trunc(ctx.attackPower * cp / 100);
|
|
102
|
+
} else if (fam === SPELLFAMILY_ROGUE && (flags & RUPTURE_FLAGS) !== 0) {
|
|
103
|
+
// AP * min(cp, 3) / 100
|
|
104
|
+
let cp = ctx.comboPoints | 0;
|
|
105
|
+
if (cp > 3) cp = 3;
|
|
106
|
+
amount += trunc(ctx.attackPower * cp / 100);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
amount = Math.max(1, amount);
|
|
111
|
+
const tickMs = (raw.amplitude | 0) || 3000;
|
|
112
|
+
const dur = durationMsResolved(state);
|
|
113
|
+
// ImplicitTargetA tags self-cost dots (Hellfire tgtA=1) vs foe DoTs (Corruption tgtA=6).
|
|
114
|
+
// Cite: SpellTargetDefines.h TARGET_UNIT_CASTER=1; applySpell isSelfTargetedDot.
|
|
115
|
+
const base = withPpc(
|
|
116
|
+
{
|
|
117
|
+
kind: 'dot',
|
|
118
|
+
school: schoolOf(state.spell),
|
|
119
|
+
min: amount,
|
|
120
|
+
max: amount,
|
|
121
|
+
durationMs: dur,
|
|
122
|
+
tickMs,
|
|
123
|
+
},
|
|
124
|
+
pointsPerComboPoint,
|
|
125
|
+
);
|
|
126
|
+
state.effects.push(withHostile(base, raw.targetA | 0, amount) as SpellEffect);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── SPELL_AURA_PERIODIC_HEAL (8) ────────────────────────────────────────────
|
|
130
|
+
// Cite: SpellAuras.cpp:3129–3153 HandlePeriodicHeal
|
|
131
|
+
export function handlePeriodicHeal(
|
|
132
|
+
state: HandlerState,
|
|
133
|
+
raw: RawSpellEffect,
|
|
134
|
+
_slot: number,
|
|
135
|
+
_effectType: number,
|
|
136
|
+
): void {
|
|
137
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
138
|
+
let amount = min;
|
|
139
|
+
|
|
140
|
+
// Polymorph Heal Effect 12939: amount = maxHealth / 10. Cite: SpellAuras.cpp:3150.
|
|
141
|
+
if (state.spell.id === 12939 && state.ctx.targetMaxHealth != null) {
|
|
142
|
+
amount = trunc(state.ctx.targetMaxHealth / 10);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
amount = Math.max(1, amount);
|
|
146
|
+
const tickMs = (raw.amplitude | 0) || 1000;
|
|
147
|
+
const dur = durationMsResolved(state);
|
|
148
|
+
// TARGET_PET: still periodic (Health Funnel 755 amp 1000 / DurIndex 1). Cite: SpellAuras.cpp:3129.
|
|
149
|
+
if ((raw.targetA | 0) === TARGET_PET) {
|
|
150
|
+
state.effects.push({
|
|
151
|
+
kind: 'restore_health',
|
|
152
|
+
amountPerTick: amount,
|
|
153
|
+
tickMs,
|
|
154
|
+
durationMs: dur,
|
|
155
|
+
applyTo: 'pet',
|
|
156
|
+
});
|
|
157
|
+
state.role = state.role || 'pet_heal';
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
state.effects.push({
|
|
161
|
+
kind: 'restore_health',
|
|
162
|
+
amountPerTick: amount,
|
|
163
|
+
tickMs,
|
|
164
|
+
durationMs: dur,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ── SPELL_AURA_MOD_STAT (29) ────────────────────────────────────────────────
|
|
169
|
+
// Cite: SpellAuras.cpp:3443–3487 HandleAuraModStat
|
|
170
|
+
export function handleModStat(
|
|
171
|
+
state: HandlerState,
|
|
172
|
+
raw: RawSpellEffect,
|
|
173
|
+
slot: number,
|
|
174
|
+
effectType: number,
|
|
175
|
+
): void {
|
|
176
|
+
const misc = raw.miscValue | 0;
|
|
177
|
+
// C++: miscvalue < -2 || > 4 → error return. Cite: :3445–3448.
|
|
178
|
+
if (misc < -2 || misc > 4) {
|
|
179
|
+
state.unhandled.push({
|
|
180
|
+
slot,
|
|
181
|
+
effect: effectType,
|
|
182
|
+
auraName: SPELL_AURA_MOD_STAT,
|
|
183
|
+
reason: `MOD_STAT miscValue ${misc} out of range [-2,4]`,
|
|
184
|
+
});
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const mod = STAT_MOD[String(misc)];
|
|
188
|
+
if (!mod) {
|
|
189
|
+
state.unhandled.push({
|
|
190
|
+
slot,
|
|
191
|
+
effect: effectType,
|
|
192
|
+
auraName: SPELL_AURA_MOD_STAT,
|
|
193
|
+
reason: `MOD_STAT miscValue ${misc} not in STAT_MOD map`,
|
|
194
|
+
});
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
// Signed amount — debuffs must not clamp to 1. Cite: bake map-spell-effects; :3480.
|
|
198
|
+
const { min, pointsPerComboPoint } = effectAmountRange(raw, state.ctx);
|
|
199
|
+
const dur = durationMsResolved(state);
|
|
200
|
+
const base = withPpc(
|
|
201
|
+
{ kind: 'buff' as const, mod, amount: min, durationMs: dur },
|
|
202
|
+
pointsPerComboPoint,
|
|
203
|
+
);
|
|
204
|
+
const tagged = withHostile(base, raw.targetA | 0, min);
|
|
205
|
+
state.effects.push(tagged as SpellEffect);
|
|
206
|
+
|
|
207
|
+
// Improved Scorpid Sting: on apply, scan the override-class-scripts auras for the talent rank and
|
|
208
|
+
// remove that percent of the sting's stat modifier. Cite: SpellAuras.cpp:3453-3472.
|
|
209
|
+
if ((flagsOf(state.spell) & SCORPID_STING_FLAGS) !== 0) {
|
|
210
|
+
let staminaToRemove = 0;
|
|
211
|
+
for (const script of state.ctx.classScriptAuras ?? []) {
|
|
212
|
+
switch (script.miscValue | 0) {
|
|
213
|
+
case 2388:
|
|
214
|
+
staminaToRemove = trunc(min * 10 / 100);
|
|
215
|
+
break;
|
|
216
|
+
case 2389:
|
|
217
|
+
staminaToRemove = trunc(min * 20 / 100);
|
|
218
|
+
break;
|
|
219
|
+
case 2390:
|
|
220
|
+
staminaToRemove = trunc(min * 30 / 100);
|
|
221
|
+
break;
|
|
222
|
+
default:
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// C++: if (staminaToRemove) CastCustomSpell(19486, …). Zero → no cast.
|
|
227
|
+
// Without classScriptAuras, branch is evaluated (no cast) — bake-thin parity.
|
|
228
|
+
if (staminaToRemove) {
|
|
229
|
+
state.intents.push({
|
|
230
|
+
kind: 'cast_custom_spell',
|
|
231
|
+
spellId: 19486,
|
|
232
|
+
bp0: staminaToRemove,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// ── SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT (174) & HEALING (175) ───────
|
|
239
|
+
// Cite: SpellAuras.cpp:3513–3531 HandleModSpellDamagePercentFromStat / HandleModSpellHealingPercentFromStat
|
|
240
|
+
export function handleModSpellDamageHealingOfStatPercent(
|
|
241
|
+
state: HandlerState,
|
|
242
|
+
raw: RawSpellEffect,
|
|
243
|
+
_slot: number,
|
|
244
|
+
_effectType: number,
|
|
245
|
+
): void {
|
|
246
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
247
|
+
const dur = durationMsResolved(state);
|
|
248
|
+
const mod: BuffMod = raw.auraName === SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT
|
|
249
|
+
? 'spell_power_of_spirit_pct'
|
|
250
|
+
: 'healing_power_of_spirit_pct';
|
|
251
|
+
const tagged = withHostile(
|
|
252
|
+
{ kind: 'buff' as const, mod, amount: min, durationMs: dur },
|
|
253
|
+
raw.targetA | 0,
|
|
254
|
+
min,
|
|
255
|
+
);
|
|
256
|
+
state.effects.push(tagged as SpellEffect);
|
|
257
|
+
state.role = state.role || 'buff';
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// ── SPELL_AURA_MOD_DAMAGE_DONE (13) ── a physical-only mask becomes attack power; any magic bit
|
|
261
|
+
// becomes spell power. Cite: SpellAuras.cpp:4026-4106 HandleModDamageDone.
|
|
262
|
+
export function handleModDamageDone(
|
|
263
|
+
state: HandlerState,
|
|
264
|
+
raw: RawSpellEffect,
|
|
265
|
+
_slot: number,
|
|
266
|
+
_effectType: number,
|
|
267
|
+
): void {
|
|
268
|
+
const misc = raw.miscValue | 0;
|
|
269
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
270
|
+
const dur = durationMsResolved(state);
|
|
271
|
+
// The bake-thin oracle surface collapses schools to one buff mod: exactly one magic school becomes
|
|
272
|
+
// that school's spell damage. Cite: SpellAuras.cpp:4047-4106; SharedDefines.h:175-197.
|
|
273
|
+
const physicalOnly = misc === SPELL_SCHOOL_MASK_NORMAL;
|
|
274
|
+
const oneSchool = schoolFromSingleBitMask(misc);
|
|
275
|
+
const mod: BuffMod = physicalOnly ? 'attack_power'
|
|
276
|
+
: oneSchool && oneSchool !== 'physical' ? (`spell_damage_${oneSchool}` as BuffMod)
|
|
277
|
+
: 'spell_power';
|
|
278
|
+
const tagged = withHostile(
|
|
279
|
+
{ kind: 'buff' as const, mod, amount: min, durationMs: dur },
|
|
280
|
+
raw.targetA | 0,
|
|
281
|
+
min,
|
|
282
|
+
);
|
|
283
|
+
state.effects.push(tagged as SpellEffect);
|
|
284
|
+
state.role = state.role || 'buff';
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// ── SPELL_AURA_MOD_STUN (12) ── the C++ always stuns; mechanic and interrupt flags decide hard stun
|
|
288
|
+
// versus break-on-damage. Duration reuses a bake-stamped ms when the index is absent; never invented.
|
|
289
|
+
function modStunDurationMs(state: HandlerState): number {
|
|
290
|
+
const fromIndex = durationMsResolved(state);
|
|
291
|
+
if (fromIndex > 0) return fromIndex;
|
|
292
|
+
// durationIndex present (incl. 21 → 0 infinite) → trust resolved value.
|
|
293
|
+
if (state.spell.durationIndex != null || state.ctx.durationIndex != null) {
|
|
294
|
+
return fromIndex;
|
|
295
|
+
}
|
|
296
|
+
if (state.ctx.durationMs != null) return fromIndex;
|
|
297
|
+
let best = 0;
|
|
298
|
+
for (const e of state.spell.effects ?? []) {
|
|
299
|
+
if (e.kind === 'cc' && (e.durationMs | 0) > best) best = e.durationMs | 0;
|
|
300
|
+
}
|
|
301
|
+
return best > 0 ? best : fromIndex;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export function handleModStun(
|
|
305
|
+
state: HandlerState,
|
|
306
|
+
raw: RawSpellEffect,
|
|
307
|
+
_slot: number,
|
|
308
|
+
_effectType: number,
|
|
309
|
+
): void {
|
|
310
|
+
const dur = modStunDurationMs(state);
|
|
311
|
+
const school = schoolOf(state.spell);
|
|
312
|
+
// Prefer raw.mechanic (spell-level Mechanic folded by mapRawEffects); name/tooltip
|
|
313
|
+
// fallback when older bakes left mechanic 0. Cite: breakableStunCc.resolveModStunMechanicId.
|
|
314
|
+
const mechId = resolveModStunMechanicId(state.spell, raw.mechanic | 0);
|
|
315
|
+
// The interrupt flags: the dump is 0 on every row, so the bake stamps the DBC field, and the context
|
|
316
|
+
// overrides only when a caller supplies them. Cite: SpellDefines.h AURA_INTERRUPT_FLAG_DAMAGE.
|
|
317
|
+
const spellAif = ((state.spell as { auraInterruptFlags?: number }).auraInterruptFlags ?? 0) | 0;
|
|
318
|
+
const aif = ((state.ctx.auraInterruptFlags ?? 0) | 0) || spellAif;
|
|
319
|
+
state.effects.push(buildModStunCcEffect(mechId, dur, school, state.spell.name, aif));
|
|
320
|
+
state.role = state.role || 'control';
|
|
321
|
+
|
|
322
|
+
// Specials (not in bake effects) — intents for SI5+ apply/remove.
|
|
323
|
+
const frostFreeze = school === 'frost';
|
|
324
|
+
let wyvernStingSleepSpellId: number | undefined;
|
|
325
|
+
let wyvernBossNatureDamage: { expire: number; dispel: number } | undefined;
|
|
326
|
+
|
|
327
|
+
// Wyvern Sting family specials fire on *remove*; document mapping at interpret.
|
|
328
|
+
// Cite: :2525–2573.
|
|
329
|
+
if (familyOf(state.spell) === SPELLFAMILY_HUNTER) {
|
|
330
|
+
const flags = flagsOf(state.spell);
|
|
331
|
+
const id = state.spell.id | 0;
|
|
332
|
+
if ((flags & WYVERN_STING_FAMILY_FLAGS) !== 0) {
|
|
333
|
+
const sleepId = WYVERN_STING_SLEEP[id];
|
|
334
|
+
if (sleepId) wyvernStingSleepSpellId = sleepId;
|
|
335
|
+
} else if (id === 26180) {
|
|
336
|
+
// Princess Huhuran: 500 nature on expire, 3000 on dispel. Cite: :2561–2564.
|
|
337
|
+
wyvernBossNatureDamage = { expire: 500, dispel: 3000 };
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (frostFreeze || wyvernStingSleepSpellId != null || wyvernBossNatureDamage) {
|
|
342
|
+
const intent: InterpretIntent = { kind: 'mod_stun_special' };
|
|
343
|
+
if (frostFreeze) intent.frostFreeze = true;
|
|
344
|
+
if (wyvernStingSleepSpellId != null) intent.wyvernStingSleepSpellId = wyvernStingSleepSpellId;
|
|
345
|
+
if (wyvernBossNatureDamage) intent.wyvernBossNatureDamage = wyvernBossNatureDamage;
|
|
346
|
+
state.intents.push(intent);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ── SPELL_AURA_MOD_RESISTANCE (22) ── physical becomes armor and magic bits become resistances.
|
|
351
|
+
// Cite: SpellAuras.cpp:3362-3381 HandleAuraModResistance; map-spell-effects mapModResistanceEffects.
|
|
352
|
+
export function handleModResistance(
|
|
353
|
+
state: HandlerState,
|
|
354
|
+
raw: RawSpellEffect,
|
|
355
|
+
_slot: number,
|
|
356
|
+
_effectType: number,
|
|
357
|
+
): void {
|
|
358
|
+
const { min, pointsPerComboPoint } = effectAmountRange(raw, state.ctx);
|
|
359
|
+
// The C++ returns early on a zero amount, but at interpret time the base can be 0 while the
|
|
360
|
+
// per-combo or per-level term is not — Expose Armor and the NPC armor shreds. Keep the row.
|
|
361
|
+
const perLevel = Number(raw.perLevel) || 0;
|
|
362
|
+
if (!min && !pointsPerComboPoint && !perLevel) {
|
|
363
|
+
state.effects.push({ kind: 'client_inform' });
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const mask = raw.miscValue | 0;
|
|
368
|
+
const dur = durationMsResolved(state);
|
|
369
|
+
const tgtA = raw.targetA | 0;
|
|
370
|
+
|
|
371
|
+
// Physical / armor (SPELL_SCHOOL_MASK_NORMAL = 1). Mask 0 → armor fallback.
|
|
372
|
+
// Cite: map-spell-effects.mjs:67–76; C++ loops all schools with misc bit. Cite: :3370–3379.
|
|
373
|
+
if (!mask || (mask & SPELL_SCHOOL_MASK_NORMAL) !== 0) {
|
|
374
|
+
// Hostile when the amount is negative, or when only the per-combo or per-level term is (Expose
|
|
375
|
+
// Armor, NPC Sunder). An enemy targetA already forces hostile; this covers the other shapes.
|
|
376
|
+
const hostilityAmt = min
|
|
377
|
+
|| (pointsPerComboPoint != null && pointsPerComboPoint < 0 ? -1 : 0)
|
|
378
|
+
|| (perLevel < 0 ? -1 : 0);
|
|
379
|
+
const base = withPpc(
|
|
380
|
+
{ kind: 'buff' as const, mod: 'armor' as const, amount: min, durationMs: dur },
|
|
381
|
+
pointsPerComboPoint,
|
|
382
|
+
);
|
|
383
|
+
state.effects.push(withHostile(base, tgtA, hostilityAmt) as SpellEffect);
|
|
384
|
+
}
|
|
385
|
+
// Magic schools by bit. Hostility is stamped from targetA so Curse of the Elements does not
|
|
386
|
+
// self-apply on the caster. Cite: SpellTargetDefines TARGET_UNIT_ENEMY = 6.
|
|
387
|
+
for (let bit = 1; bit <= 6; bit++) {
|
|
388
|
+
if ((mask & (1 << bit)) !== 0) {
|
|
389
|
+
state.effects.push(withHostile(
|
|
390
|
+
{ kind: 'resist', school: SCHOOLS[bit]!, amount: min },
|
|
391
|
+
tgtA,
|
|
392
|
+
min,
|
|
393
|
+
) as SpellEffect);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ── SPELL_AURA_MOD_BASE_RESISTANCE (83) ── the same player-visible surface as aura 22; only the
|
|
399
|
+
// UnitMods layer differs, base value rather than total. Cite: SpellAuras.cpp:3411-3422.
|
|
400
|
+
export function handleModBaseResistance(
|
|
401
|
+
state: HandlerState,
|
|
402
|
+
raw: RawSpellEffect,
|
|
403
|
+
_slot: number,
|
|
404
|
+
_effectType: number,
|
|
405
|
+
): void {
|
|
406
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
407
|
+
// C++: if (!m_modifier.m_amount) return. Cite: SpellAuras.cpp:3413–3414.
|
|
408
|
+
if (!min) return;
|
|
409
|
+
|
|
410
|
+
const mask = raw.miscValue | 0;
|
|
411
|
+
const dur = durationMsResolved(state);
|
|
412
|
+
const tgtA = raw.targetA | 0;
|
|
413
|
+
|
|
414
|
+
// Physical / armor (SPELL_SCHOOL_MASK_NORMAL = 1). Mask 0 → armor fallback.
|
|
415
|
+
// Cite: map-spell-effects.mjs:67–76; C++ school loop :3418–3421.
|
|
416
|
+
if (!mask || (mask & SPELL_SCHOOL_MASK_NORMAL) !== 0) {
|
|
417
|
+
const base = { kind: 'buff' as const, mod: 'armor' as const, amount: min, durationMs: dur };
|
|
418
|
+
state.effects.push(withHostile(base, tgtA, min) as SpellEffect);
|
|
419
|
+
}
|
|
420
|
+
// Magic schools: bit i → SCHOOLS[i] (holy=1 … arcane=6). Hostile from targetA (KI-765).
|
|
421
|
+
// Cite: map-spell-effects.mjs:79–82; SharedDefines SpellSchoolMask; withHostile.
|
|
422
|
+
for (let bit = 1; bit <= 6; bit++) {
|
|
423
|
+
if ((mask & (1 << bit)) !== 0) {
|
|
424
|
+
state.effects.push(withHostile(
|
|
425
|
+
{ kind: 'resist', school: SCHOOLS[bit]!, amount: min },
|
|
426
|
+
tgtA,
|
|
427
|
+
min,
|
|
428
|
+
) as SpellEffect);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Does an aura slot sit on the cast target rather than the caster? A channel holder is caster-targeted
|
|
434
|
+
// and stays; 92 of 445 periodic-trigger slots name someone else and were all landing on the caster.
|
|
435
|
+
function auraSitsOnTarget(raw: RawSpellEffect): boolean {
|
|
436
|
+
const a = raw.targetA | 0;
|
|
437
|
+
const b = raw.targetB | 0;
|
|
438
|
+
if (a === 21 || a === 25) return true;
|
|
439
|
+
// The cone, nearby-enemy and dest-enemy families. Missing these put dummy and periodic holders on
|
|
440
|
+
// the caster as a self-buff. Cite: SpellTargetDefines.h; targeting.ts HOSTILE_IMPLICIT.
|
|
441
|
+
if (HOSTILE_IMPLICIT.has(a) || HOSTILE_IMPLICIT.has(b)) return true;
|
|
442
|
+
return (a === 22 || a === 53) && b === 15;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function auraIsHostileImplicit(raw: RawSpellEffect): boolean {
|
|
446
|
+
return HOSTILE_IMPLICIT.has(raw.targetA | 0) || HOSTILE_IMPLICIT.has(raw.targetB | 0);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// ── SPELL_AURA_PERIODIC_TRIGGER_SPELL (23) ── baked as a proc trigger with a tick. A zero trigger id
|
|
450
|
+
// goes through the per-id switch in periodic-trigger-zero.ts. Cite: SpellAuras.cpp:3092-3111.
|
|
451
|
+
export function handlePeriodicTriggerSpell(
|
|
452
|
+
state: HandlerState,
|
|
453
|
+
raw: RawSpellEffect,
|
|
454
|
+
_slot: number,
|
|
455
|
+
_effectType: number,
|
|
456
|
+
): void {
|
|
457
|
+
const trig = raw.triggerSpell | 0;
|
|
458
|
+
if (!trig) {
|
|
459
|
+
// Scripted empty-trigger specials (or intentional no-ops). Cite: periodic-trigger-zero.ts.
|
|
460
|
+
emitPeriodicTriggerSpellZero(state, raw);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
465
|
+
const dur = durationMsResolved(state);
|
|
466
|
+
// Amplitude from EffectAmplitude (Aura ctor SetModifier periodictime). Cite: :280.
|
|
467
|
+
// 0 = on-hit (applySpell drops it); truthy tickMs is the periodic while gate. Do not || fallback.
|
|
468
|
+
const tickMs = raw.amplitude | 0;
|
|
469
|
+
state.effects.push({
|
|
470
|
+
kind: 'proc_trigger_spell',
|
|
471
|
+
triggerSpellId: trig,
|
|
472
|
+
durationMs: dur,
|
|
473
|
+
amount: min,
|
|
474
|
+
tickMs,
|
|
475
|
+
...(auraSitsOnTarget(raw) ? { auraOnTarget: true } : {}),
|
|
476
|
+
});
|
|
477
|
+
state.role = state.role || 'buff';
|
|
478
|
+
|
|
479
|
+
// On remove specials (Burning Adrenaline). Documented for SI5 remove path.
|
|
480
|
+
// Cite: :3098–3106.
|
|
481
|
+
const id = state.spell.id | 0;
|
|
482
|
+
if (id === 18173 || id === 23620) {
|
|
483
|
+
state.intents.push({
|
|
484
|
+
kind: 'periodic_trigger_remove',
|
|
485
|
+
castSpellIds: [...BURNING_ADRENALINE_REMOVE_CASTS],
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// ── SPELL_AURA_MOD_DECREASE_SPEED (33) ── baked as a signed speed percent. Snare immunity reads the
|
|
491
|
+
// spell's own mechanic, defaulting to snare when the effect carries none. Cite: SpellAuras.cpp:2907.
|
|
492
|
+
export function handleModDecreaseSpeed(
|
|
493
|
+
state: HandlerState,
|
|
494
|
+
raw: RawSpellEffect,
|
|
495
|
+
_slot: number,
|
|
496
|
+
_effectType: number,
|
|
497
|
+
): void {
|
|
498
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
499
|
+
const dur = durationMsResolved(state);
|
|
500
|
+
// Signed pct (slows negative). Cite: map-spell-effects.mjs:727–738.
|
|
501
|
+
const tagged = withHostile(
|
|
502
|
+
{
|
|
503
|
+
kind: 'speed' as const,
|
|
504
|
+
aura: SPELL_AURA_MOD_DECREASE_SPEED,
|
|
505
|
+
pct: min,
|
|
506
|
+
durationMs: dur,
|
|
507
|
+
},
|
|
508
|
+
raw.targetA | 0,
|
|
509
|
+
min,
|
|
510
|
+
raw.targetB | 0,
|
|
511
|
+
);
|
|
512
|
+
state.effects.push(tagged as SpellEffect);
|
|
513
|
+
state.role = state.role || 'buff';
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// ── SPELL_AURA_DUMMY (4) ── the bake is empty for this aura, so the specials become intents only.
|
|
517
|
+
// Cite: SpellAuras.cpp:1229-1620 HandleAuraDummy; PeriodicDummyTick :5025.
|
|
518
|
+
export function handleAuraDummy(
|
|
519
|
+
state: HandlerState,
|
|
520
|
+
raw: RawSpellEffect,
|
|
521
|
+
_slot: number,
|
|
522
|
+
_effectType: number,
|
|
523
|
+
): void {
|
|
524
|
+
// C++ requires Real; interpret is apply-time snapshot (Real=true). Cite: :1231–1233.
|
|
525
|
+
const id = state.spell.id | 0;
|
|
526
|
+
const fam = familyOf(state.spell);
|
|
527
|
+
|
|
528
|
+
// ── AT APPLY family/id specials ──────────────────────────────────────────
|
|
529
|
+
// Cite: :1238–1355.
|
|
530
|
+
if (fam === SPELLFAMILY_GENERIC) {
|
|
531
|
+
switch (id) {
|
|
532
|
+
case 126: // Eye of Kilrogg — charm pet 4277 casts 2585. Cite: :1245–1255.
|
|
533
|
+
state.intents.push({
|
|
534
|
+
kind: 'aura_dummy',
|
|
535
|
+
spellId: id,
|
|
536
|
+
action: 'cast_spell',
|
|
537
|
+
relatedSpellId: 2585,
|
|
538
|
+
on: 'apply',
|
|
539
|
+
});
|
|
540
|
+
return;
|
|
541
|
+
case 6946: // Curse of the Bleakheart
|
|
542
|
+
case 41170:
|
|
543
|
+
state.intents.push({
|
|
544
|
+
kind: 'aura_dummy',
|
|
545
|
+
spellId: id,
|
|
546
|
+
action: 'periodic',
|
|
547
|
+
periodMs: 5 * IN_MILLISECONDS,
|
|
548
|
+
// The C++ overrides the payload damage with this spell's second effect value, which our
|
|
549
|
+
// single-slot row does not carry, so 6945's own baked range stands.
|
|
550
|
+
relatedSpellId: id === 6946 ? 6945 : 41356,
|
|
551
|
+
chancePct: 5,
|
|
552
|
+
on: 'apply',
|
|
553
|
+
});
|
|
554
|
+
return;
|
|
555
|
+
case 7057: // Haunting Spirits — 30s period. Cite: :1265–1269.
|
|
556
|
+
state.intents.push({
|
|
557
|
+
kind: 'aura_dummy',
|
|
558
|
+
spellId: id,
|
|
559
|
+
action: 'periodic',
|
|
560
|
+
periodMs: 30 * IN_MILLISECONDS,
|
|
561
|
+
on: 'apply',
|
|
562
|
+
});
|
|
563
|
+
state.effects.push({ kind: 'client_inform' });
|
|
564
|
+
return;
|
|
565
|
+
case 7054: // Forsaken Skill — 1s period. Cite: :1270–1273.
|
|
566
|
+
state.intents.push({
|
|
567
|
+
kind: 'aura_dummy',
|
|
568
|
+
spellId: id,
|
|
569
|
+
action: 'periodic',
|
|
570
|
+
periodMs: 1 * IN_MILLISECONDS,
|
|
571
|
+
on: 'apply',
|
|
572
|
+
});
|
|
573
|
+
break;
|
|
574
|
+
case 13139: // net-o-matic root self 13138. Cite: :1274–1278.
|
|
575
|
+
state.intents.push({
|
|
576
|
+
kind: 'aura_dummy',
|
|
577
|
+
spellId: id,
|
|
578
|
+
action: 'cast_spell',
|
|
579
|
+
relatedSpellId: 13138,
|
|
580
|
+
on: 'apply',
|
|
581
|
+
});
|
|
582
|
+
return;
|
|
583
|
+
case 21094: // Separation Anxiety (Majordomo)
|
|
584
|
+
case 23487: // Separation Anxiety (Garr)
|
|
585
|
+
state.intents.push({
|
|
586
|
+
kind: 'aura_dummy',
|
|
587
|
+
spellId: id,
|
|
588
|
+
action: 'periodic',
|
|
589
|
+
periodMs: 5 * IN_MILLISECONDS,
|
|
590
|
+
on: 'apply',
|
|
591
|
+
});
|
|
592
|
+
return;
|
|
593
|
+
case 23183: // Mark of Frost → 23186 if has 23182. Cite: :1289–1293.
|
|
594
|
+
state.intents.push({
|
|
595
|
+
kind: 'aura_dummy',
|
|
596
|
+
spellId: id,
|
|
597
|
+
action: 'cast_spell',
|
|
598
|
+
relatedSpellId: 23186,
|
|
599
|
+
on: 'apply',
|
|
600
|
+
});
|
|
601
|
+
return;
|
|
602
|
+
case 25042: // Mark of Nature → 25043 if has 25040. Cite: :1295–1299.
|
|
603
|
+
state.intents.push({
|
|
604
|
+
kind: 'aura_dummy',
|
|
605
|
+
spellId: id,
|
|
606
|
+
action: 'cast_spell',
|
|
607
|
+
relatedSpellId: 25043,
|
|
608
|
+
on: 'apply',
|
|
609
|
+
});
|
|
610
|
+
return;
|
|
611
|
+
case 25471: // Attack Order → 25473. Cite: :1301–1304.
|
|
612
|
+
state.intents.push({
|
|
613
|
+
kind: 'aura_dummy',
|
|
614
|
+
spellId: id,
|
|
615
|
+
action: 'cast_spell',
|
|
616
|
+
relatedSpellId: 25473,
|
|
617
|
+
on: 'apply',
|
|
618
|
+
});
|
|
619
|
+
return;
|
|
620
|
+
case 26681: // Cologne removes Perfume 26682. Cite: :1306–1312.
|
|
621
|
+
state.intents.push({
|
|
622
|
+
kind: 'aura_dummy',
|
|
623
|
+
spellId: id,
|
|
624
|
+
action: 'remove_aura',
|
|
625
|
+
relatedSpellId: 26682,
|
|
626
|
+
on: 'apply',
|
|
627
|
+
});
|
|
628
|
+
state.effects.push({ kind: 'client_inform' });
|
|
629
|
+
return;
|
|
630
|
+
case 26682: // Perfume removes Cologne 26681. Cite: :1314–1320.
|
|
631
|
+
state.intents.push({
|
|
632
|
+
kind: 'aura_dummy',
|
|
633
|
+
spellId: id,
|
|
634
|
+
action: 'remove_aura',
|
|
635
|
+
relatedSpellId: 26681,
|
|
636
|
+
on: 'apply',
|
|
637
|
+
});
|
|
638
|
+
state.effects.push({ kind: 'client_inform' });
|
|
639
|
+
return;
|
|
640
|
+
default:
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
} else if (fam === SPELLFAMILY_WARRIOR) {
|
|
644
|
+
if (id === 23427) {
|
|
645
|
+
// Summon Infernals (Nefarian). Cite: :1328–1333.
|
|
646
|
+
state.intents.push({
|
|
647
|
+
kind: 'aura_dummy',
|
|
648
|
+
spellId: id,
|
|
649
|
+
action: 'cast_spell',
|
|
650
|
+
relatedSpellId: 23426,
|
|
651
|
+
on: 'apply',
|
|
652
|
+
});
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
} else if (fam === SPELLFAMILY_PRIEST) {
|
|
656
|
+
if (id === 30238) {
|
|
657
|
+
// Lordaeron's Blessing → 31906. Cite: :1340–1344.
|
|
658
|
+
state.intents.push({
|
|
659
|
+
kind: 'aura_dummy',
|
|
660
|
+
spellId: id,
|
|
661
|
+
action: 'cast_spell',
|
|
662
|
+
relatedSpellId: 31906,
|
|
663
|
+
on: 'apply',
|
|
664
|
+
});
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// ── AT REMOVE specials ───────────────────────────────────────────────────
|
|
670
|
+
// Cite: :1356–1448. Emit as remove-phase intents (SI5 consumes on expire/dispel/death).
|
|
671
|
+
const tameFinal = QUEST_TAME_FINAL[id];
|
|
672
|
+
if (tameFinal) {
|
|
673
|
+
state.intents.push({
|
|
674
|
+
kind: 'aura_dummy',
|
|
675
|
+
spellId: id,
|
|
676
|
+
action: 'quest_tame_final',
|
|
677
|
+
relatedSpellId: tameFinal,
|
|
678
|
+
on: 'remove',
|
|
679
|
+
});
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
switch (id) {
|
|
684
|
+
case 11129: // Combustion clear 28682 stacks. Cite: :1386–1388.
|
|
685
|
+
state.intents.push({
|
|
686
|
+
kind: 'aura_dummy',
|
|
687
|
+
spellId: id,
|
|
688
|
+
action: 'combustion_clear_stacks',
|
|
689
|
+
relatedSpellId: 28682,
|
|
690
|
+
on: 'remove',
|
|
691
|
+
});
|
|
692
|
+
return;
|
|
693
|
+
case 11826: // Electromagnetic Gigaflux Reactivator expire → 11828. Cite: :1389–1398.
|
|
694
|
+
state.intents.push({
|
|
695
|
+
kind: 'aura_dummy',
|
|
696
|
+
spellId: id,
|
|
697
|
+
action: 'cast_spell',
|
|
698
|
+
relatedSpellId: 11828,
|
|
699
|
+
on: 'remove_expire',
|
|
700
|
+
});
|
|
701
|
+
return;
|
|
702
|
+
case 12774: // Belnistrasz Idol → 12816 unless death. Cite: :1399–1409.
|
|
703
|
+
state.intents.push({
|
|
704
|
+
kind: 'aura_dummy',
|
|
705
|
+
spellId: id,
|
|
706
|
+
action: 'cast_spell',
|
|
707
|
+
relatedSpellId: 12816,
|
|
708
|
+
on: 'remove',
|
|
709
|
+
});
|
|
710
|
+
return;
|
|
711
|
+
case 17189: // Frostwhisper's Lifeblood full heal. Cite: :1410–1414.
|
|
712
|
+
state.intents.push({
|
|
713
|
+
kind: 'aura_dummy',
|
|
714
|
+
spellId: id,
|
|
715
|
+
action: 'cast_spell',
|
|
716
|
+
on: 'remove',
|
|
717
|
+
});
|
|
718
|
+
return;
|
|
719
|
+
case 25185: // Itch → 25187. Cite: :1415–1418.
|
|
720
|
+
state.intents.push({
|
|
721
|
+
kind: 'aura_dummy',
|
|
722
|
+
spellId: id,
|
|
723
|
+
action: 'cast_spell',
|
|
724
|
+
relatedSpellId: 25187,
|
|
725
|
+
on: 'remove',
|
|
726
|
+
});
|
|
727
|
+
return;
|
|
728
|
+
case 26077: // Itch → 26078. Cite: :1420–1423.
|
|
729
|
+
state.intents.push({
|
|
730
|
+
kind: 'aura_dummy',
|
|
731
|
+
spellId: id,
|
|
732
|
+
action: 'cast_spell',
|
|
733
|
+
relatedSpellId: 26078,
|
|
734
|
+
on: 'remove',
|
|
735
|
+
});
|
|
736
|
+
return;
|
|
737
|
+
case 29104: // Anub'Rekhan Aura death → 29105. Cite: :1425–1429.
|
|
738
|
+
state.intents.push({
|
|
739
|
+
kind: 'aura_dummy',
|
|
740
|
+
spellId: id,
|
|
741
|
+
action: 'cast_spell',
|
|
742
|
+
relatedSpellId: 29105,
|
|
743
|
+
on: 'remove_death',
|
|
744
|
+
});
|
|
745
|
+
return;
|
|
746
|
+
case 30238: // Lordaeron's Blessing remove 31906. Cite: :1431–1434.
|
|
747
|
+
state.intents.push({
|
|
748
|
+
kind: 'aura_dummy',
|
|
749
|
+
spellId: id,
|
|
750
|
+
action: 'remove_aura',
|
|
751
|
+
relatedSpellId: 31906,
|
|
752
|
+
on: 'remove',
|
|
753
|
+
});
|
|
754
|
+
return;
|
|
755
|
+
default:
|
|
756
|
+
break;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// Mage Arcane Missiles channel interrupt on target death. Cite: :1437–1446.
|
|
760
|
+
// Family MAGE + flag 0x800 — document for remove_death path.
|
|
761
|
+
if (fam === SPELLFAMILY_MAGE && (flagsOf(state.spell) & 0x800) !== 0) {
|
|
762
|
+
state.intents.push({
|
|
763
|
+
kind: 'aura_dummy',
|
|
764
|
+
spellId: id,
|
|
765
|
+
action: 'interrupt_channel_on_death',
|
|
766
|
+
on: 'remove_death',
|
|
767
|
+
});
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// ── AT APPLY & REMOVE ────────────────────────────────────────────────────
|
|
772
|
+
// Cite: :1450–1620.
|
|
773
|
+
if (fam === SPELLFAMILY_GENERIC) {
|
|
774
|
+
switch (id) {
|
|
775
|
+
case 6606: // Sleep Until Cancelled visual
|
|
776
|
+
case 16093:
|
|
777
|
+
state.intents.push({
|
|
778
|
+
kind: 'aura_dummy',
|
|
779
|
+
spellId: id,
|
|
780
|
+
action: 'sleep_visual',
|
|
781
|
+
on: 'both',
|
|
782
|
+
});
|
|
783
|
+
return;
|
|
784
|
+
case 24658: // Unstable Power → 24659. Cite: :1482–1493.
|
|
785
|
+
state.intents.push({
|
|
786
|
+
kind: 'aura_dummy',
|
|
787
|
+
spellId: id,
|
|
788
|
+
action: 'cast_spell',
|
|
789
|
+
relatedSpellId: 24659,
|
|
790
|
+
on: 'apply',
|
|
791
|
+
});
|
|
792
|
+
return;
|
|
793
|
+
case 24661: // Restless Strength → 24662. Cite: :1495–1506.
|
|
794
|
+
state.intents.push({
|
|
795
|
+
kind: 'aura_dummy',
|
|
796
|
+
spellId: id,
|
|
797
|
+
action: 'cast_spell',
|
|
798
|
+
relatedSpellId: 24662,
|
|
799
|
+
on: 'both',
|
|
800
|
+
});
|
|
801
|
+
return;
|
|
802
|
+
case 28819: // Submerge Visual. Cite: :1508–1518.
|
|
803
|
+
state.intents.push({
|
|
804
|
+
kind: 'aura_dummy',
|
|
805
|
+
spellId: id,
|
|
806
|
+
action: 'sleep_visual',
|
|
807
|
+
on: 'both',
|
|
808
|
+
});
|
|
809
|
+
return;
|
|
810
|
+
case 29266: // Permanent Feign Death. Cite: :1520–1530.
|
|
811
|
+
state.intents.push({
|
|
812
|
+
kind: 'aura_dummy',
|
|
813
|
+
spellId: id,
|
|
814
|
+
action: 'feign_death',
|
|
815
|
+
on: 'both',
|
|
816
|
+
});
|
|
817
|
+
return;
|
|
818
|
+
default:
|
|
819
|
+
break;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// Predatory Strikes — icon 1563 player AP recalc. Cite: :1537–1543.
|
|
824
|
+
if (fam === SPELLFAMILY_DRUID && iconIdOf(state) === 1563) {
|
|
825
|
+
state.intents.push({
|
|
826
|
+
kind: 'aura_dummy',
|
|
827
|
+
spellId: id,
|
|
828
|
+
action: 'predatory_strikes_ap',
|
|
829
|
+
on: 'both',
|
|
830
|
+
});
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
// Seal of the Crusader ranks — 40% BASE_ATTACK DPS. Cite: :1576–1584.
|
|
835
|
+
if (fam === SPELLFAMILY_PALADIN && SEAL_OF_THE_CRUSADER_IDS.has(id)) {
|
|
836
|
+
state.intents.push({
|
|
837
|
+
kind: 'aura_dummy',
|
|
838
|
+
spellId: id,
|
|
839
|
+
action: 'seal_crusader_dps',
|
|
840
|
+
dpsPct: 40,
|
|
841
|
+
on: 'both',
|
|
842
|
+
});
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
// Healing Way 29203 — dummy amount is the % Healing Wave taken. Cite: Shaman.cpp:77–89.
|
|
847
|
+
if (id === HEALING_WAY_BUFF_SPELL_ID) {
|
|
848
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
849
|
+
const dur = durationMsResolved(state);
|
|
850
|
+
state.effects.push({
|
|
851
|
+
kind: 'healing_way',
|
|
852
|
+
amountPct: min,
|
|
853
|
+
durationMs: dur > 0 ? dur : 15_000,
|
|
854
|
+
maxStacks: HEALING_WAY_MAX_STACKS,
|
|
855
|
+
});
|
|
856
|
+
state.role = state.role || 'buff';
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// A generic dummy still attaches the aura holder — duration, icon, stacking — even with an empty
|
|
861
|
+
// handler body, so materialize a timed shell rather than leave the slot hollow.
|
|
862
|
+
const dur = durationMsResolved(state);
|
|
863
|
+
state.effects.push({
|
|
864
|
+
kind: 'aura_dummy_holder',
|
|
865
|
+
spellId: id,
|
|
866
|
+
durationMs: dur > 0 ? dur : 0,
|
|
867
|
+
// Whose icon is it? 106 of the 401 spells reaching here name a unit other than the caster, and
|
|
868
|
+
// every one of them was putting the timer on the CASTER.
|
|
869
|
+
...(auraSitsOnTarget(raw) ? { auraOnTarget: true } : {}),
|
|
870
|
+
...(auraIsHostileImplicit(raw) ? { hostile: true } : {}),
|
|
871
|
+
} as never);
|
|
872
|
+
state.role = state.role || 'buff';
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// ── SPELL_AURA_MOD_MELEE_HASTE (138) ── baked as a haste buff.
|
|
876
|
+
// Cite: SpellAuras.cpp:3929-3936 HandleModMeleeSpeedPct.
|
|
877
|
+
export function handleModMeleeHaste(
|
|
878
|
+
state: HandlerState,
|
|
879
|
+
raw: RawSpellEffect,
|
|
880
|
+
_slot: number,
|
|
881
|
+
_effectType: number,
|
|
882
|
+
): void {
|
|
883
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
884
|
+
const dur = durationMsResolved(state);
|
|
885
|
+
// C++: ApplyAttackTimePercentMod BASE+OFF with amount (signed). Cite: :3931–3935.
|
|
886
|
+
const tagged = withHostile(
|
|
887
|
+
{ kind: 'buff' as const, mod: 'haste' as const, amount: min, durationMs: dur },
|
|
888
|
+
raw.targetA | 0,
|
|
889
|
+
min,
|
|
890
|
+
);
|
|
891
|
+
state.effects.push(tagged as SpellEffect);
|
|
892
|
+
state.role = state.role || 'buff';
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
// ── SPELL_AURA_MOD_ATTACK_POWER (99) ── baked as an attack-power buff.
|
|
896
|
+
// Cite: SpellAuras.cpp:3987-3991 HandleAuraModAttackPower.
|
|
897
|
+
export function handleModAttackPower(
|
|
898
|
+
state: HandlerState,
|
|
899
|
+
raw: RawSpellEffect,
|
|
900
|
+
_slot: number,
|
|
901
|
+
_effectType: number,
|
|
902
|
+
): void {
|
|
903
|
+
const { min, pointsPerComboPoint } = effectAmountRange(raw, state.ctx);
|
|
904
|
+
const dur = durationMsResolved(state);
|
|
905
|
+
// C++: HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, amount). Cite: :3989–3990.
|
|
906
|
+
const base = withPpc(
|
|
907
|
+
{ kind: 'buff' as const, mod: 'attack_power' as const, amount: min, durationMs: dur },
|
|
908
|
+
pointsPerComboPoint,
|
|
909
|
+
);
|
|
910
|
+
state.effects.push(withHostile(base, raw.targetA | 0, min) as SpellEffect);
|
|
911
|
+
state.role = state.role || 'buff';
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
// ── SPELL_AURA_MOD_ATTACK_POWER_PCT (166) ── an attack-power-only percent, which applySpell converts
|
|
915
|
+
// to a flat delta at apply. Cite: SpellAuras.cpp:4004-4010.
|
|
916
|
+
export function handleModAttackPowerPercent(
|
|
917
|
+
state: HandlerState,
|
|
918
|
+
raw: RawSpellEffect,
|
|
919
|
+
_slot: number,
|
|
920
|
+
_effectType: number,
|
|
921
|
+
): void {
|
|
922
|
+
const { min, pointsPerComboPoint } = effectAmountRange(raw, state.ctx);
|
|
923
|
+
const base = withPpc(
|
|
924
|
+
{
|
|
925
|
+
kind: 'buff' as const,
|
|
926
|
+
mod: 'attack_power_pct' as const,
|
|
927
|
+
amount: min,
|
|
928
|
+
durationMs: durationMsResolved(state),
|
|
929
|
+
},
|
|
930
|
+
pointsPerComboPoint,
|
|
931
|
+
);
|
|
932
|
+
state.effects.push(withHostile(base, raw.targetA | 0, min) as SpellEffect);
|
|
933
|
+
state.role = state.role || 'buff';
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// ── SPELL_AURA_MOD_HEALING_DONE (135) ── player-only, consumed by the healing bonus, since Classic
|
|
937
|
+
// has no client field for it. Cite: SpellAuras.cpp:3528-3535 HandleModHealingDone.
|
|
938
|
+
export function handleModHealingDone(
|
|
939
|
+
state: HandlerState,
|
|
940
|
+
raw: RawSpellEffect,
|
|
941
|
+
_slot: number,
|
|
942
|
+
_effectType: number,
|
|
943
|
+
): void {
|
|
944
|
+
// C++: non-player → return. Cite: :3530–3531.
|
|
945
|
+
// Bake-thin default: emit (player path); skip when ctx.unitTargetIsPlayer === false.
|
|
946
|
+
if (state.ctx.unitTargetIsPlayer === false) return;
|
|
947
|
+
|
|
948
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
949
|
+
const dur = durationMsResolved(state);
|
|
950
|
+
// Flat +healing for equip auras (Increase Healing N). Cite: Unit.cpp SpellHealingBonusDone.
|
|
951
|
+
const tagged = withHostile(
|
|
952
|
+
{ kind: 'buff' as const, mod: 'healing_done' as const, amount: min, durationMs: dur },
|
|
953
|
+
raw.targetA | 0,
|
|
954
|
+
min,
|
|
955
|
+
);
|
|
956
|
+
state.effects.push(tagged as SpellEffect);
|
|
957
|
+
state.role = state.role || 'buff';
|
|
958
|
+
state.intents.push({
|
|
959
|
+
kind: 'mod_healing_done',
|
|
960
|
+
amount: min,
|
|
961
|
+
schoolMask: raw.miscValue | 0,
|
|
962
|
+
durationMs: dur,
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
// ── SPELL_AURA_MOUNTED (78) ── emitted as a real EFFECT, not an intent: the census counted intents
|
|
967
|
+
// while consumers of the effect list saw only the speed aura. Cite: SpellAuras.cpp:1629-1656.
|
|
968
|
+
export function handleAuraMounted(
|
|
969
|
+
state: HandlerState,
|
|
970
|
+
raw: RawSpellEffect,
|
|
971
|
+
_slot: number,
|
|
972
|
+
_effectType: number,
|
|
973
|
+
): void {
|
|
974
|
+
// C++ requires Real. Cite: :1631–1633.
|
|
975
|
+
const creatureEntry = raw.miscValue | 0;
|
|
976
|
+
// Missing creature template → error log + return. Cite: :1638–1642.
|
|
977
|
+
if (!creatureEntry) return;
|
|
978
|
+
// The interpreter emits the creature entry; the display id comes from the runtime creature DB.
|
|
979
|
+
// Cite: SpellAuras.cpp:1644-1650 ChooseDisplayId; Unit.cpp:7741-7756 Mount.
|
|
980
|
+
state.effects.push({ kind: 'mounted', creatureEntry });
|
|
981
|
+
state.intents.push({ kind: 'mounted', creatureEntry });
|
|
982
|
+
// World/travel utility — keep out of combat kit roles (aura 32 alone stays utility).
|
|
983
|
+
// Cite: roles.ts mounted-speed world mounts; SpellAuras HandleAuraMounted is OOC.
|
|
984
|
+
state.role = state.role || 'utility';
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// ── SPELL_AURA_MOD_DAMAGE_TAKEN (14) ── a physical mask becomes physical_taken, else spell_taken.
|
|
988
|
+
// Cite: SpellAuras.cpp:75; Unit.cpp:7160 MeleeDamageBonusTaken, :7597 SpellBaseDamageBonusTaken.
|
|
989
|
+
export function handleModDamageTaken(
|
|
990
|
+
state: HandlerState,
|
|
991
|
+
raw: RawSpellEffect,
|
|
992
|
+
_slot: number,
|
|
993
|
+
_effectType: number,
|
|
994
|
+
): void {
|
|
995
|
+
const misc = raw.miscValue | 0;
|
|
996
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
997
|
+
const dur = durationMsResolved(state);
|
|
998
|
+
// Physical-only mask (SPELL_SCHOOL_MASK_NORMAL=1) vs magic. Cite: map-spell-effects.mjs:783–791.
|
|
999
|
+
const physicalOnly = misc === SPELL_SCHOOL_MASK_NORMAL;
|
|
1000
|
+
const mod: BuffMod = physicalOnly ? 'physical_taken' : 'spell_taken';
|
|
1001
|
+
const tagged = withHostile(
|
|
1002
|
+
{ kind: 'buff' as const, mod, amount: min, durationMs: dur },
|
|
1003
|
+
raw.targetA | 0,
|
|
1004
|
+
min,
|
|
1005
|
+
);
|
|
1006
|
+
state.effects.push(tagged as SpellEffect);
|
|
1007
|
+
state.role = state.role || 'buff';
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// ── SPELL_AURA_MOD_ROOT (26) ── Real applications only, baked as a root with its duration. Immunity
|
|
1011
|
+
// reads the spell's own mechanic. Cite: SpellAuras.cpp:2727-2775 HandleAuraModRoot.
|
|
1012
|
+
export function handleModRoot(
|
|
1013
|
+
state: HandlerState,
|
|
1014
|
+
raw: RawSpellEffect,
|
|
1015
|
+
_slot: number,
|
|
1016
|
+
_effectType: number,
|
|
1017
|
+
): void {
|
|
1018
|
+
// C++: if (!Real) return. Interpret is apply-time snapshot (Real=true). Cite: :2729–2731.
|
|
1019
|
+
const dur = durationMsResolved(state);
|
|
1020
|
+
state.effects.push({ kind: 'root', durationMs: dur });
|
|
1021
|
+
state.role = state.role || 'control';
|
|
1022
|
+
|
|
1023
|
+
// Frost root → AURA_STATE_FROZEN on apply (and clear on remove if no other frost freeze).
|
|
1024
|
+
// Cite: SpellAuras.cpp:2737–2739 apply; :2748–2765 remove scan.
|
|
1025
|
+
if (schoolOf(state.spell) === 'frost') {
|
|
1026
|
+
state.intents.push({ kind: 'mod_root_special', frostFreeze: true });
|
|
1027
|
+
}
|
|
1028
|
+
// Caster AI JustRootedTarget is runtime-only (no bake surface). Cite: :2741–2743.
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
export function handleModSkill(
|
|
1032
|
+
state: HandlerState,
|
|
1033
|
+
raw: RawSpellEffect,
|
|
1034
|
+
_slot: number,
|
|
1035
|
+
_effectType: number,
|
|
1036
|
+
): void {
|
|
1037
|
+
pushModSkillIntent(state, raw, false);
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
export function handleModSkillTalent(
|
|
1041
|
+
state: HandlerState,
|
|
1042
|
+
raw: RawSpellEffect,
|
|
1043
|
+
_slot: number,
|
|
1044
|
+
_effectType: number,
|
|
1045
|
+
): void {
|
|
1046
|
+
pushModSkillIntent(state, raw, true);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// ── SPELL_AURA_MOD_INCREASE_SPEED (31) ── baked as a signed speed percent on the run rate.
|
|
1050
|
+
// Cite: SpellAuras.cpp:2880-2886 HandleAuraModIncreaseSpeed.
|
|
1051
|
+
export function handleModIncreaseSpeed(
|
|
1052
|
+
state: HandlerState,
|
|
1053
|
+
raw: RawSpellEffect,
|
|
1054
|
+
_slot: number,
|
|
1055
|
+
_effectType: number,
|
|
1056
|
+
): void {
|
|
1057
|
+
// C++ requires Real. Cite: :2882–2884.
|
|
1058
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1059
|
+
const dur = durationMsResolved(state);
|
|
1060
|
+
const tagged = withHostile(
|
|
1061
|
+
{
|
|
1062
|
+
kind: 'speed' as const,
|
|
1063
|
+
aura: SPELL_AURA_MOD_INCREASE_SPEED,
|
|
1064
|
+
pct: min,
|
|
1065
|
+
durationMs: dur,
|
|
1066
|
+
},
|
|
1067
|
+
raw.targetA | 0,
|
|
1068
|
+
min,
|
|
1069
|
+
raw.targetB | 0,
|
|
1070
|
+
);
|
|
1071
|
+
state.effects.push(tagged as SpellEffect);
|
|
1072
|
+
state.role = state.role || 'buff';
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
// ── SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED (32) ── the run rate is only recalculated while mounted,
|
|
1076
|
+
// so this is world travel and not fight kit — aura 31 is the combat speed buff.
|
|
1077
|
+
export function handleModIncreaseMountedSpeed(
|
|
1078
|
+
state: HandlerState,
|
|
1079
|
+
raw: RawSpellEffect,
|
|
1080
|
+
_slot: number,
|
|
1081
|
+
_effectType: number,
|
|
1082
|
+
): void {
|
|
1083
|
+
// C++ requires Real. Cite: SpellAuras.cpp:2891–2893.
|
|
1084
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1085
|
+
const dur = durationMsResolved(state);
|
|
1086
|
+
const tagged = withHostile(
|
|
1087
|
+
{
|
|
1088
|
+
kind: 'speed' as const,
|
|
1089
|
+
aura: SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED,
|
|
1090
|
+
pct: min,
|
|
1091
|
+
durationMs: dur,
|
|
1092
|
+
},
|
|
1093
|
+
raw.targetA | 0,
|
|
1094
|
+
min,
|
|
1095
|
+
);
|
|
1096
|
+
state.effects.push(tagged as SpellEffect);
|
|
1097
|
+
// Utility, not buff — pure world travel (KI-479 / roles.ts aura-32 contract). Aura 31 alone is the combat
|
|
1098
|
+
// buff path; do not stamp 'buff' here or roleOf promotes mount bridles into knownCombatSpells.
|
|
1099
|
+
state.role = state.role || 'utility';
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
// ── SPELL_AURA_TRANSFORM (56) ── baked as a breakable incapacitate.
|
|
1103
|
+
// Cite: SpellAuras.cpp:1979-2052 HandleAuraTransform.
|
|
1104
|
+
export function handleAuraTransform(
|
|
1105
|
+
state: HandlerState,
|
|
1106
|
+
raw: RawSpellEffect,
|
|
1107
|
+
_slot: number,
|
|
1108
|
+
_effectType: number,
|
|
1109
|
+
): void {
|
|
1110
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1111
|
+
const dur = durationMsResolved(state);
|
|
1112
|
+
// Merge with a confuse slot when both remap to the same incapacitate (Polymorph carries both), so
|
|
1113
|
+
// diminishing returns advance once per cast rather than twice.
|
|
1114
|
+
pushOrMergePolymorphIncapacitate(state, {
|
|
1115
|
+
kind: 'cc',
|
|
1116
|
+
control: 'incapacitate',
|
|
1117
|
+
mechanic: 'polymorph',
|
|
1118
|
+
durationMs: dur,
|
|
1119
|
+
school: schoolOf(state.spell),
|
|
1120
|
+
breakOnDamage: true,
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1123
|
+
// C++ display path: misc = creature entry → ChooseDisplayId into m_amount.
|
|
1124
|
+
// misc 0 → script override amount or error. Cite: :1985–2021.
|
|
1125
|
+
const creatureEntry = raw.miscValue | 0;
|
|
1126
|
+
const intent: InterpretIntent = {
|
|
1127
|
+
kind: 'transform',
|
|
1128
|
+
creatureEntry,
|
|
1129
|
+
};
|
|
1130
|
+
// Unknown template → pig pink display 16358. Cite: :2000–2004.
|
|
1131
|
+
// Bake-thin has no creature DB; emit fallback id when entry non-zero so SI5 can resolve.
|
|
1132
|
+
if (creatureEntry) {
|
|
1133
|
+
intent.missingCreatureDisplayId = TRANSFORM_MISSING_CREATURE_DISPLAY;
|
|
1134
|
+
} else if (!min) {
|
|
1135
|
+
// misc 0 and amount 0 → C++ error log only (no SetDisplayId from entry). Cite: :1991–1996.
|
|
1136
|
+
}
|
|
1137
|
+
state.intents.push(intent);
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// ── SPELL_AURA_SCHOOL_ABSORB (69) ── baked as an absorb pool, with a caster-master target applying to
|
|
1141
|
+
// the owner (Voidwalker Sacrifice). Cite: SpellAuras.cpp:130; Spell.cpp:2422-2424 GetMaster.
|
|
1142
|
+
export function handleSchoolAbsorb(
|
|
1143
|
+
state: HandlerState,
|
|
1144
|
+
raw: RawSpellEffect,
|
|
1145
|
+
_slot: number,
|
|
1146
|
+
_effectType: number,
|
|
1147
|
+
): void {
|
|
1148
|
+
const { min, max } = effectAmountRange(raw, state.ctx);
|
|
1149
|
+
const dur = durationMsResolved(state);
|
|
1150
|
+
// Pool from basepoints; clamp ≥ 1. Cite: map-spell-effects.mjs:952–957.
|
|
1151
|
+
// Bonus coefficient path is cast-time (ctx not on bake-thin). Cite: :6053–6059.
|
|
1152
|
+
const clamped = clampPositiveRange(min, max);
|
|
1153
|
+
// Cite: SpellTargetDefines.h TARGET_UNIT_CASTER_MASTER = 27; targeting.ts TARGET_CASTER_MASTER.
|
|
1154
|
+
const applyTo =
|
|
1155
|
+
(raw.targetA | 0) === 27 ? ('owner' as const) : undefined;
|
|
1156
|
+
state.effects.push({
|
|
1157
|
+
kind: 'school_absorb',
|
|
1158
|
+
schoolMask: raw.miscValue | 0,
|
|
1159
|
+
min: clamped.min,
|
|
1160
|
+
max: clamped.max,
|
|
1161
|
+
durationMs: dur,
|
|
1162
|
+
...(applyTo ? { applyTo } : {}),
|
|
1163
|
+
});
|
|
1164
|
+
state.role = state.role || 'buff';
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// ── SPELL_AURA_MECHANIC_IMMUNITY (77) ── baked as a mechanic immunity.
|
|
1168
|
+
// Cite: SpellAuras.cpp:2936-2948 HandleModMechanicImmunity.
|
|
1169
|
+
export function handleModMechanicImmunity(
|
|
1170
|
+
state: HandlerState,
|
|
1171
|
+
raw: RawSpellEffect,
|
|
1172
|
+
_slot: number,
|
|
1173
|
+
_effectType: number,
|
|
1174
|
+
): void {
|
|
1175
|
+
const misc = raw.miscValue | 0;
|
|
1176
|
+
const dur = durationMsResolved(state);
|
|
1177
|
+
// ApplySpellImmune(IMMUNITY_MECHANIC, misc). Cite: :2947.
|
|
1178
|
+
state.effects.push({
|
|
1179
|
+
kind: 'mechanic_immunity',
|
|
1180
|
+
mechanic: misc,
|
|
1181
|
+
durationMs: dur,
|
|
1182
|
+
positive: true,
|
|
1183
|
+
});
|
|
1184
|
+
state.role = state.role || 'buff';
|
|
1185
|
+
|
|
1186
|
+
// On apply + SPELL_ATTR_EX_IMMUNITY_PURGES_EFFECT → RemoveAurasAtMechanicImmunity. mechanic bit mask = 1
|
|
1187
|
+
// << (misc − 1). Cite: :2941–2945. Bake-thin: attr unknown unless ctx.immunityPurgesEffect === true.
|
|
1188
|
+
if (state.ctx.immunityPurgesEffect === true && misc > 0) {
|
|
1189
|
+
state.intents.push({
|
|
1190
|
+
kind: 'mechanic_immunity_purge',
|
|
1191
|
+
mechanic: misc,
|
|
1192
|
+
mechanicMask: 1 << (misc - 1),
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
// ── SPELL_AURA_MOD_POWER_REGEN (85) ── a finite duration bakes as a drink-style restore, else a flat
|
|
1198
|
+
// mana-per-five buff. Cite: SpellAuras.cpp:3621-3641; PeriodicTick :4959-4985.
|
|
1199
|
+
export function handleModPowerRegen(
|
|
1200
|
+
state: HandlerState,
|
|
1201
|
+
raw: RawSpellEffect,
|
|
1202
|
+
_slot: number,
|
|
1203
|
+
_effectType: number,
|
|
1204
|
+
): void {
|
|
1205
|
+
// C++ requires Real. Cite: :3623–3625.
|
|
1206
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1207
|
+
const dur = durationMsResolved(state);
|
|
1208
|
+
// The C++ arms the period when it is 0 — 3000 for rage, else 2000 — while the bake's drink path
|
|
1209
|
+
// uses the amplitude or 5000 for its ticks. Rage Anger Management is three fifths in combat.
|
|
1210
|
+
|
|
1211
|
+
// Finite duration = drink sit-and-sip (category 59). Cite: map-spell-effects.mjs:1025–1033.
|
|
1212
|
+
if (dur > 0) {
|
|
1213
|
+
// The tick only lands when the bearer's own power type IS this one. Cite: SpellAuras.cpp:4965-4967.
|
|
1214
|
+
state.effects.push({
|
|
1215
|
+
kind: 'restore_power',
|
|
1216
|
+
amountPerTick: Math.max(1, min),
|
|
1217
|
+
powerType: raw.miscValue | 0,
|
|
1218
|
+
tickMs: (raw.amplitude | 0) || 5000,
|
|
1219
|
+
durationMs: dur,
|
|
1220
|
+
});
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
// Permanent / gear path → flat mp5. Cite: map-spell-effects.mjs:1035–1038.
|
|
1225
|
+
// withHostile stamps hostile:false for friendly targets (oracle field parity).
|
|
1226
|
+
const amount = Math.max(1, min);
|
|
1227
|
+
const tagged = withHostile(
|
|
1228
|
+
{ kind: 'buff' as const, mod: 'mp5' as const, amount, durationMs: dur },
|
|
1229
|
+
raw.targetA | 0,
|
|
1230
|
+
amount,
|
|
1231
|
+
);
|
|
1232
|
+
state.effects.push(tagged as SpellEffect);
|
|
1233
|
+
state.role = state.role || 'buff';
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// ── SPELL_AURA_MOD_RANGED_ATTACK_POWER (124) ── baked as an attack-power buff, as melee AP is.
|
|
1237
|
+
// Cite: SpellAuras.cpp:3994-4000 HandleAuraModRangedAttackPower.
|
|
1238
|
+
export function handleModRangedAttackPower(
|
|
1239
|
+
state: HandlerState,
|
|
1240
|
+
raw: RawSpellEffect,
|
|
1241
|
+
_slot: number,
|
|
1242
|
+
_effectType: number,
|
|
1243
|
+
): void {
|
|
1244
|
+
// Wand users (priest/mage/warlock) skip RAP. Cite: :3996–3997 CLASSMASK_WAND_USERS.
|
|
1245
|
+
// Bake-thin: no class → emit. Cast-time: unitTargetClass set and wand → return.
|
|
1246
|
+
const cls = state.ctx.unitTargetClass;
|
|
1247
|
+
if (cls != null) {
|
|
1248
|
+
const classMask = 1 << (cls - 1);
|
|
1249
|
+
if ((classMask & CLASSMASK_WAND_USERS) !== 0) return;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
const { min, pointsPerComboPoint } = effectAmountRange(raw, state.ctx);
|
|
1253
|
+
const dur = durationMsResolved(state);
|
|
1254
|
+
// UNIT_MOD_ATTACK_POWER_RANGED TOTAL_VALUE. Cite: :3999.
|
|
1255
|
+
const base = withPpc(
|
|
1256
|
+
{ kind: 'buff' as const, mod: 'attack_power' as const, amount: min, durationMs: dur },
|
|
1257
|
+
pointsPerComboPoint,
|
|
1258
|
+
);
|
|
1259
|
+
state.effects.push(withHostile(base, raw.targetA | 0, min) as SpellEffect);
|
|
1260
|
+
state.role = state.role || 'buff';
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
// ── SPELL_AURA_DAMAGE_SHIELD (15) ── baked as a damage shield, paid out in DealMeleeDamage.
|
|
1264
|
+
// Cite: SpellAuras.cpp:76; Unit.cpp:2242-2293.
|
|
1265
|
+
export function handleDamageShield(
|
|
1266
|
+
state: HandlerState,
|
|
1267
|
+
raw: RawSpellEffect,
|
|
1268
|
+
_slot: number,
|
|
1269
|
+
_effectType: number,
|
|
1270
|
+
): void {
|
|
1271
|
+
const { min, max } = effectAmountRange(raw, state.ctx);
|
|
1272
|
+
const dur = durationMsResolved(state);
|
|
1273
|
+
const clamped = clampPositiveRange(min, max || min);
|
|
1274
|
+
// Retaliation amount is modifier m_amount; school from spell. Cite: Unit.cpp:2267–2288.
|
|
1275
|
+
const effect: SpellEffect = {
|
|
1276
|
+
kind: 'damage_shield',
|
|
1277
|
+
school: schoolOf(state.spell),
|
|
1278
|
+
min: clamped.min,
|
|
1279
|
+
max: clamped.max,
|
|
1280
|
+
durationMs: dur,
|
|
1281
|
+
};
|
|
1282
|
+
// Optional proc charges / CD from spell row (bake opts.procCharges / peCd).
|
|
1283
|
+
// Cite: map-spell-effects.mjs:504–505, :619–622.
|
|
1284
|
+
const charges = (state.spell.procCharges ?? 0) | 0;
|
|
1285
|
+
if (charges > 0) effect.charges = charges;
|
|
1286
|
+
state.effects.push(effect);
|
|
1287
|
+
state.role = state.role || 'buff';
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
// ── SPELL_AURA_MOD_SCALE (61) ── a cosmetic scale percent, emitted as an effect so the census credits
|
|
1291
|
+
// the slot and combat stores the display scale. Cite: SpellAuras.cpp:2182-2185.
|
|
1292
|
+
export function handleModScale(
|
|
1293
|
+
state: HandlerState,
|
|
1294
|
+
raw: RawSpellEffect,
|
|
1295
|
+
_slot: number,
|
|
1296
|
+
_effectType: number,
|
|
1297
|
+
): void {
|
|
1298
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1299
|
+
const dur = durationMsResolved(state);
|
|
1300
|
+
// ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X, float(amount), apply). Cite: :2184.
|
|
1301
|
+
state.effects.push({ kind: 'mod_scale', pct: min, durationMs: dur });
|
|
1302
|
+
state.role = state.role || 'buff';
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
// ── SPELL_AURA_MOD_FEAR (7) ── Real applications only, baked as a fear with a one-second pulse.
|
|
1306
|
+
// Cite: SpellAuras.cpp:2368-2379 HandleModFear.
|
|
1307
|
+
export function handleModFear(
|
|
1308
|
+
state: HandlerState,
|
|
1309
|
+
raw: RawSpellEffect,
|
|
1310
|
+
_slot: number,
|
|
1311
|
+
_effectType: number,
|
|
1312
|
+
): void {
|
|
1313
|
+
// C++: if (!Real) return. Interpret is apply-time snapshot (Real=true). Cite: :2370–2371.
|
|
1314
|
+
// Remove path: keep fleeing while any MOD_FEAR remains. Cite: :2373–2375.
|
|
1315
|
+
const dur = durationMsResolved(state);
|
|
1316
|
+
state.effects.push({
|
|
1317
|
+
kind: 'cc',
|
|
1318
|
+
control: 'fear',
|
|
1319
|
+
mechanic: 'fear',
|
|
1320
|
+
durationMs: dur,
|
|
1321
|
+
school: schoolOf(state.spell),
|
|
1322
|
+
pulseMs: 1000,
|
|
1323
|
+
});
|
|
1324
|
+
state.role = state.role || 'control';
|
|
1325
|
+
// getHostileRefManager().HandleSuppressed is runtime threat list only. Cite: :2379.
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
// ── SPELL_AURA_SCHOOL_IMMUNITY (39) ── baked as a school immunity.
|
|
1329
|
+
// Cite: SpellAuras.cpp:2992-3043 HandleAuraModSchoolImmunity.
|
|
1330
|
+
export function handleSchoolImmunity(
|
|
1331
|
+
state: HandlerState,
|
|
1332
|
+
raw: RawSpellEffect,
|
|
1333
|
+
_slot: number,
|
|
1334
|
+
_effectType: number,
|
|
1335
|
+
): void {
|
|
1336
|
+
const schoolMask = raw.miscValue | 0;
|
|
1337
|
+
const dur = durationMsResolved(state);
|
|
1338
|
+
// ApplySpellImmune(IMMUNITY_SCHOOL, misc). Cite: :2995.
|
|
1339
|
+
state.effects.push({
|
|
1340
|
+
kind: 'school_immunity',
|
|
1341
|
+
schoolMask,
|
|
1342
|
+
durationMs: dur,
|
|
1343
|
+
positive: true,
|
|
1344
|
+
});
|
|
1345
|
+
state.role = state.role || 'buff';
|
|
1346
|
+
|
|
1347
|
+
// Apply-time specials (purge / banish isolate). Cite: :2996–3030.
|
|
1348
|
+
const intent: InterpretIntent = { kind: 'school_immunity_special', schoolMask };
|
|
1349
|
+
// Positive + SPELL_ATTR_EX_IMMUNITY_PURGES_EFFECT → remove negative school auras.
|
|
1350
|
+
// Bake-thin always tags positive; purge only when attr gated. Cite: :3002–3023.
|
|
1351
|
+
if (state.ctx.immunityPurgesEffect === true) {
|
|
1352
|
+
intent.purgeNegativeSchoolAuras = true;
|
|
1353
|
+
}
|
|
1354
|
+
// MECHANIC_BANISH → UNIT_STAT_ISOLATED. Cite: :3025–3030.
|
|
1355
|
+
const spellMech = state.spell.mechanic;
|
|
1356
|
+
const rawMech = raw.mechanic | 0;
|
|
1357
|
+
if (spellMech === 'banish' || rawMech === MECHANIC_BANISH) {
|
|
1358
|
+
intent.isolated = true;
|
|
1359
|
+
}
|
|
1360
|
+
if (intent.purgeNegativeSchoolAuras || intent.isolated) {
|
|
1361
|
+
state.intents.push(intent);
|
|
1362
|
+
}
|
|
1363
|
+
// UNIT_FLAG_IMMUNE + hostile-ref suppress are runtime flags. Cite: :3033–3042.
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
// ── SPELL_AURA_MOD_REGEN (84) ── baked as a food-style health restore.
|
|
1367
|
+
// Cite: SpellAuras.cpp:3612-3617 HandleModRegen; PeriodicTick :4948-4957.
|
|
1368
|
+
export function handleModRegen(
|
|
1369
|
+
state: HandlerState,
|
|
1370
|
+
raw: RawSpellEffect,
|
|
1371
|
+
_slot: number,
|
|
1372
|
+
_effectType: number,
|
|
1373
|
+
): void {
|
|
1374
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1375
|
+
const dur = durationMsResolved(state);
|
|
1376
|
+
// C++: periodictime default 5000; m_periodicTimer = 5000; m_isPeriodic. Cite: :3614–3617.
|
|
1377
|
+
// Tick: ModifyHealth(amount). Cite: :4954.
|
|
1378
|
+
state.effects.push({
|
|
1379
|
+
kind: 'restore_health',
|
|
1380
|
+
amountPerTick: Math.max(1, min),
|
|
1381
|
+
tickMs: (raw.amplitude | 0) || 5000,
|
|
1382
|
+
durationMs: dur,
|
|
1383
|
+
});
|
|
1384
|
+
// map-spell-effects sets outOfCombatOnly on the spell roll for food — SI5.
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
// ── SPELL_AURA_MOD_DAMAGE_PERCENT_DONE (79) ── baked as a damage-done percent, with the school when
|
|
1388
|
+
// the mask is a single bit. Cite: SpellAuras.cpp:4109-4173 HandleModDamagePercentDone.
|
|
1389
|
+
export function handleModDamagePercentDone(
|
|
1390
|
+
state: HandlerState,
|
|
1391
|
+
raw: RawSpellEffect,
|
|
1392
|
+
_slot: number,
|
|
1393
|
+
_effectType: number,
|
|
1394
|
+
): void {
|
|
1395
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1396
|
+
const dur = durationMsResolved(state);
|
|
1397
|
+
const misc = raw.miscValue | 0;
|
|
1398
|
+
// Physical TOTAL_PCT weapon mods + magic SpellDamageBonusDone are runtime.
|
|
1399
|
+
// Cite: :4131–4168. Bake surface is the percent buff.
|
|
1400
|
+
const buff: {
|
|
1401
|
+
kind: 'buff';
|
|
1402
|
+
mod: BuffMod;
|
|
1403
|
+
amount: number;
|
|
1404
|
+
durationMs: number;
|
|
1405
|
+
school?: School;
|
|
1406
|
+
} = {
|
|
1407
|
+
kind: 'buff',
|
|
1408
|
+
mod: 'damage_done_pct',
|
|
1409
|
+
amount: min,
|
|
1410
|
+
durationMs: dur,
|
|
1411
|
+
};
|
|
1412
|
+
const sch = schoolFromSingleBitMask(misc);
|
|
1413
|
+
if (sch) buff.school = sch;
|
|
1414
|
+
state.effects.push(withHostile(buff, raw.targetA | 0, min) as SpellEffect);
|
|
1415
|
+
state.role = state.role || 'buff';
|
|
1416
|
+
|
|
1417
|
+
// Expire special. Cite: :4170–4172.
|
|
1418
|
+
const expireCast = MOD_DMG_PCT_EXPIRE_CAST[state.spell.id | 0];
|
|
1419
|
+
if (expireCast != null) {
|
|
1420
|
+
state.intents.push({ kind: 'mod_damage_percent_done_expire', castSpellId: expireCast });
|
|
1421
|
+
}
|
|
1422
|
+
// The weapon-dependent path runs at equip time and has no interpret surface, and the magic percent
|
|
1423
|
+
// fields are gated on the magic school mask. Cite: SpellAuras.cpp:4115-4168.
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
// ── SPELL_AURA_PERIODIC_ENERGIZE (24) ── baked as a periodic power restore.
|
|
1427
|
+
// Cite: SpellAuras.cpp:3119-3121 HandlePeriodicEnergize; PeriodicTick :4809-4852.
|
|
1428
|
+
export function handlePeriodicEnergize(
|
|
1429
|
+
state: HandlerState,
|
|
1430
|
+
raw: RawSpellEffect,
|
|
1431
|
+
_slot: number,
|
|
1432
|
+
_effectType: number,
|
|
1433
|
+
): void {
|
|
1434
|
+
// Handler body only arms m_isPeriodic. Cite: :3121.
|
|
1435
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1436
|
+
const dur = durationMsResolved(state);
|
|
1437
|
+
// Rage is stored ten times larger in spell data than the display units combat uses, so it is
|
|
1438
|
+
// converted here: Bloodrage ticks +1 display rage, not +10. Cite: Unit.h POWER_RAGE_DEFAULT.
|
|
1439
|
+
const power = raw.miscValue | 0;
|
|
1440
|
+
let amountPerTick = Math.max(1, min);
|
|
1441
|
+
if (power === POWER_RAGE) {
|
|
1442
|
+
amountPerTick = Math.max(1, Math.round(min / 10));
|
|
1443
|
+
}
|
|
1444
|
+
state.effects.push({
|
|
1445
|
+
kind: 'restore_power',
|
|
1446
|
+
amountPerTick,
|
|
1447
|
+
powerType: power,
|
|
1448
|
+
tickMs: (raw.amplitude | 0) || 1000,
|
|
1449
|
+
durationMs: dur,
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
export function handleAddFlatModifier(
|
|
1454
|
+
state: HandlerState,
|
|
1455
|
+
raw: RawSpellEffect,
|
|
1456
|
+
_slot: number,
|
|
1457
|
+
_effectType: number,
|
|
1458
|
+
): void {
|
|
1459
|
+
pushAddModifierIntent(state, raw, 'add_flat_modifier');
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
export function handleAddPctModifier(
|
|
1463
|
+
state: HandlerState,
|
|
1464
|
+
raw: RawSpellEffect,
|
|
1465
|
+
_slot: number,
|
|
1466
|
+
_effectType: number,
|
|
1467
|
+
): void {
|
|
1468
|
+
pushAddModifierIntent(state, raw, 'add_pct_modifier');
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
// ── SPELL_AURA_MOD_HIT_CHANCE (54) ── baked as a hit buff; a player sums it into the per-hand weapon
|
|
1472
|
+
// hit chances and an NPC into its own. Cite: SpellAuras.cpp:3850-3866; StatSystem.cpp:523-533.
|
|
1473
|
+
export function handleModHitChance(
|
|
1474
|
+
state: HandlerState,
|
|
1475
|
+
raw: RawSpellEffect,
|
|
1476
|
+
_slot: number,
|
|
1477
|
+
_effectType: number,
|
|
1478
|
+
): void {
|
|
1479
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1480
|
+
const dur = durationMsResolved(state);
|
|
1481
|
+
// Whole percentage points → BuffMod hit. Cite: schema BuffMod hit; characterRatings hitChance.
|
|
1482
|
+
const tagged = withHostile(
|
|
1483
|
+
{ kind: 'buff' as const, mod: 'hit' as const, amount: min, durationMs: dur },
|
|
1484
|
+
raw.targetA | 0,
|
|
1485
|
+
min,
|
|
1486
|
+
);
|
|
1487
|
+
state.effects.push(tagged as SpellEffect);
|
|
1488
|
+
state.role = state.role || 'buff';
|
|
1489
|
+
const intent: InterpretIntent = {
|
|
1490
|
+
kind: 'mod_hit_chance',
|
|
1491
|
+
amount: min,
|
|
1492
|
+
durationMs: dur,
|
|
1493
|
+
};
|
|
1494
|
+
// Non-player flat path. Cite: :3860–3865.
|
|
1495
|
+
if (state.ctx.unitTargetIsPlayer === false) {
|
|
1496
|
+
intent.nonPlayerFlat = true;
|
|
1497
|
+
}
|
|
1498
|
+
// Player recompute + EquippedItemClass gate is SI5/runtime (weapon equip state).
|
|
1499
|
+
// Cite: StatSystem.cpp:527–531.
|
|
1500
|
+
state.intents.push(intent);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
// ── SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE (143) ── a per-school exclusive maximum against other auras of
|
|
1504
|
+
// the same type, on the same bake surface as aura 22. Cite: SpellAuras.cpp:3314-3360.
|
|
1505
|
+
export function handleModResistanceExclusive(
|
|
1506
|
+
state: HandlerState,
|
|
1507
|
+
raw: RawSpellEffect,
|
|
1508
|
+
_slot: number,
|
|
1509
|
+
_effectType: number,
|
|
1510
|
+
): void {
|
|
1511
|
+
const { min, pointsPerComboPoint } = effectAmountRange(raw, state.ctx);
|
|
1512
|
+
// C++: if (!m_modifier.m_amount) return. Cite: :3316–3317.
|
|
1513
|
+
if (!min) return;
|
|
1514
|
+
|
|
1515
|
+
const mask = raw.miscValue | 0;
|
|
1516
|
+
const dur = durationMsResolved(state);
|
|
1517
|
+
const tgtA = raw.targetA | 0;
|
|
1518
|
+
|
|
1519
|
+
// Exclusivity is a runtime rule across co-active auras, so interpret emits this aura's amount and
|
|
1520
|
+
// the apply path enforces it. A zero mask falls back to armor, as the resistance bake does.
|
|
1521
|
+
if (!mask || (mask & SPELL_SCHOOL_MASK_NORMAL) !== 0) {
|
|
1522
|
+
const base = withPpc(
|
|
1523
|
+
{ kind: 'buff' as const, mod: 'armor' as const, amount: min, durationMs: dur },
|
|
1524
|
+
pointsPerComboPoint,
|
|
1525
|
+
);
|
|
1526
|
+
state.effects.push(withHostile(base, tgtA, min) as SpellEffect);
|
|
1527
|
+
}
|
|
1528
|
+
for (let bit = 1; bit <= 6; bit++) {
|
|
1529
|
+
if ((mask & (1 << bit)) !== 0) {
|
|
1530
|
+
state.effects.push({ kind: 'resist', school: SCHOOLS[bit]!, amount: min });
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
// ── SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK (65) ── baked as cast_haste, NOT haste: one shared scalar
|
|
1536
|
+
// made Burning Adrenaline's 100000 a 1001x weapon speed. Cite: SpellAuras.cpp:3915-3920.
|
|
1537
|
+
export function handleModCastingSpeedNotStack(
|
|
1538
|
+
state: HandlerState,
|
|
1539
|
+
raw: RawSpellEffect,
|
|
1540
|
+
_slot: number,
|
|
1541
|
+
_effectType: number,
|
|
1542
|
+
): void {
|
|
1543
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1544
|
+
const dur = durationMsResolved(state);
|
|
1545
|
+
// Signed percent (Curse of Tongues negative). Cite: :3917–3919.
|
|
1546
|
+
const tagged = withHostile(
|
|
1547
|
+
{ kind: 'buff' as const, mod: 'cast_haste' as const, amount: min, durationMs: dur },
|
|
1548
|
+
raw.targetA | 0,
|
|
1549
|
+
min,
|
|
1550
|
+
);
|
|
1551
|
+
state.effects.push(tagged as SpellEffect);
|
|
1552
|
+
state.role = state.role || 'buff';
|
|
1553
|
+
// NOT_STACK exclusivity is aura-stacking policy (SI5), not interpret amount.
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
// ── SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS (102) ── the misc value is a creature TYPE MASK, not an
|
|
1557
|
+
// index, matched against the target's type. Cite: Unit.cpp:7475-7476; Unit.h:1432-1436.
|
|
1558
|
+
export function handleModMeleeAttackPowerVersus(
|
|
1559
|
+
state: HandlerState,
|
|
1560
|
+
raw: RawSpellEffect,
|
|
1561
|
+
_slot: number,
|
|
1562
|
+
_effectType: number,
|
|
1563
|
+
): void {
|
|
1564
|
+
const { min } = effectAmountRange(raw, state.ctx);
|
|
1565
|
+
const dur = durationMsResolved(state);
|
|
1566
|
+
// misc = creature type mask (e.g. undead = 1<<(6-1) = 32). Cite: Unit.cpp:7476.
|
|
1567
|
+
const creatureTypeMask = raw.miscValue | 0;
|
|
1568
|
+
state.intents.push({
|
|
1569
|
+
kind: 'mod_melee_attack_power_versus',
|
|
1570
|
+
creatureTypeMask,
|
|
1571
|
+
amount: min,
|
|
1572
|
+
durationMs: dur,
|
|
1573
|
+
});
|
|
1574
|
+
// Play surface: consumable BuffMod + mask. Applied at damage time, not sheet AP.
|
|
1575
|
+
state.effects.push({
|
|
1576
|
+
kind: 'buff',
|
|
1577
|
+
mod: 'attack_power_versus',
|
|
1578
|
+
amount: min,
|
|
1579
|
+
durationMs: dur,
|
|
1580
|
+
creatureTypeMask,
|
|
1581
|
+
} as SpellEffect);
|
|
1582
|
+
state.role = state.role || 'buff';
|
|
1583
|
+
}
|