azeroth-shell 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +26 -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 +126 -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,506 @@
|
|
|
1
|
+
// Peeled from createSession (Wave 4 createSession.md P4) — pattern (D).
|
|
2
|
+
// ensurePlayerFocus / foeOf / hostileTargetOf / selectTarget* / nearestPartyInAcquire.
|
|
3
|
+
|
|
4
|
+
import type { CombatContext } from './context.ts';
|
|
5
|
+
import type { Fighter } from './types.ts';
|
|
6
|
+
import type { EnemySide, Side, TotemSide } from '../core/events.ts';
|
|
7
|
+
import { isAllySide, isEnemySide, isTotemSide } from '../core/events.ts';
|
|
8
|
+
import type { CombatantId } from './threat.ts';
|
|
9
|
+
import type { SpellDef } from '../../data/schema.ts';
|
|
10
|
+
import {
|
|
11
|
+
TARGET_T,
|
|
12
|
+
selectHighestHpAmongTopThreat,
|
|
13
|
+
type SelectTargetFriendly,
|
|
14
|
+
type SelectTargetHostile,
|
|
15
|
+
} from '../../domain/creature/aiTargeting.ts';
|
|
16
|
+
import { killOrderEntryMatches, killOrderTakesCharmed } from '../../domain/rotation/killOrder.ts';
|
|
17
|
+
import { buildSelectTargetCtx, resolveSelectTargetFighter } from './aiTargetResolve.ts';
|
|
18
|
+
import { isPlayerCharacterTarget } from './castTargetGates.ts';
|
|
19
|
+
import { MIN_AGGRO_DISTANCE } from '../../domain/creature/creatureAi.ts';
|
|
20
|
+
import { CHARGE_INTERCEPT_MAX_YD, combatDistanceYd, MELEE_REACH_YD, sameStoreyYd } from './combatGeometry.ts';
|
|
21
|
+
import { AURA_DECREASE_SPEED } from '../../domain/nav/speed.ts';
|
|
22
|
+
|
|
23
|
+
export type SessionFocusDeps = {
|
|
24
|
+
dead: (f: Fighter) => boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export function installSessionFocus(ctx: CombatContext, deps: SessionFocusDeps): void {
|
|
28
|
+
const dead = deps.dead;
|
|
29
|
+
const {
|
|
30
|
+
player, enemies, pet, allies, totems, cfg, rng,
|
|
31
|
+
} = ctx;
|
|
32
|
+
|
|
33
|
+
// Resolve the player's focus to a living legal hostile, keeping a sticky one while it is valid and
|
|
34
|
+
// otherwise preferring native enemies over charmed bodies. On the endless floor, never stick a passive.
|
|
35
|
+
const ensurePlayerFocus = (): Fighter => {
|
|
36
|
+
// Free-player viewer for sticky/hostile checks (charmed player is enemy-faction).
|
|
37
|
+
const freeViewer =
|
|
38
|
+
!ctx.isCharmed(player) ? player
|
|
39
|
+
: ctx.livingAllies().find((a) => !ctx.isCharmed(a))
|
|
40
|
+
?? (pet && !dead(pet) && !ctx.isCharmed(pet) ? pet : null)
|
|
41
|
+
?? player;
|
|
42
|
+
let playerFocus = ctx.playerFocusFighter;
|
|
43
|
+
// A focus that CANNOT be killed loses its stickiness the moment something killable is in the pull.
|
|
44
|
+
// On Majordomo the sticky branch returned the boss all fight and the reselect never ran.
|
|
45
|
+
const stickyIsWasted = ctx.isUnkillableEnemy?.(playerFocus) === true
|
|
46
|
+
&& ctx.livingHostilesFor(freeViewer).some(
|
|
47
|
+
(h) => h !== playerFocus && !ctx.isUnkillableEnemy!(h),
|
|
48
|
+
);
|
|
49
|
+
// Same gap for healers: init locks onto enemies[0], so preferFocusHostile never ran. Cite:
|
|
50
|
+
// PlayerbotClassAI.cpp:659 GetBotJob; sessionPools preferFocusHostile.
|
|
51
|
+
// `groupRole` is an ARENA seat's role; a raid add carrying it re-aimed the party (see
|
|
52
|
+
// sessionPools preferFocusHostile). The creature's own armed kit still counts everywhere.
|
|
53
|
+
const isHealerSeat = (h: Fighter): boolean =>
|
|
54
|
+
(cfg.enemiesAreATeam === true && h.spec.groupRole === 'healer')
|
|
55
|
+
|| ctx.enemyCastBySide.get(h.side as EnemySide)?.healer === true;
|
|
56
|
+
// A CLICK WINS. GetBotJob picks a BOT's target; it never re-aims the one the player asked for.
|
|
57
|
+
// Cite: PlayerbotClassAI.cpp:659; the endless branch below already reads explicitEnemyFocus.
|
|
58
|
+
const stickyIsClicked = ctx.explicitEnemyFocus != null && playerFocus.side === ctx.explicitEnemyFocus;
|
|
59
|
+
const stickyMissesHealer = !stickyIsClicked
|
|
60
|
+
&& !isHealerSeat(playerFocus)
|
|
61
|
+
&& ctx.livingHostilesFor(freeViewer).some((h) => h !== playerFocus && isHealerSeat(h));
|
|
62
|
+
// Arena: do not stick a healer past Charge/Intercept 25 yd when a closer body exists.
|
|
63
|
+
// Cite: PlayerbotWarriorAI.cpp:175-176; sessionPools preferFocusHostile.
|
|
64
|
+
const stickyDist = ctx.distanceBetween(freeViewer, playerFocus);
|
|
65
|
+
const stickyHealerOutOfReach = cfg.enemiesAreATeam === true
|
|
66
|
+
&& isHealerSeat(playerFocus)
|
|
67
|
+
&& stickyDist != null
|
|
68
|
+
&& stickyDist > CHARGE_INTERCEPT_MAX_YD
|
|
69
|
+
&& ctx.livingHostilesFor(freeViewer).some((h) => {
|
|
70
|
+
if (h === playerFocus) return false;
|
|
71
|
+
const d = ctx.distanceBetween(freeViewer, h);
|
|
72
|
+
return d != null && d <= CHARGE_INTERCEPT_MAX_YD;
|
|
73
|
+
});
|
|
74
|
+
// Sticky: current focus still a living legal hostile for free friendlies.
|
|
75
|
+
if (
|
|
76
|
+
!stickyIsWasted
|
|
77
|
+
&& !stickyMissesHealer
|
|
78
|
+
&& !stickyHealerOutOfReach
|
|
79
|
+
&& !dead(playerFocus)
|
|
80
|
+
&& !ctx.isUnattackable(playerFocus)
|
|
81
|
+
&& ctx.factionOfFighter(playerFocus) !== ctx.factionOfFighter(freeViewer)
|
|
82
|
+
) {
|
|
83
|
+
// Endless floor: don't keep sticky on a random passive unless player clicked it.
|
|
84
|
+
if (
|
|
85
|
+
!cfg.endless
|
|
86
|
+
|| !isEnemySide(playerFocus.side)
|
|
87
|
+
|| ctx.enemyHasThreat!(playerFocus)
|
|
88
|
+
|| (ctx.explicitEnemyFocus != null && playerFocus.side === ctx.explicitEnemyFocus)
|
|
89
|
+
) {
|
|
90
|
+
return playerFocus;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Free reselect: endless = only threat-bearing; normal pulls = any living hostile.
|
|
94
|
+
const pool = ctx.livingHostilesFor(freeViewer).filter(
|
|
95
|
+
(h) => !cfg.endless || !isEnemySide(h.side) || ctx.enemyHasThreat!(h),
|
|
96
|
+
);
|
|
97
|
+
let next = ctx.preferFocusHostile!(pool, freeViewer);
|
|
98
|
+
// Possessed body can miss the acquire pool (storey / cache) while the boss is
|
|
99
|
+
// unattackable — still the only legal burn target (Anastari 17250 vanish).
|
|
100
|
+
if (!next) {
|
|
101
|
+
const charmed = ctx.partyUnits().find(
|
|
102
|
+
(u) => !dead(u) && ctx.isCharmed(u) && !ctx.isUnattackable(u),
|
|
103
|
+
);
|
|
104
|
+
if (charmed) next = charmed;
|
|
105
|
+
}
|
|
106
|
+
if (next) {
|
|
107
|
+
playerFocus = next;
|
|
108
|
+
ctx.playerFocusFighter = next;
|
|
109
|
+
if (ctx.explicitEnemyFocus != null && next.side !== ctx.explicitEnemyFocus) {
|
|
110
|
+
ctx.explicitEnemyFocus = null;
|
|
111
|
+
}
|
|
112
|
+
} else if (cfg.endless) {
|
|
113
|
+
// No free-fire hostiles: stand down. Leaving playerFocus on a corpse side re-armed
|
|
114
|
+
// keep-set / free-fire when that slot was recycled as a passive (controller-farpull A).
|
|
115
|
+
ctx.explicitEnemyFocus = null;
|
|
116
|
+
playerFocus = player;
|
|
117
|
+
ctx.playerFocusFighter = player;
|
|
118
|
+
}
|
|
119
|
+
return playerFocus;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
let foeTick = -1;
|
|
123
|
+
const foeCache = new Map<string, Fighter>();
|
|
124
|
+
const foeOf = (f: Fighter): Fighter => {
|
|
125
|
+
if (ctx.t !== foeTick) {
|
|
126
|
+
foeCache.clear();
|
|
127
|
+
foeTick = ctx.t;
|
|
128
|
+
}
|
|
129
|
+
const cached = foeCache.get(f.side);
|
|
130
|
+
if (cached && (cached === f || (!dead(cached) && !ctx.isUnattackable(cached)))) return cached;
|
|
131
|
+
const resolved = foeOfResolve(f);
|
|
132
|
+
foeCache.set(f.side, resolved);
|
|
133
|
+
return resolved;
|
|
134
|
+
};
|
|
135
|
+
const foeOfResolve = (f: Fighter): Fighter => {
|
|
136
|
+
// Charmed / side-switched: attack former friends (dumb hostile), first legal hostile.
|
|
137
|
+
// Cite: TakeCharmOf PetAI vs friends; not smart tank AI.
|
|
138
|
+
if (ctx.isCharmed(f) || ctx.factionOfFighter(f) !== ctx.nativeFactionOf!(f.side)) {
|
|
139
|
+
const hostiles = ctx.livingHostilesFor(f);
|
|
140
|
+
return hostiles[0] ?? f;
|
|
141
|
+
}
|
|
142
|
+
if (isEnemySide(f.side)) return hostileTargetOf(f);
|
|
143
|
+
// The pet bar's react and command state decides what the pet may swing at, before any party rule.
|
|
144
|
+
// Passive never picks a victim, aggressive takes anything it sees, and defensive assists the owner.
|
|
145
|
+
if (f.side === 'pet') {
|
|
146
|
+
// Recalled: no victim at all until it is home, not even the one attacking it.
|
|
147
|
+
// Cite: PetAI.cpp:188-197 (UpdateAI returns before any attack logic), :480 AttackedBy.
|
|
148
|
+
if (ctx.petRetreating) return f;
|
|
149
|
+
const manual = ctx.petManualTarget;
|
|
150
|
+
if (manual != null) {
|
|
151
|
+
const mf = ctx.sideFighter?.(manual) ?? null;
|
|
152
|
+
if (mf && !dead(mf) && !ctx.isUnattackable(mf)) return mf;
|
|
153
|
+
ctx.petManualTarget = null;
|
|
154
|
+
}
|
|
155
|
+
if (ctx.petReact === 'passive') return f;
|
|
156
|
+
// COMMAND_STAY suppresses the owner assist (PetAI.cpp:380 `!staying &&`), so a staying
|
|
157
|
+
// defensive pet swings only at what is already swinging at IT.
|
|
158
|
+
if (ctx.petCommand === 'stay' && ctx.petReact !== 'aggressive') {
|
|
159
|
+
for (const h of ctx.freeFireHostilesFor!(f)) {
|
|
160
|
+
if (!dead(h) && hostileTargetOf(h) === f) return h;
|
|
161
|
+
}
|
|
162
|
+
return f;
|
|
163
|
+
}
|
|
164
|
+
if (ctx.petReact === 'aggressive') {
|
|
165
|
+
const seen = ctx.livingHostilesFor(f);
|
|
166
|
+
const free = ctx.freeFireHostilesFor!(f);
|
|
167
|
+
// In-combat hostiles first (the pull we are in), then anything else in range.
|
|
168
|
+
if (free.length > 0) return ctx.preferFocusHostile!(free, f) ?? free[0]!;
|
|
169
|
+
if (seen.length > 0) return ctx.preferFocusHostile!(seen, f) ?? seen[0]!;
|
|
170
|
+
return f;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Free player-faction: only free-fire hostiles (combat + explicit target).
|
|
174
|
+
// Cite: endless floor passive stream — livingHostilesFor alone pulls every near spawn.
|
|
175
|
+
const facHostiles = ctx.freeFireHostilesFor!(f);
|
|
176
|
+
if (facHostiles.length > 0) {
|
|
177
|
+
// A companion tank picks up loose mobs: a hostile whose victim is a non-tank friendly outranks
|
|
178
|
+
// the player's focus. Hard-CC'd mobs are skipped. A manual takeover target outranks both.
|
|
179
|
+
if (isAllySide(f.side)) {
|
|
180
|
+
const manualSide = ctx.allyManualTarget.get(f.side);
|
|
181
|
+
if (manualSide != null) {
|
|
182
|
+
const mf = facHostiles.find((h) => h.side === manualSide);
|
|
183
|
+
if (mf) return mf;
|
|
184
|
+
ctx.allyManualTarget.delete(f.side);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Present only on a unit that FOLLOWS the order — one place decides, and the main tank is excluded
|
|
188
|
+
// by never being handed a list. Re-testing the role here refused every off-tank told to peel.
|
|
189
|
+
const order = f.killOrderEntries;
|
|
190
|
+
if (order?.length) {
|
|
191
|
+
// Same walk pickAction runs, including the charmed-ally term - two answers to one order
|
|
192
|
+
// is what section 0c rule 4 forbids.
|
|
193
|
+
const mine = isEnemySide(f.side);
|
|
194
|
+
for (const entry of order) {
|
|
195
|
+
const hit = facHostiles.find((h) => !dead(h) && (
|
|
196
|
+
killOrderTakesCharmed(entry | 0, ctx.isCharmed(h), isEnemySide(h.side) === mine)
|
|
197
|
+
|| killOrderEntryMatches(entry | 0, h.spec.creatureEntry ?? 0)
|
|
198
|
+
));
|
|
199
|
+
if (hit) return hit;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Tank peel, the PLAYER included: the human tanking a pull picks up the mob eating the healer just
|
|
203
|
+
// as a companion tank does. Their own click still wins, the same precedence a companion has.
|
|
204
|
+
if (f.spec.groupRole === 'tank'
|
|
205
|
+
&& (isAllySide(f.side) || (f.side === 'player' && ctx.explicitEnemyFocus == null))) {
|
|
206
|
+
// Peel priority: a mob eating the HEALER outranks one on a DPS. BOUNDED BY WHAT THIS UNIT MAY
|
|
207
|
+
// CROSS — with no distance term the tank left for a mob 40 yd away, and a leashed one just stood.
|
|
208
|
+
const peelYd = cfg.partyFollowYd ?? cfg.friendlyHoldYd ?? cfg.acquireRangeYd ?? Infinity;
|
|
209
|
+
let loose: Fighter | null = null;
|
|
210
|
+
for (const h of facHostiles) {
|
|
211
|
+
if (!isEnemySide(h.side)) continue;
|
|
212
|
+
if ((ctx.isControlledHard as ((u: Fighter) => boolean) | undefined)?.(h)) continue;
|
|
213
|
+
if (ctx.enemyHasThreat && !ctx.enemyHasThreat(h)) continue;
|
|
214
|
+
if (Number.isFinite(peelYd)) {
|
|
215
|
+
const d = ctx.distanceBetween(f, h);
|
|
216
|
+
if (d != null && d > peelYd) continue;
|
|
217
|
+
}
|
|
218
|
+
const victimRole = hostileTargetOf(h).spec.groupRole;
|
|
219
|
+
if (victimRole === 'tank') continue;
|
|
220
|
+
if (victimRole === 'healer') { loose = h; break; }
|
|
221
|
+
loose ??= h;
|
|
222
|
+
}
|
|
223
|
+
if (loose) return loose;
|
|
224
|
+
}
|
|
225
|
+
// The player's focus drives the free party, so white swings and casts follow click-to-target.
|
|
226
|
+
// Without it the pack's FIRST member absorbed every hit while the frame moved.
|
|
227
|
+
const focus = ensurePlayerFocus();
|
|
228
|
+
if (facHostiles.includes(focus)) return focus;
|
|
229
|
+
return ctx.preferFocusHostile!(facHostiles, f) ?? facHostiles[0]!;
|
|
230
|
+
}
|
|
231
|
+
// No free-fire hostiles means stand down. Returning a corpse focus made the party swing at air after
|
|
232
|
+
// every pull, and a latched ally target has to be released here too or an empty floor keeps it.
|
|
233
|
+
if (isAllySide(f.side) && ctx.allyManualTarget.has(f.side)) {
|
|
234
|
+
ctx.allyManualTarget.delete(f.side);
|
|
235
|
+
}
|
|
236
|
+
return f;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// The nearest living party body inside acquire range of this enemy, or null. Multi-sensor floor aggro
|
|
240
|
+
// must seed on THAT body — a player-only acquire refused the seed while detection cancelled the walk.
|
|
241
|
+
const nearestPartyInAcquire = (enemySide: string): CombatantId | null => {
|
|
242
|
+
const acq = cfg.acquireRangeYd;
|
|
243
|
+
const unitPositionsMutable = ctx.unitPositionsMutable;
|
|
244
|
+
if (acq == null || !unitPositionsMutable) return 'player';
|
|
245
|
+
const at = unitPositionsMutable[enemySide];
|
|
246
|
+
if (!at) return 'player';
|
|
247
|
+
let best: CombatantId | null = null;
|
|
248
|
+
let bestD = Infinity;
|
|
249
|
+
const consider = (id: CombatantId, u: Fighter): void => {
|
|
250
|
+
if (dead(u) || ctx.isCharmed(u)) return;
|
|
251
|
+
const from = unitPositionsMutable![id];
|
|
252
|
+
if (!from) return;
|
|
253
|
+
if (!sameStoreyYd(at, from)) return;
|
|
254
|
+
const d = combatDistanceYd(at, from);
|
|
255
|
+
if (d != null && d <= acq && d < bestD) {
|
|
256
|
+
bestD = d;
|
|
257
|
+
best = id;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
consider('player', player);
|
|
261
|
+
if (pet) consider('pet', pet);
|
|
262
|
+
for (const al of ctx.allyBlock()) consider(al.side as CombatantId, al);
|
|
263
|
+
return best;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// Resolve a threat-list id to a living Fighter, or null. One cached map hit where the branches used to
|
|
267
|
+
// scan: this runs per threat entry per mob per tick, 3.8% of tick self time at 40 allies.
|
|
268
|
+
const fighterByThreatId = (id: CombatantId | null): Fighter | null => {
|
|
269
|
+
if (!id) return null;
|
|
270
|
+
if (id === 'player') return dead(player) ? null : player;
|
|
271
|
+
if (id === 'pet') return pet && !dead(pet) ? pet : null;
|
|
272
|
+
// The pools install unconditionally at session build, so the store is always there by the time
|
|
273
|
+
// anything calls this. The array-scan branches below it were a SECOND, unreachable answer.
|
|
274
|
+
const roster = ctx.sideFighter;
|
|
275
|
+
if (roster && (isAllySide(id) || isEnemySide(id) || isTotemSide(id as Side))) {
|
|
276
|
+
const hit = roster(id as Side);
|
|
277
|
+
return hit && !dead(hit) ? hit : null;
|
|
278
|
+
}
|
|
279
|
+
if (isTotemSide(id as Side)) {
|
|
280
|
+
const tot = totems.get(id as TotemSide);
|
|
281
|
+
return tot && !dead(tot) ? tot : null;
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// One enemy's victim from its threat manager, sticky. An empty list on a fresh pull prefers a living
|
|
287
|
+
// party tank, else the player. Always the true top threat — gap-close closes the distance.
|
|
288
|
+
const hostileTargetOf = (enemyF: Fighter): Fighter => {
|
|
289
|
+
// An ARENA seat is a player, not a mob: it picks its target the way the player faction does
|
|
290
|
+
// (`preferFocusHostile`, healers first) rather than off a creature threat list. Only an arena
|
|
291
|
+
// passes the flag, so every dungeon and raid pull still reads threat. Cite: sessionPools
|
|
292
|
+
// preferFocusHostile; PlayerbotClassAI.cpp:659 GetBotJob.
|
|
293
|
+
if (cfg.enemiesAreATeam && enemyF.spec.classId != null) {
|
|
294
|
+
const pool = ctx.livingHostilesFor(enemyF).filter((h) => !ctx.isUnattackable(h, enemyF));
|
|
295
|
+
const pick = pool.length > 0 ? ctx.preferFocusHostile!(pool, enemyF) : null;
|
|
296
|
+
if (pick) return pick;
|
|
297
|
+
}
|
|
298
|
+
const tm = ctx.threatOf(enemyF);
|
|
299
|
+
// Missing TM (player/ally/pet/totem or lookup miss): empty-list fallback, never throw.
|
|
300
|
+
if (tm) {
|
|
301
|
+
// Drop dead and unattackable entries so nothing sticks on a corpse or a phase-shifted pet. Ids,
|
|
302
|
+
// not cloned rows: the clone spread every hate list once a tick just to read an id.
|
|
303
|
+
const ids = tm.getThreatIds();
|
|
304
|
+
for (let i = 0; i < ids.length; i++) {
|
|
305
|
+
const id = ids[i]!;
|
|
306
|
+
const unit = fighterByThreatId(id);
|
|
307
|
+
if (!unit || ctx.isUnattackable(unit, enemyF)) tm.remove(id);
|
|
308
|
+
}
|
|
309
|
+
// Real melee-reach predicate: a ranged/healer challenger must exceed 1.3× (not 1.1×)
|
|
310
|
+
// before ripping aggro (ThreatManager.cpp:398–411). Geometry absent → melee (legacy).
|
|
311
|
+
const id = tm.getHostileTarget((challengerId) => {
|
|
312
|
+
const cf = fighterByThreatId(challengerId);
|
|
313
|
+
if (!cf || ctx.isUnattackable(cf, enemyF)) return true;
|
|
314
|
+
const d = ctx.distanceBetween(enemyF, cf);
|
|
315
|
+
return d == null || d <= MELEE_REACH_YD + 1e-6;
|
|
316
|
+
});
|
|
317
|
+
const f = fighterByThreatId(id);
|
|
318
|
+
// A threat victim is kept at ANY distance: the C++ has no distance term, and only feign death
|
|
319
|
+
// takes a reference offline. Distance ends a chase through evade, never through re-targeting.
|
|
320
|
+
if (f && !ctx.isUnattackable(f, enemyF)) return f;
|
|
321
|
+
}
|
|
322
|
+
if (cfg.acquireRangeYd != null) {
|
|
323
|
+
const near = ctx.livingHostilesFor(enemyF)[0];
|
|
324
|
+
if (near) return near;
|
|
325
|
+
}
|
|
326
|
+
// Empty threat — open on the party's tank, player first when that is their role.
|
|
327
|
+
// Skip unattackable (phased Imp) so MOD_UNATTACKABLE is not a free tank.
|
|
328
|
+
if (player.hp > 0 && !ctx.isUnattackable(player, enemyF) && player.spec.groupRole === 'tank') return player;
|
|
329
|
+
for (const al of ctx.livingAllies()) {
|
|
330
|
+
if (!ctx.isUnattackable(al, enemyF) && al.spec.groupRole === 'tank') return al;
|
|
331
|
+
}
|
|
332
|
+
if (player.hp > 0 && !ctx.isUnattackable(player, enemyF)) return player;
|
|
333
|
+
for (const al of ctx.livingAllies()) {
|
|
334
|
+
if (!ctx.isUnattackable(al, enemyF)) return al;
|
|
335
|
+
}
|
|
336
|
+
// Last resort: original player seat (may be dead) — better than a phased pet.
|
|
337
|
+
return player;
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
/** Snapshot + selectTarget resolve for EventAI / spell-list / ScriptDev (S2 D5). */
|
|
341
|
+
const selectTargetLookup = (caster: Fighter) => (id: string): Fighter | null => {
|
|
342
|
+
if (id === player.side) return player;
|
|
343
|
+
const fromThreat = fighterByThreatId(id);
|
|
344
|
+
if (fromThreat) return fromThreat;
|
|
345
|
+
const fromHostiles = ctx.livingHostilesFor(caster).find((h) => h.side === id);
|
|
346
|
+
if (fromHostiles) return fromHostiles;
|
|
347
|
+
const fromPack = ctx.livingEnemies().find((e) => e.side === id);
|
|
348
|
+
if (fromPack) return fromPack;
|
|
349
|
+
const al = isAllySide(id) ? ctx.sideFighter?.(id) ?? null : null;
|
|
350
|
+
return al && al.hp > 0 ? al : null;
|
|
351
|
+
};
|
|
352
|
+
// FriendlyEligibleDispelInRangeCheck with empty masks: in combat AND immobilized, snared, frozen or
|
|
353
|
+
// crowd-controlled, never "carries a debuff". Cite: GridNotifiers.h:923; UnitAI.cpp:764-771.
|
|
354
|
+
const isEligibleDispelFriendly = (f: Fighter): boolean => {
|
|
355
|
+
const t = ctx.t;
|
|
356
|
+
// IsInCombat(): an add that has not engaged is no dispel target in the C++ either.
|
|
357
|
+
if (ctx.threatOf(f)?.isEmpty() !== false) return false;
|
|
358
|
+
if (f.rootedUntil > t || f.stunnedUntil > t || f.fearedUntil > t || f.incapUntil > t) return true;
|
|
359
|
+
for (const e of ctx.effectsOn(f.side)) {
|
|
360
|
+
if (e.kind !== 'speed') continue;
|
|
361
|
+
if ((e.aura ?? 0) !== AURA_DECREASE_SPEED) continue;
|
|
362
|
+
if ((e.pct ?? 0) < 0) return true;
|
|
363
|
+
}
|
|
364
|
+
return false;
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
const selectTargetCtxFor = (
|
|
368
|
+
caster: Fighter, spellId = 0, selectClass = 0, friendlyMaxRangeYd = 0,
|
|
369
|
+
requireInMelee = false,
|
|
370
|
+
) => {
|
|
371
|
+
const victim = hostileTargetOf(caster);
|
|
372
|
+
const hostiles: SelectTargetHostile[] = ctx.livingHostilesFor(caster).map((h) => ({
|
|
373
|
+
id: h.side,
|
|
374
|
+
// SELECT_FLAG_PLAYER is TYPEID_PLAYER. A companion pet and a summoned guardian both hold
|
|
375
|
+
// an `ally_N` seat, so `isAllySide` alone read both as players. Cite: Unit.cpp:12069.
|
|
376
|
+
isPlayer: isPlayerCharacterTarget(h),
|
|
377
|
+
classId: h.spec.classId,
|
|
378
|
+
powerType: h.spec.powerType,
|
|
379
|
+
casting: h.castingSpell != null,
|
|
380
|
+
inMelee: (() => {
|
|
381
|
+
const d = ctx.distanceBetween(caster, h);
|
|
382
|
+
return d != null && d <= MIN_AGGRO_DISTANCE;
|
|
383
|
+
})(),
|
|
384
|
+
hpPct: h.hp / Math.max(1, h.spec.maxHealth),
|
|
385
|
+
distanceYd: ctx.distanceBetween(caster, h) ?? undefined,
|
|
386
|
+
hasAura: (id: number) => h.buffActive.has(id),
|
|
387
|
+
}));
|
|
388
|
+
// Faction-relative support pool (not "always the pack"): charmed former-allies
|
|
389
|
+
// drop out of friendlyPoolOf; player casters see livingFriendlies-equivalent.
|
|
390
|
+
const friendlies: SelectTargetFriendly[] = ctx.friendlyPoolOf(caster).map((ally) => ({
|
|
391
|
+
id: ally.side,
|
|
392
|
+
isSelf: ally.side === caster.side,
|
|
393
|
+
hpPct: ally.hp / Math.max(1, ally.spec.maxHealth),
|
|
394
|
+
hasAura: (id: number) => ally.buffActive.has(id),
|
|
395
|
+
hasDispellable: isEligibleDispelFriendly(ally),
|
|
396
|
+
distanceYd: ctx.distanceBetween(caster, ally) ?? undefined,
|
|
397
|
+
}));
|
|
398
|
+
return buildSelectTargetCtx({
|
|
399
|
+
caster,
|
|
400
|
+
victimId: victim.side,
|
|
401
|
+
threatList: ctx.threatOf(caster)?.getThreatIds().slice() ?? [],
|
|
402
|
+
hostiles,
|
|
403
|
+
friendlies,
|
|
404
|
+
playerSide: player.side,
|
|
405
|
+
spellId,
|
|
406
|
+
...(selectClass > 0 ? { selectClass } : {}),
|
|
407
|
+
...(friendlyMaxRangeYd > 0 ? { friendlyMaxRangeYd } : {}),
|
|
408
|
+
...(requireInMelee ? { requireInMelee: true } : {}),
|
|
409
|
+
rng,
|
|
410
|
+
});
|
|
411
|
+
};
|
|
412
|
+
// Non-cast EventAI (REMOVEAURAS, ATTACK_START, …): full TARGET_T via selectTarget.
|
|
413
|
+
// Cite: CreatureEventAI.cpp ProcessAction GetTargetByType. Fail → SELF/self else victim.
|
|
414
|
+
const resolveEventAiTargetFighter = (summoner: Fighter, targetSel: number): Fighter => {
|
|
415
|
+
const mode = targetSel | 0;
|
|
416
|
+
const got = resolveSelectTargetFighter(
|
|
417
|
+
mode,
|
|
418
|
+
selectTargetCtxFor(summoner),
|
|
419
|
+
'eventai',
|
|
420
|
+
selectTargetLookup(summoner),
|
|
421
|
+
summoner,
|
|
422
|
+
);
|
|
423
|
+
if (got) return got;
|
|
424
|
+
if (mode === TARGET_T.SELF) return summoner;
|
|
425
|
+
return hostileTargetOf(summoner);
|
|
426
|
+
};
|
|
427
|
+
// Cast path: null on failure → caller keeps current victim.
|
|
428
|
+
const resolveEventAiCastTarget = (
|
|
429
|
+
caster: Fighter,
|
|
430
|
+
spell: SpellDef,
|
|
431
|
+
mode: number,
|
|
432
|
+
source: 'eventai' | 'spell_list' = 'eventai',
|
|
433
|
+
selectClass = 0,
|
|
434
|
+
friendlyMaxRangeYd = 0,
|
|
435
|
+
requireInMelee = false,
|
|
436
|
+
): Fighter | null =>
|
|
437
|
+
resolveSelectTargetFighter(
|
|
438
|
+
mode,
|
|
439
|
+
selectTargetCtxFor(caster, spell.id, selectClass, friendlyMaxRangeYd, requireInMelee),
|
|
440
|
+
source,
|
|
441
|
+
selectTargetLookup(caster),
|
|
442
|
+
caster,
|
|
443
|
+
);
|
|
444
|
+
const resolveHighestHpTopThreat = (caster: Fighter, topN: number): Fighter | null => {
|
|
445
|
+
const res = selectHighestHpAmongTopThreat(selectTargetCtxFor(caster), topN, true);
|
|
446
|
+
if (!res.ok || res.id == null) return null;
|
|
447
|
+
return selectTargetLookup(caster)(res.id);
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* A team match does not stop because a seat fell. `seedAttackStart` opens every enemy on ONE body
|
|
452
|
+
* (createSession.ts:213-226), and when that body dies the list empties, `enemyEngaged` reads
|
|
453
|
+
* not-engaged and the unit stands still for the rest of the match — measured 17,600 idle ticks to
|
|
454
|
+
* the 30 min cap in a 2v2. So a player-shaped enemy with an empty list re-opens on the nearest
|
|
455
|
+
* living hostile, the same `addThreatDirectly(id, 1)` the seed uses. Off by default: a CREATURE
|
|
456
|
+
* with nobody on its list is supposed to stand down and walk home (HomeMovementGenerator).
|
|
457
|
+
*/
|
|
458
|
+
const reacquireEmptyThreat = (): number => {
|
|
459
|
+
let reopened = 0;
|
|
460
|
+
for (const ef of ctx.livingEnemies()) {
|
|
461
|
+
const tm = ctx.threatOf(ef);
|
|
462
|
+
if (!tm || !tm.isEmpty()) continue;
|
|
463
|
+
const pool = ctx.livingHostilesFor(ef).filter((h) => !ctx.isUnattackable(h, ef));
|
|
464
|
+
const next = ctx.preferFocusHostile!(pool, ef) ?? pool[0];
|
|
465
|
+
if (!next) continue;
|
|
466
|
+
tm.addThreatDirectly(next.side, 1, false);
|
|
467
|
+
reopened++;
|
|
468
|
+
}
|
|
469
|
+
return reopened;
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
ctx.ensurePlayerFocus = ensurePlayerFocus;
|
|
473
|
+
ctx.foeOf = foeOf;
|
|
474
|
+
ctx.hostileTargetOf = hostileTargetOf;
|
|
475
|
+
ctx.reacquireEmptyThreat = reacquireEmptyThreat;
|
|
476
|
+
ctx.nearestPartyInAcquire = nearestPartyInAcquire;
|
|
477
|
+
ctx.fighterByThreatId = fighterByThreatId;
|
|
478
|
+
ctx.resolveEventAiTargetFighter = resolveEventAiTargetFighter;
|
|
479
|
+
ctx.resolveEventAiCastTarget = resolveEventAiCastTarget;
|
|
480
|
+
// DoSelectLowestHpFriendly: the lowest-hp friendly within radiusYd missing at least minDeficit hp,
|
|
481
|
+
// self included. Cite: UnitAI.cpp DoSelectLowestHpFriendly; boss_sulfuron_harbinger.cpp:162.
|
|
482
|
+
const resolveLowestHpFriendly = (
|
|
483
|
+
caster: Fighter, radiusYd: number, minDeficit: number,
|
|
484
|
+
): Fighter | null => {
|
|
485
|
+
let best: Fighter | null = null;
|
|
486
|
+
let bestPct = Infinity;
|
|
487
|
+
for (const ally of ctx.friendlyPoolOf(caster)) {
|
|
488
|
+
if (dead(ally)) continue;
|
|
489
|
+
const max = Math.max(1, ally.spec.maxHealth);
|
|
490
|
+
if (max - ally.hp < Math.max(1, minDeficit)) continue;
|
|
491
|
+
if (ally.side !== caster.side) {
|
|
492
|
+
const d = ctx.distanceBetween(caster, ally);
|
|
493
|
+
if (d != null && d > radiusYd) continue;
|
|
494
|
+
}
|
|
495
|
+
const pct = ally.hp / max;
|
|
496
|
+
if (pct < bestPct) {
|
|
497
|
+
bestPct = pct;
|
|
498
|
+
best = ally;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return best;
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
ctx.resolveHighestHpTopThreat = resolveHighestHpTopThreat;
|
|
505
|
+
ctx.resolveLowestHpFriendly = resolveLowestHpFriendly;
|
|
506
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// Follow arms for the motion phase, peeled from sessionMotion for the filesize ratchet: the pet bar's
|
|
2
|
+
// stay and follow, the guardian's out-of-combat follow, one scripted follow, and the party bubble.
|
|
3
|
+
// No combat import.
|
|
4
|
+
|
|
5
|
+
import { isEnemySide, type Side } from '../core/events.ts';
|
|
6
|
+
import { moveStepYd, combatDistanceYd, type CombatPosYd } from './combatGeometry.ts';
|
|
7
|
+
import { followDistFor, isGuardianFollow, PET_FOLLOW_SLACK_YD } from '../../domain/creature/creatureAiConstants.ts';
|
|
8
|
+
import type { CombatContext } from './context.ts';
|
|
9
|
+
import type { Fighter } from './types.ts';
|
|
10
|
+
import type { MotionOwner } from './motionClaim.ts';
|
|
11
|
+
import type { MotionGenerator } from './motionGenerator.ts';
|
|
12
|
+
|
|
13
|
+
/** Closures the follow arms need from installSessionMotion. */
|
|
14
|
+
export interface FollowDeps {
|
|
15
|
+
ctx: CombatContext;
|
|
16
|
+
tickMs: number;
|
|
17
|
+
posOf: (side: Side | string) => CombatPosYd | undefined;
|
|
18
|
+
setPos: (side: Side | string, p: CombatPosYd) => void;
|
|
19
|
+
dead: (f: Fighter) => boolean;
|
|
20
|
+
foeOf: (f: Fighter) => Fighter | null;
|
|
21
|
+
bySide: (s: Side) => Fighter;
|
|
22
|
+
enemyEngaged: (f: Fighter) => boolean;
|
|
23
|
+
takeMotion: (
|
|
24
|
+
side: string, owner: MotionOwner, goal: CombatPosYd | null,
|
|
25
|
+
opts?: { force?: boolean; holdMs?: number },
|
|
26
|
+
) => CombatPosYd | null;
|
|
27
|
+
navStepToward: (
|
|
28
|
+
side: string, from: CombatPosYd, to: CombatPosYd,
|
|
29
|
+
step: number, stopAtDist: number, pathfind?: boolean,
|
|
30
|
+
) => CombatPosYd;
|
|
31
|
+
runSpeedYdPerSec: (f: Fighter) => number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function createFollowArms(deps: FollowDeps): {
|
|
35
|
+
petCommand: MotionGenerator;
|
|
36
|
+
guardianFollow: MotionGenerator;
|
|
37
|
+
spiritFollow: MotionGenerator;
|
|
38
|
+
partyFollow: MotionGenerator;
|
|
39
|
+
} {
|
|
40
|
+
const {
|
|
41
|
+
ctx, tickMs, posOf, setPos, dead, foeOf, bySide, enemyEngaged,
|
|
42
|
+
takeMotion, navStepToward, runSpeedYdPerSec,
|
|
43
|
+
} = deps;
|
|
44
|
+
|
|
45
|
+
// The pet bar's stay, follow and attack. Stay parks on its pin, follow parks at the follow distance
|
|
46
|
+
// and a recall clears at twice that, and attack falls to the companion dest and corridor.
|
|
47
|
+
const advancePetCommand = (f: Fighter): boolean => {
|
|
48
|
+
if (f.side !== 'pet') return false;
|
|
49
|
+
if (ctx.petCommand === 'stay') {
|
|
50
|
+
const from = posOf('pet');
|
|
51
|
+
if (!from) return false;
|
|
52
|
+
const speed = runSpeedYdPerSec(f);
|
|
53
|
+
const stay = ctx.petStayPos ?? { x: from.x, y: from.y, ...(from.z != null ? { z: from.z } : {}) };
|
|
54
|
+
ctx.petStayPos = stay;
|
|
55
|
+
const dStay = combatDistanceYd(from, stay);
|
|
56
|
+
if (dStay != null && dStay > PET_FOLLOW_SLACK_YD && speed > 0
|
|
57
|
+
&& takeMotion('pet', 'pet', stay) != null) {
|
|
58
|
+
setPos('pet', navStepToward('pet', from, stay, moveStepYd(speed, tickMs), 0, true));
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
if (ctx.petCommand === 'attack') {
|
|
63
|
+
ctx.petRetreating = false;
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const from = posOf('pet');
|
|
67
|
+
const owner = posOf('player');
|
|
68
|
+
if (!from || !owner) return false;
|
|
69
|
+
const d = combatDistanceYd(from, owner);
|
|
70
|
+
if (ctx.petRetreating && d != null && d <= PET_FOLLOW_SLACK_YD) ctx.petRetreating = false;
|
|
71
|
+
if (!ctx.petRetreating) {
|
|
72
|
+
const victim = foeOf(f);
|
|
73
|
+
if (victim && victim !== f && !dead(victim)) return false;
|
|
74
|
+
}
|
|
75
|
+
const park = followDistFor(f.spec);
|
|
76
|
+
const speed = runSpeedYdPerSec(f);
|
|
77
|
+
if (d != null && d > park && speed > 0 && takeMotion('pet', 'pet', owner) != null) {
|
|
78
|
+
setPos('pet', navStepToward('pet', from, owner, moveStepYd(speed, tickMs), park, true));
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/** GuardianAI OOC follow at 1.5 (Imp 11939 at 3). Cite: GuardianAI.cpp:31, :36. */
|
|
84
|
+
const advanceGuardianFollow = (f: Fighter): boolean => {
|
|
85
|
+
if (!isGuardianFollow(f.spec)) return false;
|
|
86
|
+
if (isEnemySide(f.side) && enemyEngaged(f)) return false;
|
|
87
|
+
if (!isEnemySide(f.side)) {
|
|
88
|
+
const victim = foeOf(f);
|
|
89
|
+
if (victim && victim !== f && !dead(victim)) return false;
|
|
90
|
+
}
|
|
91
|
+
let ownerSide: Side | null = null;
|
|
92
|
+
for (const [owner, owned] of ctx.guardianSidesBySummoner) {
|
|
93
|
+
if (owned.has(f.side)) { ownerSide = owner; break; }
|
|
94
|
+
}
|
|
95
|
+
if (!ownerSide && !isEnemySide(f.side)) ownerSide = 'player';
|
|
96
|
+
if (!ownerSide) return false;
|
|
97
|
+
const from = posOf(f.side);
|
|
98
|
+
const owner = posOf(ownerSide);
|
|
99
|
+
if (!from || !owner) return false;
|
|
100
|
+
const park = followDistFor(f.spec);
|
|
101
|
+
const d = combatDistanceYd(from, owner);
|
|
102
|
+
const speed = runSpeedYdPerSec(f);
|
|
103
|
+
if (d != null && d > park && speed > 0 && takeMotion(f.side, 'follow', owner) != null) {
|
|
104
|
+
setPos(f.side, navStepToward(f.side, from, owner, moveStepYd(speed, tickMs), park, !isEnemySide(f.side)));
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// ScriptDev JustSummoned MoveFollow(boss) during the encounter — Burning Spirit 9178. Cite:
|
|
110
|
+
// boss_ambassador_flamelash.cpp:112 MoveFollow(m_creature, 0, 0).
|
|
111
|
+
const advanceFlamelashSpiritFollow = (f: Fighter): boolean => {
|
|
112
|
+
if (((f.spec.creatureEntry ?? 0) | 0) !== 9178) return false;
|
|
113
|
+
let ownerSide: Side | null = null;
|
|
114
|
+
for (const [owner, owned] of ctx.guardianSidesBySummoner) {
|
|
115
|
+
if (owned.has(f.side)) { ownerSide = owner; break; }
|
|
116
|
+
}
|
|
117
|
+
if (!ownerSide) return false;
|
|
118
|
+
const ownerF = bySide(ownerSide);
|
|
119
|
+
if (!ownerF || ((ownerF.spec.creatureEntry ?? 0) | 0) !== 9156) return false;
|
|
120
|
+
const from = posOf(f.side);
|
|
121
|
+
const owner = posOf(ownerSide);
|
|
122
|
+
if (!from || !owner) return false;
|
|
123
|
+
const park = 0;
|
|
124
|
+
const d = combatDistanceYd(from, owner);
|
|
125
|
+
const speed = runSpeedYdPerSec(f);
|
|
126
|
+
if (d != null && d > park && speed > 0 && takeMotion(f.side, 'follow', owner) != null) {
|
|
127
|
+
setPos(f.side, navStepToward(f.side, from, owner, moveStepYd(speed, tickMs), park, false));
|
|
128
|
+
}
|
|
129
|
+
return true;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// The party bubble. No hostile inside cfg.acquireRangeYd means foeOf hands back the unit itself
|
|
133
|
+
// (sessionPools.ts:347) and chase stands it forever (sessionChase.ts:160). Cite: combatGeometry.ts:788.
|
|
134
|
+
const advancePartyFollow = (f: Fighter): boolean => {
|
|
135
|
+
const holdYd = ctx.cfg.partyFollowYd;
|
|
136
|
+
// The RTS hold bubble answers the same question with an anchor, and `home` above walks to it.
|
|
137
|
+
if (holdYd == null || !(holdYd > 0) || ctx.cfg.friendlyHoldYd != null) return false;
|
|
138
|
+
if (isEnemySide(f.side) || f.side === 'player' || f.side === 'pet') return false;
|
|
139
|
+
// The bubble is the unit path's rule: it tows a member the player moves TOGETHER with their own
|
|
140
|
+
// body. One sent off alone, or left standing while you walk alone, keeps its ground until regrouped.
|
|
141
|
+
const unit = ctx.followGroupSides;
|
|
142
|
+
if (unit && !(unit.has(f.side) && unit.has('player'))) return false;
|
|
143
|
+
// A live focus is the chase arm's; only the no-target sentinel reaches here.
|
|
144
|
+
const victim = foeOf(f);
|
|
145
|
+
if (victim && victim !== f && !dead(victim)) return false;
|
|
146
|
+
const leader = bySide('player');
|
|
147
|
+
if (!leader || dead(leader)) return false;
|
|
148
|
+
const from = posOf(f.side);
|
|
149
|
+
const lead = posOf('player');
|
|
150
|
+
if (!from || !lead) return false;
|
|
151
|
+
const d = combatDistanceYd(from, lead);
|
|
152
|
+
if (d == null || d <= holdYd) return false;
|
|
153
|
+
const speed = runSpeedYdPerSec(f);
|
|
154
|
+
if (!(speed > 0) || takeMotion(f.side, 'follow', lead) == null) return false;
|
|
155
|
+
setPos(f.side, navStepToward(f.side, from, lead, moveStepYd(speed, tickMs), holdYd, true));
|
|
156
|
+
return true;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// Three generators share the `follow` tag on purpose — CMaNGOS stacks many
|
|
160
|
+
// FollowMovementGenerator instances too; the tag is the kind, not the instance.
|
|
161
|
+
return {
|
|
162
|
+
petCommand: { owner: 'pet', update: (f) => advancePetCommand(f) },
|
|
163
|
+
guardianFollow: { owner: 'follow', update: (f) => advanceGuardianFollow(f) },
|
|
164
|
+
spiritFollow: { owner: 'follow', update: (f) => advanceFlamelashSpiritFollow(f) },
|
|
165
|
+
partyFollow: { owner: 'follow', update: (f) => advancePartyFollow(f) },
|
|
166
|
+
};
|
|
167
|
+
}
|