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,695 @@
|
|
|
1
|
+
// The P7 lab track: run authored comps headlessly and table the win rates. Not a player mode; it
|
|
2
|
+
// drives createDuelSession (duel.ts:182).
|
|
3
|
+
|
|
4
|
+
import type { DataStore } from '../../data/dataStore.ts';
|
|
5
|
+
import { createSession, type CombatantSpec, type CombatSession } from '../../engine/combat.ts';
|
|
6
|
+
import type { Character } from '../character/character.ts';
|
|
7
|
+
import {
|
|
8
|
+
companionCharacter, companionLevel, companionPetSpec, companionSpec, companionSpellbook,
|
|
9
|
+
type Companion,
|
|
10
|
+
} from '../bots/squad.ts';
|
|
11
|
+
import { runPrePullHealthstones, type StoneHolder } from '../../engine/game/prePullHealthstones.ts';
|
|
12
|
+
import { emptyInventory } from '../items/inventory.ts';
|
|
13
|
+
import { routeWeaponImbueItem } from '../../engine/game/weaponImbueItem.ts';
|
|
14
|
+
import type { ItemRuleHand } from '../rotation/types.ts';
|
|
15
|
+
import { applyBgTeamPrebuffs } from './bgPrebuff.ts';
|
|
16
|
+
import { openerFormOf } from '../rotation/openerForm.ts';
|
|
17
|
+
import {
|
|
18
|
+
companionActionProvider, companionRotationOf, isCompanionKeepUpSpell, syncCompanionBagItemRules,
|
|
19
|
+
} from '../bots/companionRotation.ts';
|
|
20
|
+
import { vsClassVariant } from '../rotation/rotationSuggestions.ts';
|
|
21
|
+
import { createDuelSession, resolveDuelOutcome } from '../run/duel.ts';
|
|
22
|
+
import { seedDuelGeometry } from '../../engine/game/combatSeed.ts';
|
|
23
|
+
import { hashSeed, mulberry32 } from '../../engine/core/rng.ts';
|
|
24
|
+
import { buildEnemySeats, type BgTeamSeat } from './bgRoster.ts';
|
|
25
|
+
import { bgTier, DEFAULT_BG_TIER, type BgTierId } from './bgTier.ts';
|
|
26
|
+
import { compsForBracket, type ArenaBracket, type ArenaComp } from './arenaComps.ts';
|
|
27
|
+
|
|
28
|
+
// Seeds per pair. CLAUDE.md §5: one run is a rate, not a verdict — never quote a win rate off fewer than
|
|
29
|
+
// five.
|
|
30
|
+
export const LAB_DEFAULT_SEEDS = 5;
|
|
31
|
+
|
|
32
|
+
export interface LabPairResult {
|
|
33
|
+
aId: string;
|
|
34
|
+
aName: string;
|
|
35
|
+
bId: string;
|
|
36
|
+
bName: string;
|
|
37
|
+
/** Duels actually run for this pair (a pair whose seats cannot be built runs 0). */
|
|
38
|
+
duels: number;
|
|
39
|
+
aWins: number;
|
|
40
|
+
bWins: number;
|
|
41
|
+
/** Timed out with no winner. A draw is a real result, not a failure. */
|
|
42
|
+
draws: number;
|
|
43
|
+
/** aWins as a percentage of duels run, 0 when none ran. */
|
|
44
|
+
aWinPct: number;
|
|
45
|
+
avgDurationMs: number;
|
|
46
|
+
/** Comp seats actually seated on each side. A duel seats the lead alone; a team match seats the comp. */
|
|
47
|
+
bodiesA: number;
|
|
48
|
+
bodiesB: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// A comp's seats as fightable specs PLUS their combat brains. The brain is not optional: with no
|
|
52
|
+
// action provider a player-shaped spec has no event-AI slots, so the target only auto-attacks.
|
|
53
|
+
export function arenaSeats(
|
|
54
|
+
ds: DataStore,
|
|
55
|
+
char: Character,
|
|
56
|
+
comp: ArenaComp,
|
|
57
|
+
seed: number,
|
|
58
|
+
opts?: {
|
|
59
|
+
teamSize?: number;
|
|
60
|
+
tier?: BgTierId;
|
|
61
|
+
team?: 'alliance' | 'horde';
|
|
62
|
+
// Take the other faction when `team` cannot field this comp — for the gauntlet and the arena,
|
|
63
|
+
// where the opponent is a DUELIST rather than the other side of a war. A battleground never does.
|
|
64
|
+
otherFactionIfUnseatable?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* G7's axis, and INDEPENDENT of tier on purpose: `kit` gives every seat the consume kit the
|
|
67
|
+
* tier machinery gives a raid-profile body, `none` gives it none, so a Freemade cell can
|
|
68
|
+
* fight kitted and an Apes cell dry. Absent = the tier's own policy
|
|
69
|
+
* (`profileWantsConsumes`), which is what every live caller means.
|
|
70
|
+
*
|
|
71
|
+
* The PvP Insignia is NOT part of this: `applyPvpKit` equips it either way
|
|
72
|
+
* (`bgConsumes.ts:137-152`), because the hard-CC self-rescue reads it off
|
|
73
|
+
* `session.unitItems` and a dry Freemade still wears a trinket. The axis is the
|
|
74
|
+
* consumables.
|
|
75
|
+
*/
|
|
76
|
+
loadout?: 'none' | 'kit';
|
|
77
|
+
/**
|
|
78
|
+
* G16: the class this side is fighting. A seat that names no rotation of its own then asks for
|
|
79
|
+
* `vs-<class>`, and `selectBand` falls that back to the variant-less pvp pool when nobody has
|
|
80
|
+
* authored it - so every one of the 81 matchups works before any of them is written.
|
|
81
|
+
*
|
|
82
|
+
* A seat's OWN `rotation` still wins: a promoted duelist names the list it was promoted on.
|
|
83
|
+
*/
|
|
84
|
+
vsClass?: number;
|
|
85
|
+
},
|
|
86
|
+
) {
|
|
87
|
+
const build = (team: 'alliance' | 'horde'): BgTeamSeat[] => buildEnemySeats({
|
|
88
|
+
ds, char, team, teamSize: opts?.teamSize ?? 1, seed,
|
|
89
|
+
tier: bgTier(opts?.tier ?? comp.tier ?? DEFAULT_BG_TIER), comp,
|
|
90
|
+
...(opts?.loadout ? { consumes: opts.loadout === 'kit' } : {}),
|
|
91
|
+
});
|
|
92
|
+
// A comp the faction pool cannot field is DROPPED and replaced with random bots, silently.
|
|
93
|
+
// Paladin is Alliance-only and shaman Horde-only, so a fixed side leaves one class unseatable.
|
|
94
|
+
const asked = opts?.team ?? 'horde';
|
|
95
|
+
let seats = build(asked);
|
|
96
|
+
if ((!opts?.team || opts.otherFactionIfUnseatable) && !seatsAreTheComp(comp, seats)) {
|
|
97
|
+
const other = asked === 'horde' ? 'alliance' : 'horde';
|
|
98
|
+
const alt = build(other);
|
|
99
|
+
if (seatsAreTheComp(comp, alt)) seats = alt;
|
|
100
|
+
}
|
|
101
|
+
// Gate-time prep, the pass a BG gives both teams (bgScreen.ts:234-238). Without it 69 of 69 duel
|
|
102
|
+
// and gauntlet seats walked in with zero pre-pull auras and an uncoated weapon.
|
|
103
|
+
applyBgTeamPrebuffs({
|
|
104
|
+
ds, now: Date.now(), playerLevel: char.level, seats, applyImbue: seatImbue(ds, char, seats),
|
|
105
|
+
});
|
|
106
|
+
// The conjure step: prebuff never spends a Soul Shard, so a warlock rung carried a Healthstone
|
|
107
|
+
// recovery row and no stone. A lone warlock supplies itself (prePullHealthstones.ts:97).
|
|
108
|
+
seatHealthstones(ds, char, seats);
|
|
109
|
+
for (const seat of seats) if (seat.comp) freshenPrepClock(seat.comp);
|
|
110
|
+
const out = [];
|
|
111
|
+
for (const seat of seats) {
|
|
112
|
+
const body = seat.comp;
|
|
113
|
+
if (!body) continue;
|
|
114
|
+
// The seat's authored variant when the comp named one; else G16's matchup list; else the class
|
|
115
|
+
// default pvp band, which is every shipped duelist (arenaComps ArenaCompSeat.rotation).
|
|
116
|
+
const variant = seat.compSeat?.rotation ?? vsClassVariant(opts?.vsClass);
|
|
117
|
+
// Bagged combat items become rules, the sync a BG runs per unit (bgScreen.ts:492). An authored
|
|
118
|
+
// variant band carries none of the default band's 11 gadget rows, so without this it throws nothing.
|
|
119
|
+
const rot = syncCompanionBagItemRules(
|
|
120
|
+
companionRotationOf(body, char.level, ds, undefined, {
|
|
121
|
+
mode: 'pvp', ...(variant ? { variant } : {}),
|
|
122
|
+
}),
|
|
123
|
+
companionCharacter(body, char.level, ds),
|
|
124
|
+
body.bags,
|
|
125
|
+
ds,
|
|
126
|
+
);
|
|
127
|
+
const openerForm = openerFormOf(rot, ds);
|
|
128
|
+
out.push({
|
|
129
|
+
body,
|
|
130
|
+
// Seated in the state its list opens with: a duel starts unflagged (fighterFactory.ts:908),
|
|
131
|
+
// so a rogue holds Stealth and a feral Bear at t=0 instead of spending the opening GCDs on it.
|
|
132
|
+
spec: companionSpec(body, char.level, ds, {
|
|
133
|
+
stealthForPull: true,
|
|
134
|
+
...(openerForm ? { openerForm } : {}),
|
|
135
|
+
}),
|
|
136
|
+
/** Hunter beast / warlock demon. `buildEnemySeats` already tamed one (bgRoster.ts:113). */
|
|
137
|
+
pet: companionPetSpec(body, char.level, ds),
|
|
138
|
+
// The list this seat actually fights with, so a caller can NAME it - which band, which
|
|
139
|
+
// variant - instead of assuming the comp got what it asked for (duel plan §2).
|
|
140
|
+
rot,
|
|
141
|
+
provider: companionActionProvider(rot, undefined, {
|
|
142
|
+
companion: body,
|
|
143
|
+
isOocKeepUp: (id) => isCompanionKeepUpSpell(ds.spell(id)),
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Drop the wall-clock expiry prep just stamped: buildCombatant.ts:909 reads it as `expiresAt - now`,
|
|
151
|
+
// so two lab runs ms apart got different buff lengths. Absent = the spell's own full duration.
|
|
152
|
+
function freshenPrepClock(body: Companion): void {
|
|
153
|
+
if (body.prePullAuras) {
|
|
154
|
+
body.prePullAuras = body.prePullAuras.map(({ expiresAt: _drop, ...rest }) => rest);
|
|
155
|
+
}
|
|
156
|
+
const te = body.tempEnchants;
|
|
157
|
+
if (!te) return;
|
|
158
|
+
const drop = <T extends { expiresAt?: number }>(h: T) => {
|
|
159
|
+
const { expiresAt: _drop, ...rest } = h;
|
|
160
|
+
return rest as T;
|
|
161
|
+
};
|
|
162
|
+
body.tempEnchants = {
|
|
163
|
+
...(te.mainhand ? { mainhand: drop(te.mainhand) } : {}),
|
|
164
|
+
...(te.offhand ? { offhand: drop(te.offhand) } : {}),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** One healthstone run over a comp's own seats, the dungeon prep's call (squadDungeon.ts:745). */
|
|
169
|
+
function seatHealthstones(ds: DataStore, char: Character, seats: readonly BgTeamSeat[]): void {
|
|
170
|
+
const holders: StoneHolder[] = [];
|
|
171
|
+
for (const seat of seats) {
|
|
172
|
+
const body = seat.comp;
|
|
173
|
+
if (!body) continue;
|
|
174
|
+
const lvl = companionLevel(body, char.level);
|
|
175
|
+
const wearer = companionCharacter(body, lvl, ds);
|
|
176
|
+
holders.push({
|
|
177
|
+
name: body.name,
|
|
178
|
+
char: wearer,
|
|
179
|
+
role: body.role === 'tank' ? 'tank' : body.role === 'healer' ? 'healer' : 'dps',
|
|
180
|
+
...(body.rotation?.autoSig?.spec ? { specName: body.rotation.autoSig.spec } : {}),
|
|
181
|
+
knownSpellIds: companionSpellbook(body, lvl, ds).known,
|
|
182
|
+
auraSpellIds: (body.prePullAuras ?? []).map((a) => a.spellId),
|
|
183
|
+
bag: () => body.bags ?? emptyInventory(),
|
|
184
|
+
setBag: (inv) => { body.bags = inv; },
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (!holders.length) return;
|
|
188
|
+
// Arena is not a raid wipe: keep no shard reserve. A 2-shard bag plus the default reserve of 2
|
|
189
|
+
// meant a dest warlock walked in with a Healthstone recovery row and no stone (seed 8402).
|
|
190
|
+
runPrePullHealthstones(holders, ds, '', { shardReserve: 0 });
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Coat a seat's weapon out of ITS OWN bags: the router debits whoever `inventory` names, so it runs
|
|
194
|
+
// unbound per body with a setter that writes back (squadDungeon.ts:534-561).
|
|
195
|
+
function seatImbue(ds: DataStore, char: Character, seats: readonly BgTeamSeat[]) {
|
|
196
|
+
const bodies = seats.map((s) => s.comp).filter((c): c is Companion => c != null);
|
|
197
|
+
return (compId: string, itemEntry: number, hand?: ItemRuleHand): boolean => {
|
|
198
|
+
const comp = bodies.find((c) => c.id === compId);
|
|
199
|
+
if (!comp) return false;
|
|
200
|
+
const res = routeWeaponImbueItem(
|
|
201
|
+
itemEntry,
|
|
202
|
+
{ target: { kind: 'companion', id: compId }, ...(hand != null ? { slot: hand } : {}) },
|
|
203
|
+
{
|
|
204
|
+
ds,
|
|
205
|
+
char,
|
|
206
|
+
inventory: comp.bags ?? emptyInventory(),
|
|
207
|
+
squad: bodies,
|
|
208
|
+
setPlayer: () => {},
|
|
209
|
+
setCompanion: (id, patch, inventory) => {
|
|
210
|
+
const c = bodies.find((x) => x.id === id);
|
|
211
|
+
if (!c) return;
|
|
212
|
+
c.equipped = patch.equipped;
|
|
213
|
+
c.tempEnchants = patch.tempEnchants;
|
|
214
|
+
c.bags = inventory;
|
|
215
|
+
},
|
|
216
|
+
log: () => {},
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
return !!res?.ok;
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** Every body came back as the class its comp seat asked for - i.e. the comp seated whole. */
|
|
224
|
+
function seatsAreTheComp(comp: ArenaComp, seats: readonly BgTeamSeat[]): boolean {
|
|
225
|
+
if (seats.length !== comp.seats.length) return false;
|
|
226
|
+
return comp.seats.every((seat, i) => seats[i]?.comp?.cls === seat.cls);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** The 1v1 case of `arenaSeats`, kept because most callers seat exactly one duelist. */
|
|
230
|
+
export function arenaSeat(ds: DataStore, char: Character, comp: ArenaComp, seed: number) {
|
|
231
|
+
return arenaSeats(ds, char, comp, seed)[0] ?? null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// The seed for one row's nth duel. Public because P7.2 replays a fight from (challenger, target,
|
|
235
|
+
// index) and must land on the same one, so there is no second copy of the arithmetic to drift.
|
|
236
|
+
export function labSeedFor(aId: string, bId: string, index: number): number {
|
|
237
|
+
return hashSeed(hashSeed(index + 1, aId.length * 31 + bId.length), 0x1ab);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export interface LabDuel {
|
|
241
|
+
/** LIVE, not run: the caller either ticks it on the combat surface or calls runToEnd. */
|
|
242
|
+
session: CombatSession;
|
|
243
|
+
challengerName: string;
|
|
244
|
+
targetName: string;
|
|
245
|
+
// The two specs and the rng seed, so a caller can rebuild the SAME fight with something changed
|
|
246
|
+
// — the only way to price what a change is worth.
|
|
247
|
+
specs: { challenger: CombatantSpec; target: CombatantSpec; seed: number };
|
|
248
|
+
/** The target's body, for the combat surface's player-shaped foe portrait. */
|
|
249
|
+
opponent: { race: number; cls: number; gender?: 0 | 1; equipped: Companion['equipped'] };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ONE duel, built the one way, so a watched fight is the same fight the table scored. Null when
|
|
253
|
+
// either comp's premade cannot be seated.
|
|
254
|
+
export function buildLabDuel(args: {
|
|
255
|
+
ds: DataStore;
|
|
256
|
+
char: Character;
|
|
257
|
+
a: ArenaComp;
|
|
258
|
+
b: ArenaComp;
|
|
259
|
+
index?: number;
|
|
260
|
+
// Override the seed `index` would derive. Only a caller comparing the SAME seed across two
|
|
261
|
+
// seatings needs it, or a rate difference would be seed variance rather than about the seat.
|
|
262
|
+
seed?: number;
|
|
263
|
+
/** G7's axis. Applied to BOTH seats: an honorable cell owns it, so a win is about the list. */
|
|
264
|
+
loadout?: 'none' | 'kit';
|
|
265
|
+
/**
|
|
266
|
+
* G10: PER-SIDE loadout, which only a DIRTY round may ask for. `loadout` above is the honorable
|
|
267
|
+
* case and stays the default for both seats; these override it one side at a time, and the
|
|
268
|
+
* caller that asks is `duel-bench.mjs` on a cell whose `kind` is `dirty` - where every asymmetry
|
|
269
|
+
* is declared per contender and stamped, so a reader can see what was uneven.
|
|
270
|
+
*/
|
|
271
|
+
loadoutA?: 'none' | 'kit';
|
|
272
|
+
loadoutB?: 'none' | 'kit';
|
|
273
|
+
}): LabDuel | null {
|
|
274
|
+
const { ds, char, a, b } = args;
|
|
275
|
+
const seed = args.seed ?? labSeedFor(a.id, b.id, Math.max(0, Math.trunc(args.index ?? 0)));
|
|
276
|
+
const kitOf = (side?: 'none' | 'kit') => {
|
|
277
|
+
const l = side ?? args.loadout;
|
|
278
|
+
return l ? { loadout: l } : {};
|
|
279
|
+
};
|
|
280
|
+
// G16: each side is told the class across from it, off the comp's own seat 0, so the matchup
|
|
281
|
+
// list is chosen before either body is built. A comp with no seats leaves it absent.
|
|
282
|
+
const vsA = b.seats[0]?.cls;
|
|
283
|
+
const vsB = a.seats[0]?.cls;
|
|
284
|
+
const sa = arenaSeats(ds, char, a, seed,
|
|
285
|
+
{ ...kitOf(args.loadoutA), ...(vsA != null ? { vsClass: vsA } : {}) })[0] ?? null;
|
|
286
|
+
const sb = arenaSeats(ds, char, b, hashSeed(seed, 0x2b),
|
|
287
|
+
{ ...kitOf(args.loadoutB), ...(vsB != null ? { vsClass: vsB } : {}) })[0] ?? null;
|
|
288
|
+
if (!sa || !sb) return null;
|
|
289
|
+
// Yards at t=0, the same call all three LIVE sites make: `battleground.ts:97` (the gauntlet
|
|
290
|
+
// rung a player fights), `:157` (arena 2v2) and `squadDungeon.ts:2519` (the tavern trial). Without
|
|
291
|
+
// positions `createSession` takes its no-geometry path (createSession.ts:222), and
|
|
292
|
+
// `combatSeed.ts:22` says only test fixtures do that — which is what this bench had been.
|
|
293
|
+
// What the fixture shape costs: `inMeleeBand` returns TRUE for self, target and pet with no
|
|
294
|
+
// geometry (rotationSubject.ts:52-55, pickAction.ts:1494-1500), so every `inMelee == 0` gate
|
|
295
|
+
// is unsatisfiable and every `inMelee == 1` gate is free; distances read null
|
|
296
|
+
// (pickAction.ts:1313-1315); nobody moves; and the fight opens inside white-swing range, so
|
|
297
|
+
// no snare, no Charge (rangeMin ~8) and no ranged dead zone can fire.
|
|
298
|
+
|
|
299
|
+
// A hunter or warlock seat fights WITH its pet: the challenger's rides side `pet`, the target's is
|
|
300
|
+
// one more enemy body. Both were already tamed by the seat build and were being dropped here.
|
|
301
|
+
const foeBodies = sb.pet ? [sb.spec, sb.pet] : [sb.spec];
|
|
302
|
+
const geo = seedDuelGeometry({
|
|
303
|
+
player: sa.spec, enemySpecs: foeBodies, includePet: sa.pet != null, spellOf: (id) => ds.spell(id),
|
|
304
|
+
});
|
|
305
|
+
return {
|
|
306
|
+
session: createDuelSession(sa.spec, foeBodies, mulberry32(seed), {
|
|
307
|
+
playerActionProvider: sa.provider,
|
|
308
|
+
// null for a pet: it has no rotation section, so the factory's pet heuristics drive it.
|
|
309
|
+
enemyActionProviders: sb.pet ? [sb.provider, null] : [sb.provider],
|
|
310
|
+
unitPositionsYd: geo.positions,
|
|
311
|
+
geometryAnchor: geo.anchor,
|
|
312
|
+
}, sa.pet),
|
|
313
|
+
challengerName: sa.spec.name,
|
|
314
|
+
targetName: sb.spec.name,
|
|
315
|
+
specs: { challenger: sa.spec, target: sb.spec, seed },
|
|
316
|
+
opponent: {
|
|
317
|
+
race: sb.body.race,
|
|
318
|
+
cls: sb.body.cls,
|
|
319
|
+
...(sb.body.gender != null ? { gender: sb.body.gender } : {}),
|
|
320
|
+
equipped: sb.body.equipped,
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Every ORDERED pair of `comps`, `seeds` duels each. Ordered because the two seats are not
|
|
326
|
+
// symmetric — the opener, stealth seed and geometry all favour one — so collapsing would hide it.
|
|
327
|
+
export function runDuelLab(args: {
|
|
328
|
+
ds: DataStore;
|
|
329
|
+
char: Character;
|
|
330
|
+
/** Default: every authored bracket-1 comp. Pass a tier's slice to keep a run small. */
|
|
331
|
+
comps?: readonly ArenaComp[];
|
|
332
|
+
seeds?: number;
|
|
333
|
+
/** G7's axis. The CELL owns it, so every fighter in a round is measured kitted or dry alike. */
|
|
334
|
+
loadout?: 'none' | 'kit';
|
|
335
|
+
/**
|
|
336
|
+
* G10: one comp's loadout, when a DIRTY round declared it. Absent, or returning null, leaves
|
|
337
|
+
* that comp on the cell's `loadout` - so an honorable round never calls this and every fighter
|
|
338
|
+
* shares one kit rule.
|
|
339
|
+
*/
|
|
340
|
+
loadoutOf?: (compId: string) => 'none' | 'kit' | null | undefined;
|
|
341
|
+
}): LabPairResult[] {
|
|
342
|
+
const { ds, char } = args;
|
|
343
|
+
const comps = args.comps ?? compsForBracket(1);
|
|
344
|
+
const seeds = Math.max(1, Math.trunc(args.seeds ?? LAB_DEFAULT_SEEDS));
|
|
345
|
+
const out: LabPairResult[] = [];
|
|
346
|
+
for (const a of comps) {
|
|
347
|
+
for (const b of comps) {
|
|
348
|
+
// A comp never fights itself in a TABLE — a mirror row scores 100% for whichever seat won.
|
|
349
|
+
// `buildLabDuel` still builds one, which is how repro-duel-seat-gap.mjs isolates the seat.
|
|
350
|
+
if (a.id === b.id) continue;
|
|
351
|
+
let aWins = 0;
|
|
352
|
+
let bWins = 0;
|
|
353
|
+
let draws = 0;
|
|
354
|
+
let duels = 0;
|
|
355
|
+
let totalMs = 0;
|
|
356
|
+
let bodiesA = 0;
|
|
357
|
+
let bodiesB = 0;
|
|
358
|
+
for (let s = 0; s < seeds; s++) {
|
|
359
|
+
// Built through `buildLabDuel`, the same call P7.2's replay makes, so a row is
|
|
360
|
+
// reproducible from (aId, bId, s) alone and a watched fight is THIS fight.
|
|
361
|
+
const la = args.loadoutOf?.(a.id) ?? null;
|
|
362
|
+
const lb = args.loadoutOf?.(b.id) ?? null;
|
|
363
|
+
const d = buildLabDuel({
|
|
364
|
+
ds, char, a, b, index: s,
|
|
365
|
+
...(args.loadout ? { loadout: args.loadout } : {}),
|
|
366
|
+
...(la ? { loadoutA: la } : {}),
|
|
367
|
+
...(lb ? { loadoutB: lb } : {}),
|
|
368
|
+
});
|
|
369
|
+
if (!d) continue;
|
|
370
|
+
bodiesA = 1;
|
|
371
|
+
bodiesB = 1;
|
|
372
|
+
const r = resolveDuelOutcome(d.session.runToEnd(), d.challengerName, d.targetName);
|
|
373
|
+
duels++;
|
|
374
|
+
totalMs += r.durationMs;
|
|
375
|
+
if (r.winner == null) draws++;
|
|
376
|
+
else if (r.winner === d.challengerName) aWins++;
|
|
377
|
+
else bWins++;
|
|
378
|
+
}
|
|
379
|
+
out.push({
|
|
380
|
+
aId: a.id,
|
|
381
|
+
aName: a.name,
|
|
382
|
+
bId: b.id,
|
|
383
|
+
bName: b.name,
|
|
384
|
+
duels,
|
|
385
|
+
aWins,
|
|
386
|
+
bWins,
|
|
387
|
+
draws,
|
|
388
|
+
aWinPct: duels > 0 ? Math.round((aWins / duels) * 100) : 0,
|
|
389
|
+
avgDurationMs: duels > 0 ? Math.round(totalMs / duels) : 0,
|
|
390
|
+
bodiesA,
|
|
391
|
+
bodiesB,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return out;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// The rows as a fixed-width table, strongest challenger first. `chal win%` is ONE SEAT and the
|
|
399
|
+
// header says so — the player seat wins about 78% of a mirror. `labQueueTable` is the balanced view.
|
|
400
|
+
export function labTable(rows: readonly LabPairResult[]): string {
|
|
401
|
+
const sorted = [...rows].sort((x, y) => y.aWinPct - x.aWinPct);
|
|
402
|
+
const head = 'challenger vs target W-L-D chal win% avg s';
|
|
403
|
+
const lines = sorted.map((r) => {
|
|
404
|
+
const a = r.aName.slice(0, 30).padEnd(30);
|
|
405
|
+
const b = r.bName.slice(0, 30).padEnd(30);
|
|
406
|
+
const wld = `${r.aWins}-${r.bWins}-${r.draws}`.padEnd(8);
|
|
407
|
+
const pct = `${r.aWinPct}%`.padStart(5);
|
|
408
|
+
const secs = (r.avgDurationMs / 1000).toFixed(1).padStart(7);
|
|
409
|
+
return `${a} ${b} ${wld} ${pct} ${secs}`;
|
|
410
|
+
});
|
|
411
|
+
return [head, ...lines].join('\n');
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// ---- P7.3: the table as an authoring queue ---------------------------------------------
|
|
415
|
+
|
|
416
|
+
export interface LabStanding {
|
|
417
|
+
compId: string;
|
|
418
|
+
name: string;
|
|
419
|
+
tier: string;
|
|
420
|
+
/** Duels as the challenger (`player` seat) and as the target (`enemy` seat). */
|
|
421
|
+
asChallenger: { duels: number; wins: number; pct: number };
|
|
422
|
+
asTarget: { duels: number; wins: number; pct: number };
|
|
423
|
+
duels: number;
|
|
424
|
+
wins: number;
|
|
425
|
+
draws: number;
|
|
426
|
+
/** Wins over duels across BOTH seats, 0 when none ran. */
|
|
427
|
+
pct: number;
|
|
428
|
+
/** `asChallenger.pct - asTarget.pct`. A large gap is a seat artefact, not a comp result. */
|
|
429
|
+
seatGap: number;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// Per-comp record across every row it appears in, BOTH seats — the lab's first run proved the seat
|
|
433
|
+
// can decide a fight outright, so a one-seat standing would report that artefact as skill.
|
|
434
|
+
export function labStandings(
|
|
435
|
+
rows: readonly LabPairResult[],
|
|
436
|
+
tierOf: (compId: string) => string = () => '',
|
|
437
|
+
): LabStanding[] {
|
|
438
|
+
const by = new Map<string, LabStanding>();
|
|
439
|
+
const get = (id: string, name: string): LabStanding => {
|
|
440
|
+
let s = by.get(id);
|
|
441
|
+
if (!s) {
|
|
442
|
+
s = {
|
|
443
|
+
compId: id,
|
|
444
|
+
name,
|
|
445
|
+
tier: tierOf(id),
|
|
446
|
+
asChallenger: { duels: 0, wins: 0, pct: 0 },
|
|
447
|
+
asTarget: { duels: 0, wins: 0, pct: 0 },
|
|
448
|
+
duels: 0,
|
|
449
|
+
wins: 0,
|
|
450
|
+
draws: 0,
|
|
451
|
+
pct: 0,
|
|
452
|
+
seatGap: 0,
|
|
453
|
+
};
|
|
454
|
+
by.set(id, s);
|
|
455
|
+
}
|
|
456
|
+
return s;
|
|
457
|
+
};
|
|
458
|
+
for (const r of rows) {
|
|
459
|
+
if (r.duels <= 0) continue;
|
|
460
|
+
const a = get(r.aId, r.aName);
|
|
461
|
+
a.asChallenger.duels += r.duels;
|
|
462
|
+
a.asChallenger.wins += r.aWins;
|
|
463
|
+
a.duels += r.duels;
|
|
464
|
+
a.wins += r.aWins;
|
|
465
|
+
a.draws += r.draws;
|
|
466
|
+
const b = get(r.bId, r.bName);
|
|
467
|
+
b.asTarget.duels += r.duels;
|
|
468
|
+
b.asTarget.wins += r.bWins;
|
|
469
|
+
b.duels += r.duels;
|
|
470
|
+
b.wins += r.bWins;
|
|
471
|
+
b.draws += r.draws;
|
|
472
|
+
}
|
|
473
|
+
const pct = (w: number, d: number): number => (d > 0 ? Math.round((w / d) * 100) : 0);
|
|
474
|
+
const out = [...by.values()];
|
|
475
|
+
for (const s of out) {
|
|
476
|
+
s.asChallenger.pct = pct(s.asChallenger.wins, s.asChallenger.duels);
|
|
477
|
+
s.asTarget.pct = pct(s.asTarget.wins, s.asTarget.duels);
|
|
478
|
+
s.pct = pct(s.wins, s.duels);
|
|
479
|
+
s.seatGap = s.asChallenger.pct - s.asTarget.pct;
|
|
480
|
+
}
|
|
481
|
+
// Worst first: this list IS the authoring queue, so the comp that needs work is at the top.
|
|
482
|
+
return out.sort((x, y) => x.pct - y.pct || y.seatGap - x.seatGap);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/** Comps under `pct`, worst first — the P4/P5 authoring queue. */
|
|
486
|
+
export function labQueue(standings: readonly LabStanding[], pct = 40): LabStanding[] {
|
|
487
|
+
return standings.filter((s) => s.duels > 0 && s.pct < pct);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/** The queue as a fixed-width table. For the dev console. */
|
|
491
|
+
export function labQueueTable(standings: readonly LabStanding[]): string {
|
|
492
|
+
const head = 'comp tier W-D-L win% chal% targ% seat gap';
|
|
493
|
+
const lines = standings.map((s) => {
|
|
494
|
+
const losses = s.duels - s.wins - s.draws;
|
|
495
|
+
return [
|
|
496
|
+
s.name.slice(0, 30).padEnd(30),
|
|
497
|
+
(s.tier || '-').padEnd(9),
|
|
498
|
+
`${s.wins}-${s.draws}-${losses}`.padEnd(10),
|
|
499
|
+
`${s.pct}%`.padStart(5),
|
|
500
|
+
`${s.asChallenger.pct}%`.padStart(6),
|
|
501
|
+
`${s.asTarget.pct}%`.padStart(6),
|
|
502
|
+
`${s.seatGap >= 0 ? '+' : ''}${s.seatGap}`.padStart(10),
|
|
503
|
+
].join(' ');
|
|
504
|
+
});
|
|
505
|
+
return [head, ...lines].join('\n');
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// ---- G6: the team bench (2v2 / 3v3 / 5v5) ---------------------------------------------
|
|
509
|
+
|
|
510
|
+
export interface TeamMatch {
|
|
511
|
+
/** LIVE, not run: the caller ticks it or calls runToEnd. */
|
|
512
|
+
session: CombatSession;
|
|
513
|
+
aName: string;
|
|
514
|
+
bName: string;
|
|
515
|
+
/** Every body on each side, in comp-seat order, so a caller can name who actually fought. */
|
|
516
|
+
seats: { a: CombatantSpec[]; b: CombatantSpec[] };
|
|
517
|
+
seed: number;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* ONE team match, built the one way, and it is `game.arenaMatch`'s construction with comp bodies
|
|
522
|
+
* on both sides instead of the character and its squad (`battleground.ts:157-174`, pvp plan P6.5).
|
|
523
|
+
*
|
|
524
|
+
* Deliberately NOT a new path: §8.7 is what a novel construction costs - the lab's first version
|
|
525
|
+
* seated no brain on the `enemy` side and read the resulting sweep as a comp result. So the lead
|
|
526
|
+
* seat goes where the player goes and gets a `playerActionProvider` the way `buildLabDuel` gives
|
|
527
|
+
* one, the rest of its comp are allies with `allyActionProviders`, and the other comp fills the
|
|
528
|
+
* enemies with `enemyActionProviders`.
|
|
529
|
+
*
|
|
530
|
+
* NO `duel: true`. An arena is decided by ELIMINATION and a duel is not - the duel flag floors the
|
|
531
|
+
* loser at 1 HP (`duel.ts:126`) - which is the one thing that must differ from `buildLabDuel`
|
|
532
|
+
* (`repro-arena-elimination.mjs`: "ELIMINATION DECIDES IT, at every bracket").
|
|
533
|
+
*
|
|
534
|
+
* Null when either comp cannot be seated whole, which `seatsAreTheComp` already decides: a comp
|
|
535
|
+
* the faction pool cannot field comes back as random pvp bots wearing its name, and a standing
|
|
536
|
+
* built on that is fiction.
|
|
537
|
+
*/
|
|
538
|
+
export function buildTeamMatch(args: {
|
|
539
|
+
ds: DataStore;
|
|
540
|
+
char: Character;
|
|
541
|
+
a: ArenaComp;
|
|
542
|
+
b: ArenaComp;
|
|
543
|
+
index?: number;
|
|
544
|
+
/** Hold the fight fixed and vary only the seating - the paired test §8.7 needs. */
|
|
545
|
+
seed?: number;
|
|
546
|
+
/** G7's axis, applied to every seat on both sides. */
|
|
547
|
+
loadout?: 'none' | 'kit';
|
|
548
|
+
/** G10's per-side override, a DIRTY round only - the same two fields `buildLabDuel` takes. */
|
|
549
|
+
loadoutA?: 'none' | 'kit';
|
|
550
|
+
loadoutB?: 'none' | 'kit';
|
|
551
|
+
/** DEV: a Map to receive each seat's last rotation snapshot (types.ts `snapshotCapture`). */
|
|
552
|
+
snapshotCapture?: Map<string, unknown>;
|
|
553
|
+
}): TeamMatch | null {
|
|
554
|
+
const { ds, char, a, b } = args;
|
|
555
|
+
const seed = args.seed ?? labSeedFor(a.id, b.id, Math.max(0, Math.trunc(args.index ?? 0)));
|
|
556
|
+
const opts = (comp: ArenaComp, side?: 'none' | 'kit') => {
|
|
557
|
+
const l = side ?? args.loadout;
|
|
558
|
+
return {
|
|
559
|
+
teamSize: comp.seats.length,
|
|
560
|
+
tier: comp.tier,
|
|
561
|
+
otherFactionIfUnseatable: true,
|
|
562
|
+
...(l ? { loadout: l } : {}),
|
|
563
|
+
};
|
|
564
|
+
};
|
|
565
|
+
const sa = arenaSeats(ds, char, a, seed, opts(a, args.loadoutA));
|
|
566
|
+
const sb = arenaSeats(ds, char, b, hashSeed(seed, 0x2b), opts(b, args.loadoutB));
|
|
567
|
+
if (sa.length !== a.seats.length || sb.length !== b.seats.length) return null;
|
|
568
|
+
const [lead, ...mates] = sa;
|
|
569
|
+
if (!lead) return null;
|
|
570
|
+
// Pets ride AFTER the humans on their own side, so ally_0..n-1 and enemy_0..n-1 stay 1:1 with the
|
|
571
|
+
// seats a caller named (bgScreen.ts:366-419). The lead's own pet takes side `pet`.
|
|
572
|
+
const petsOf = (rows: readonly { pet: CombatantSpec | null }[]): CombatantSpec[] =>
|
|
573
|
+
rows.map((s) => s.pet).filter((p): p is CombatantSpec => p != null);
|
|
574
|
+
const mateSpecs = [...mates.map((s) => s.spec), ...petsOf(mates)];
|
|
575
|
+
const foeSpecs = [...sb.map((s) => s.spec), ...petsOf(sb)];
|
|
576
|
+
const geo = seedDuelGeometry({
|
|
577
|
+
player: lead.spec,
|
|
578
|
+
enemySpecs: foeSpecs,
|
|
579
|
+
allySpecs: mateSpecs,
|
|
580
|
+
includePet: lead.pet != null,
|
|
581
|
+
// Both sides are TEAMS here, so side B is seeded by the party's own formation mirrored rather
|
|
582
|
+
// than as a mob pack. Without it side A won 20/20 mirrors (repro-arena-seat-gap.mjs).
|
|
583
|
+
enemyIsATeam: true,
|
|
584
|
+
spellOf: (id) => ds.spell(id),
|
|
585
|
+
});
|
|
586
|
+
return {
|
|
587
|
+
session: createSession(lead.spec, foeSpecs, mulberry32(seed), {
|
|
588
|
+
playerActionProvider: lead.provider,
|
|
589
|
+
// null per pet body: pets have no rotation section, so the pet heuristics drive them.
|
|
590
|
+
allyActionProviders: [
|
|
591
|
+
...mates.map((s) => s.provider),
|
|
592
|
+
...mateSpecs.slice(mates.length).map(() => null),
|
|
593
|
+
],
|
|
594
|
+
enemyActionProviders: [
|
|
595
|
+
...sb.map((s) => s.provider),
|
|
596
|
+
...foeSpecs.slice(sb.length).map(() => null),
|
|
597
|
+
],
|
|
598
|
+
unitPositionsYd: geo.positions,
|
|
599
|
+
geometryAnchor: geo.anchor,
|
|
600
|
+
// Side B is a TEAM of player seats, so it picks targets like a player faction rather than
|
|
601
|
+
// off a creature threat list (sessionFocus hostileTargetOf).
|
|
602
|
+
enemiesAreATeam: true,
|
|
603
|
+
...(args.snapshotCapture ? { snapshotCapture: args.snapshotCapture } : {}),
|
|
604
|
+
}, lead.pet, mateSpecs.length ? mateSpecs : null),
|
|
605
|
+
aName: a.name,
|
|
606
|
+
bName: b.name,
|
|
607
|
+
seats: { a: sa.map((s) => s.spec), b: sb.map((s) => s.spec) },
|
|
608
|
+
seed,
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Every ORDERED pair of team comps, `seeds` matches each. Rows are `LabPairResult`, so
|
|
614
|
+
* `labStandings` and `labQueue` score a team bracket with no second copy of that arithmetic
|
|
615
|
+
* (duel plan §G6: "Standings reuse `labStandings` as-is - it keys on comp ids").
|
|
616
|
+
*
|
|
617
|
+
* Ordered for the same reason `runDuelLab` is: the lead seat is the `player` side and the two
|
|
618
|
+
* sides are not symmetric, so collapsing a pair would hide the seat. And `seatGap` off these rows
|
|
619
|
+
* carries the same caveat as a duel round's - the two directions are different fights (plan §2).
|
|
620
|
+
*/
|
|
621
|
+
export function runTeamLab(args: {
|
|
622
|
+
ds: DataStore;
|
|
623
|
+
char: Character;
|
|
624
|
+
/** Default: every authored comp of `bracket`. */
|
|
625
|
+
comps?: readonly ArenaComp[];
|
|
626
|
+
bracket?: ArenaBracket;
|
|
627
|
+
seeds?: number;
|
|
628
|
+
/** G7's axis. The CELL owns it. */
|
|
629
|
+
loadout?: 'none' | 'kit';
|
|
630
|
+
/** G10: one comp's declared loadout in a DIRTY round, the same hook `runDuelLab` takes. */
|
|
631
|
+
loadoutOf?: (compId: string) => 'none' | 'kit' | null | undefined;
|
|
632
|
+
}): LabPairResult[] {
|
|
633
|
+
const { ds, char } = args;
|
|
634
|
+
// Default is ONE tier's worth: the bracket is derived at all five (arenaComps.ts perTier), so the
|
|
635
|
+
// whole bracket is 35 comps and an all-pairs bench of it is 1,190 matches per seed.
|
|
636
|
+
const comps = args.comps
|
|
637
|
+
?? compsForBracket(args.bracket ?? 2).filter((c) => c.tier === DEFAULT_BG_TIER);
|
|
638
|
+
const seeds = Math.max(1, Math.trunc(args.seeds ?? LAB_DEFAULT_SEEDS));
|
|
639
|
+
const out: LabPairResult[] = [];
|
|
640
|
+
for (const a of comps) {
|
|
641
|
+
for (const b of comps) {
|
|
642
|
+
if (a.id === b.id) continue;
|
|
643
|
+
let aWins = 0;
|
|
644
|
+
let bWins = 0;
|
|
645
|
+
let draws = 0;
|
|
646
|
+
let duels = 0;
|
|
647
|
+
let totalMs = 0;
|
|
648
|
+
let bodiesA = 0;
|
|
649
|
+
let bodiesB = 0;
|
|
650
|
+
for (let s = 0; s < seeds; s++) {
|
|
651
|
+
const la = args.loadoutOf?.(a.id) ?? null;
|
|
652
|
+
const lb = args.loadoutOf?.(b.id) ?? null;
|
|
653
|
+
const m = buildTeamMatch({
|
|
654
|
+
ds, char, a, b, index: s,
|
|
655
|
+
...(args.loadout ? { loadout: args.loadout } : {}),
|
|
656
|
+
...(la ? { loadoutA: la } : {}),
|
|
657
|
+
...(lb ? { loadoutB: lb } : {}),
|
|
658
|
+
});
|
|
659
|
+
if (!m) continue;
|
|
660
|
+
bodiesA = m.seats.a.length;
|
|
661
|
+
bodiesB = m.seats.b.length;
|
|
662
|
+
const r = m.session.runToEnd();
|
|
663
|
+
duels++;
|
|
664
|
+
totalMs += r.durationMs;
|
|
665
|
+
if (r.winner === 'player') aWins++;
|
|
666
|
+
else if (r.winner === 'enemy') bWins++;
|
|
667
|
+
else draws++;
|
|
668
|
+
}
|
|
669
|
+
out.push({
|
|
670
|
+
aId: a.id,
|
|
671
|
+
aName: a.name,
|
|
672
|
+
bId: b.id,
|
|
673
|
+
bName: b.name,
|
|
674
|
+
duels,
|
|
675
|
+
aWins,
|
|
676
|
+
bWins,
|
|
677
|
+
draws,
|
|
678
|
+
aWinPct: duels > 0 ? Math.round((aWins / duels) * 100) : 0,
|
|
679
|
+
avgDurationMs: duels > 0 ? Math.round(totalMs / duels) : 0,
|
|
680
|
+
bodiesA,
|
|
681
|
+
bodiesB,
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return out;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// The bench's bracket fork, in ONE place: 1 is a DUEL, 2/3/5 an ELIMINATION team match (plan §W1).
|
|
689
|
+
// Routed back through `runDuelLab` a team bracket seats `arenaSeats(...)[0]` alone — `bodiesA` says so.
|
|
690
|
+
export function runLabForBracket(
|
|
691
|
+
bracket: ArenaBracket,
|
|
692
|
+
args: Parameters<typeof runTeamLab>[0],
|
|
693
|
+
): LabPairResult[] {
|
|
694
|
+
return bracket === 1 ? runDuelLab(args) : runTeamLab({ ...args, bracket });
|
|
695
|
+
}
|