Aq40 raid strategy module and encounter logic#2252
Draft
RovxBot wants to merge 53 commits intomod-playerbots:test-stagingfrom
Draft
Aq40 raid strategy module and encounter logic#2252RovxBot wants to merge 53 commits intomod-playerbots:test-stagingfrom
RovxBot wants to merge 53 commits intomod-playerbots:test-stagingfrom
Conversation
Master update from Test-staging: Fix ObjectAccessor retrieval, optimize EquipActions, and implement RaidBossHelpers
This reverts commit c86032f.
Master update from Test staging
Update master from Test staging and Core Update
Test staging to master
Test staging to master
Author
AQ40 Trash
The Prophet Skeram
Battleguard Sartura
Bug Trio
Fankriss the Unyielding
Princess Huhuran
Twin Emperors (In progress)
Ouro (not tested)
Viscidus
C'Thun (not tested)
|
Flee corrections Tank staging corrections
The ChooseTarget early-out check required both current target AND GetVictim() to match before returning false (no-op). For melee bots that had their target set but hadn't reached melee range yet, GetVictim() returned nullptr — so Attack() re-fired every tick, consuming the engine's single action slot and permanently blocking reach-melee from running. Remove the GetVictim() requirement so the action returns false once the target is already set, allowing lower-priority movement actions (reach melee at ACTION_HIGH+1) to execute and walk the bot into range. Fixed in Aq40TrashChooseTargetAction, Aq40SarturaChooseTargetAction, and Aq40FankrissChooseTargetAction.
The Aq40TwinEmperorsMultiplier guard used IsTwinRaidCombatActive() as a fallback, which returns true whenever ANY group member is fighting inside the 150-yard twin room bounds. During trash packs near the Twin Emperors room this made the multiplier activate even though the actual Twin Emperor bosses were never engaged. Once active, the multiplier zeroed out reach-melee, dps-assist, charge, set-behind, combat-formation-move, tank-assist, and follow — leaving melee bots standing at range with 'no actions executed' every tick. Fix: remove the twinCombatActive fallback from the guard. The multiplier now only activates when Emperor Vek'nilash or Emperor Vek'lor are actually present in GetTwinEncounterUnits(), which already enriches the attackers list with visible twins from possible-targets-no-los. During the real Twin Emps fight the bosses stay on the threat table through teleports, so they remain detectable in activeUnits without needing the room-combat heuristic.
… Flay and Thunderclap - Replace broad GetAq40TrashDanger with role-aware IsAq40TrashMovementCase - Remove Eradicator Shock Blast and Warder Fire Nova from trash movement - Keep only Defender Thunderclap (24y) and Mindslayer Mind Flay (30y) - Gate trash AoE avoidance on ranged/healer role; melee stay on target - Replace MoveAway with tank-anchored ComputeTankRetreatPosition helper to prevent bots fleeing deeper into uncleared rooms - Allow ranged/healers with Defender Plague to keep casting/healing when already at safe separation distance instead of idling - Plague separation, Mindslayer interrupt/retarget, and Cause Insanity CC paths remain unchanged
- Remove warlock tank skip in IsTwinAssignedTankReady so healers position within range during pull instead of waiting 62y away - Change EnforceSeparation collision fallback to MoveAway(otherBoss) instead of MoveTo(desiredBoss) to actively push bosses apart - Add angle retry loop (±0.3/±0.6 rad) in GetTwinFarSidePosition before returning false on collision near walls - Prioritize Shadow Ward over Curse of Doom in WarlockTankAction - Grant free Prayer of Shadow Protection (+70 SR) to all warlocks during Twin Emperors via the resistance management system
…strategy - Warlock tank isUseful() now mirrors Execute()'s safety net, allowing Searing Pain threat when Vek'lor is reachable but sideEmperor mapping disagrees after a teleport swap - HoldSplit early-out when wanted boss is already in engage range, closing the 1-2 tick idle gap after teleport - HoldSplit returns false at anchor to free action slot for utility (Shadow Ward, healthstone) while waiting for teleport - Separation triggers and action use role-based boss matching (warlock->Vek'lor, melee->Vek'nilash) instead of IsTwinPrimaryTankOnActiveBoss, fixing the post-swap blind spot where neither tank enforced separation - Separation trigger gate changed from && to || so tanks don't try to enforce separation on a boss that is out of LOS or beyond 45y - Melee DPS positions near Vek'nilash during pre-teleport staging instead of running to room centre for zero damage - ShouldReserveForTwinBug uses proximity-based IsLikelyOnSameTwinSide instead of sideEmperor pointer comparison to avoid false positives during teleport windows - Blizzard trigger radius tightened from 36y to 28y to match actual effect radius, preventing movement suppression across the entire Vek'lor side - Blizzard avoidance trigger and action check aura presence first, bypassing stale sideEmperor mapping so bots dodge even during teleport transitions
Overwrite all src/Ai/Raid/Aq40/ files on AQ40 branch with the exact versions from master so the PR branch matches the development branch.
…overy Implement Twin Emperors encounter as a five-state machine: PrePullStage, OpenerHold, SteadySplit, PreTeleportStage, TeleportRecovery. Key changes: - Tanks stay on their side after teleport; far-side tanks hold position while same-side tanks engage the boss that teleported in - ChooseTarget guards against cross-room chasing during recovery by checking IsLikelyOnSameTwinSide before moving toward a boss - HoldSplit uses same-side proximity check instead of tight distance thresholds to decide when to yield to engage vs hold at anchor - Pickup establishment checks (warlock + melee) bypass stale side-index filtering and check all designated tanks against boss identity directly - Melee tank pickup max range widened 10y -> 15y for Uppercut knockback tolerance; outer-anchor dot-product relaxed at close range - Pre-pull staging uses 1200ms retry throttle and collision-aware fallback with 7 angle offsets - Pre-teleport staging suppressed during recovery or unhealthy encounter - DPS suppressed during OpenerHold and TeleportRecovery until both side tanks are established - Multiplier correctly boosts warlock tank (2.8), hold split (2.4), and choose target (2.1) during recovery windows
- HoldSplitAction never returns false during active combat; falls back to room-center waypoint with 1200ms retry throttle to prevent dead state - Reorder role mismatch trigger: hold-split now runs at higher priority than choose-target so positioning fires before target pinning - Identity-based sideEmperor for tanks: warlock tank always assigned Vek'lor, melee tank always assigned Vek'nilash regardless of room-side mapping, eliminating post-teleport oscillation - MoveAwayFromBrother returns true when already 55y+ from aggro'd boss, preventing EMERGENCY trigger from endlessly consuming ticks
…, warlock pickup speed - Add isTankBackup flag to TwinAssignments so backup tanks (warlock mod-playerbots#2, off-tank) stage on the opposite room-side from their boss, ready for immediate pickup after teleport swaps - Add isUseful() to Aq40EraseTimersAndTrackersAction and IsAlive() guard to trigger, preventing priority-91 cleanup from blocking AI ticks - Reorder warlock tank pickup: Searing Pain first when in range for faster threat, Shadow Ward deferred or cast during repositioning
…nd tank far-side chase Phase 1 - Race condition fix: - Add IsAnyGroupMemberInTwinRoom() helper to check if any group member is inside the Twin Emperors room bounds - Guard GetStableTwinRoleIndex() cache wipe: don't erase instance-level caches (sTwinAssignments, sCachedTwinSplitByX, sTwinSideZeroIsLowSide, sTwinKnownTwinBosses) when any group member is in the twin room - Guard ShouldRunOutOfCombatMaintenance(): return false while any group member is in the twin room, preventing erase-timers trigger from firing - Guard ResetEncounterState() in EraseTimersAndTrackersAction::Execute(): skip encounter state wipe when group members are staging Phase 2 - Tank far-side chase fix: - WarlockTankAction::Execute(): during pickup hold states, if Vek'lor is on the far side of the room, hold position and pre-cast Shadow Ward instead of chasing across the room - HoldSplitAction::Execute(): when a tank's designated boss is on the far side and out of range/LOS, stop attack and hold instead of MoveNear chase Phase 3 - Dead code removal: - Remove unused GetTwinBossSideIndex() from anonymous namespace
- ChooseTarget now handles movement to range on every tick instead of returning false when already on correct target. DPS will actually move to their boss and attack. - Hunters prioritize mutate bugs before their normal target. - Multiplier now suppresses FollowAction during combat (was only suppressed during pre-pull), fixing tank oscillation back to player. - Removed ReachTarget suppression so class AI can move bots to range. - Removed isUseful() heal filter from ChooseTarget (handled in Execute). - HoldSplit now properly pins and engages for primary melee tank, and pre-casts Shadow Ward for backup warlock tanks.
… and skull marker Phase 4 - Fix post-Skeram stuck state: - Remove side-effect in GetObservedSkeramEncounterUnits() that erased sSkeramPostBlinkHoldUntilByInstance from within a getter, causing a race condition between trigger and action evaluation. The cleanup path in ShouldRunOutOfCombatMaintenance() already handles this correctly. Phase 1 - Add trash target distance cap: - FindTrashTarget() now pre-filters attackers by 45y distance before iterating priority tiers. Falls back to closest active combat unit if no priority target is within range. Prevents bots running past nearby mobs to chase distant priority targets. Phase 2 - Prevent Skeram body-pull during trash: - Aq40SkeramMultiplier suppresses Skeram-specific actions (0.0x) when trash is still active alongside Skeram, so bots finish trash first. Phase 3 - Skull marker for real Skeram: - Tank marks real Skeram with skull icon (matching Bug Trio pattern). - FindSkeramTarget() checks skull target first before aggro-based sort. - Non-tanks skip tank-aggro prerequisite when skull marker exists, reducing focus-real-boss failures after blinks.
…vement robustness - Warlock tank: add 45y distance override to bypass broken IsLikelyOnSameTwinSide check from room center (was off by 0.56y, trapping warlock in far-side hold) - Warlock tank: suppress offensive class AI spells (Corruption/CoA/Shadow Bolt/etc) via multiplier so Searing Pain threat rotation isn't overridden - Healers: position 28y from assigned side boss (outside 18y Arcane Burst, within 40y heal range) instead of staying at lethal room center - Movement: all MoveNear/MoveTo calls return true while bot is still en route, preventing 'no actions executed' spam from IsDuplicateMove dedup - Follow: suppress in entire Twin room (IsInTwinEmperorRoom) not just when IsTwinPrePullReady is true, fixing pre-pull oscillation - RTI: mark bosses Diamond (Vek'nilash) / Square (Vek'lor) during pre-pull, SetRtiTarget per DPS bot for base AI integration
- Follow suppression: revert to IsTwinPrePullReady gate (LOS to bosses required) so bots can still follow through the corridor. The 150y IsInTwinEmperorRoom radius was catching bots in the hallway. - GetTwinSideAnchor: stage 40y from boss toward room center instead of at the boss spawn position. Prevents early aggro during pre-pull. - WarlockTankAction: when far from Vek'lor, MoveNear directly instead of pathing to far-side anchor (which sent warlock toward the wall). Far-side anchor only used for backing away (too close) and soft reposition between casts.
Fix 1 - WarlockTankAction cast-first priority: Restructure Execute() so that threat generation (Searing Pain) fires BEFORE repositioning whenever the warlock is within 30y with LOS. Widen safe casting range from 21-30y to 15-30y (just outside 18y Arcane Burst). The old 9y window caused movement oscillation that prevented any casts from firing. Fix 2 - Pre-pull boss marking: PrePullStageAction marking code now falls back to HasTwinVisibleEmperors when GetTwinEncounterUnits returns empty (which it always does during pre-pull since the attackers list is empty before combat). Export HasTwinVisibleEmperors in the header. Note: backup tank promotion was removed — tanks stay on their assigned side permanently. Each side has one warlock + one melee tank. The backup picks up after teleport, not after the other tank dies.
Fix 1 - Healer positioning oscillation: Replace MoveNear(healBoss, 28y) with MoveTo(exact far-side position). MoveNear picks a random angle around the boss, which rarely matches the GetFarSidePosition check point. The healer oscillated between 'moving' and 'almost in position' every tick, returning true each time and consuming the action slot — preventing any heals from firing. Now healers move to the exact computed safe position and use 8y tolerance to stay put once arrived. Fix 2 - Warlock tank GCD gap: When Searing Pain is on GCD, the cast-first block now returns true immediately (holding the action slot) instead of falling through to the positioning code. Previously, GCD ticks would fall through to soft-reposition → return true without casting, creating 41-second gaps where the warlock was alive and in range but not casting. Now the only movement during GCD is retreat if too close (<15y). Fix 3 - Shadow Ward during approach: Re-add Shadow Ward pre-cast while moving toward Vek'lor from >30y.
…s/pets
Phase 1: Fix warlock side assignment after death/resurrection.
- GetStableTwinRoleIndex now uses side-aware assignment instead of
slot-counting. When a warlock returns from death, they get assigned
to the first unoccupied side, preventing both warlocks on same side.
Phase 2: Melee tank drags Vek'nilash away from Vek'lor.
- HoldSplitAction primary melee tank uses GetFarSidePosition to tank
on the far side of Vek'nilash from Vek'lor. This naturally pulls
Vek'nilash away, preventing Heal Brother (17 clusters in test 4).
Phase 3: Hunter targeting expanded to prioritize Explode Bugs first,
then Mutate Bugs. Hunter fallback target changed from Vek'lor to
Vek'nilash (physical damage is IMMUNE on Vek'lor).
Phase 4: Hunter pet redirection. ChooseTargetAction now redirects
hunter pets to the hunter's target, preventing IMMUNE spam on Vek'lor
and reducing Shadow Bolt aggro from pets.
Phase 5: Warlock staging distance reduced from 40y to 28y so warlocks
start within Searing Pain range on pull (fixes 31s engagement delay).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Description
This PR adds playerbot strategies for all AQ40 bosses, and some of the tougher trash. I will go through each boss strategy in a comment below.
Feature Evaluation
The main costs are:
How to Test the Changes
Go to AQ40 with bots and run the raid. Twin emps will require warlock tanks
Impact Assessment
The AQ40 logic does increase per-bot/per-tick work a little, because each bot does extra encounter-unit scans, role checks, and positioning/target evaluations during AQ40 fights. But it is scoped to raid encounters, and the unit sets involved are small enough that this should not scale badly in normal use.
Does this change modify default bot behavior?
Yes. This work intentionally changes default bot behavior inside AQ40 raid encounters.
Encounter-specific logic overrides default targeting, movement, spacing, add handling, interrupts, and temporary hold behavior.
Does this change add new decision branches or increase maintenance complexity?
Each AQ40 boss now has encounter-specific branching for role, phase, target type, aggro state, and positional safety.
Shared helpers, triggers, actions, and multipliers all have to stay aligned, so changes in one area can affect encounter behavior elsewhere.
Fights like Twin Emperors and C'Thun especially add recovery and edge-case logic, which is harder to maintain than simple target selection.
Messages to Translate
AI Assistance
I used GPT-5.4 for codebase review, strategy analysis, debugging, and code generation while implementing the AQ40 playerbot strategies.
Because I am not a C++ developer, implementation code was AI-generated, but I reviewed the outputs, tested changes incrementally, and adjusted them to stay consistent with existing playerbot strategy patterns and encounter behavior.
Final Checklist
Notes for Reviewers
This strategy is currently under development, and AQ40 is still not fully clearable. I have been able to get boss strategies working for bosses up to Twin emps, as well as all the harder trash logic.
Twin emps logic is starting to come together and I have been having better pulls now but it still needs work.
Trash after Twin emps is nightmare fuel, and Cthun has not been tested at all yet.
I am looking for some help and guidance from people far smarter than myself when it comes to this kind of thing.
Thank you!