From ab196cb532b2b939a25040f96d5653f6dfd58c4c Mon Sep 17 00:00:00 2001 From: HennyWilly <5954598+HennyWilly@users.noreply.github.com> Date: Sat, 23 May 2026 04:23:49 +0200 Subject: [PATCH] Refactoring of BWL strategy (#2397) ## Pull Request Description This PR refactors the Blackwing Lair strategy to align with newer raid strategy implementations. It extracts repeated Blackwing Lair spell IDs, game object IDs, and suppression device checks into a shared helper, so the action and trigger code use the same centralized definitions instead of duplicating literals and condition chains. No gameplay behavior changes are expected. This PR is intended as a base for follow-up PRs that introduce additional boss-specific strategy logic. ## Feature Evaluation - Describe the **minimum logic** required to achieve the intended behavior. - Move existing BWL-specific constants and the suppression device condition into a shared helper. - Keep all existing trigger names, action names, spell IDs, game object IDs, and condition checks unchanged. - Update the affected action/trigger implementations to call the helper instead of duplicating the same logic inline. - Describe the **processing cost** when this logic executes across many bots. - No meaningful increase. The logic executed per bot remains effectively the same. - This refactor only replaces duplicated inline checks with a shared helper function and named constants. - There are no additional scans, branches, state tracking, or new decision loops. ## How to Test the Changes Run the Blackwing Lair raid and check if the already implemented features still work: - _Onyxia Scale Cloak handling_: Confirm the bot still applies/checks the same aura as before. - _Suppression device handling_: Confirm bots still detect nearby active suppression devices and turn them off under the same conditions as before. - _Chromaggus bronze affliction handling_: Confirm bots still use Hourglass Sand if they have the bronze affliction. ## Impact Assessment - Does this change increase per-bot/per-tick processing or risk scaling poorly with thousands of bots? - - [ ] No, not at all - - [x] Minimal impact (**explain below**) - - [ ] Moderate impact (**explain below**) A small helper call was introduced for the suppression device check, so there is technically a minor additional call overhead compared to the previous inline condition. In practice, the executed logic, iteration scope, and decision flow remain unchanged, so the impact is negligible and does not introduce meaningful scaling risk. - Does this change modify default bot behavior? - - [x] No - - [ ] Yes (**explain why**) - Does this change add new decision branches or increase maintenance complexity? - - [x] No - - [ ] Yes (**explain below**) ## AI Assistance Was AI assistance used while working on this change? - - [ ] No - - [x] Yes (**explain below**) AI was used for review support and drafting the pull request text. The refactoring itself was done manually. ## Final Checklist - - [x] Stability is not compromised. - - [x] Performance impact is understood, tested, and acceptable. - - [x] Added logic complexity is justified and explained. - - [x] Any new bot dialogue lines are translated. - - [x] Documentation updated if needed (Conf comments, WiKi commands). ## Notes for Reviewers This PR is intended to be behavior-preserving only. The main change is consolidation of repeated Blackwing Lair constants and suppression device logic into a shared helper used by both actions and triggers. Review can focus on verifying that the extracted helper matches the previous conditions. --- .../BlackwingLair/Action/RaidBwlActions.cpp | 27 +++++++++++-------- .../BlackwingLair/Action/RaidBwlActions.h | 9 +++---- .../Strategy/RaidBwlStrategy.cpp | 14 +++++----- .../BlackwingLair/Strategy/RaidBwlStrategy.h | 6 ++--- .../BlackwingLair/Trigger/RaidBwlTriggers.cpp | 27 +++++++++++-------- .../BlackwingLair/Trigger/RaidBwlTriggers.h | 6 +++-- .../BlackwingLair/Util/RaidBwlHelpers.cpp | 12 +++++++++ .../Raid/BlackwingLair/Util/RaidBwlHelpers.h | 27 +++++++++++++++++++ 8 files changed, 88 insertions(+), 40 deletions(-) create mode 100644 src/Ai/Raid/BlackwingLair/Util/RaidBwlHelpers.cpp create mode 100644 src/Ai/Raid/BlackwingLair/Util/RaidBwlHelpers.h diff --git a/src/Ai/Raid/BlackwingLair/Action/RaidBwlActions.cpp b/src/Ai/Raid/BlackwingLair/Action/RaidBwlActions.cpp index 9014345cc..2d018fc91 100644 --- a/src/Ai/Raid/BlackwingLair/Action/RaidBwlActions.cpp +++ b/src/Ai/Raid/BlackwingLair/Action/RaidBwlActions.cpp @@ -1,35 +1,40 @@ #include "RaidBwlActions.h" #include "Playerbots.h" +#include "RaidBwlHelpers.h" + +using namespace BlackwingLairHelpers; + +// General bool BwlOnyxiaScaleCloakAuraCheckAction::Execute(Event /*event*/) { - bot->AddAura(22683, bot); + bot->AddAura(SPELL_ONYXIA_SCALE_CLOAK, bot); return true; } -bool BwlOnyxiaScaleCloakAuraCheckAction::isUseful() { return !bot->HasAura(22683); } +bool BwlOnyxiaScaleCloakAuraCheckAction::isUseful() +{ + return !bot->HasAura(SPELL_ONYXIA_SCALE_CLOAK); +} bool BwlTurnOffSuppressionDeviceAction::Execute(Event /*event*/) { GuidVector gos = AI_VALUE(GuidVector, "nearest game objects"); - for (GuidVector::iterator i = gos.begin(); i != gos.end(); i++) + for (auto i = gos.begin(); i != gos.end(); ++i) { GameObject* go = botAI->GetGameObject(*i); - if (!go) + if (IsActiveSuppressionDeviceInRange(go, bot)) { - continue; + go->SetGoState(GO_STATE_ACTIVE); } - if (go->GetEntry() != 179784 || go->GetDistance(bot) >= 15.0f || go->GetGoState() != GO_STATE_READY) - { - continue; - } - go->SetGoState(GO_STATE_ACTIVE); } return true; } +// Chromaggus + bool BwlUseHourglassSandAction::Execute(Event /*event*/) { - return botAI->CastSpell(23645, bot); + return botAI->CastSpell(SPELL_HOURGLASS_SAND, bot); } diff --git a/src/Ai/Raid/BlackwingLair/Action/RaidBwlActions.h b/src/Ai/Raid/BlackwingLair/Action/RaidBwlActions.h index 24dcf3996..27037414a 100644 --- a/src/Ai/Raid/BlackwingLair/Action/RaidBwlActions.h +++ b/src/Ai/Raid/BlackwingLair/Action/RaidBwlActions.h @@ -2,11 +2,8 @@ #define _PLAYERBOT_RAIDBWLACTIONS_H #include "Action.h" -#include "AttackAction.h" -#include "GenericActions.h" -#include "MovementActions.h" -#include "PlayerbotAI.h" -#include "Playerbots.h" + +// General class BwlOnyxiaScaleCloakAuraCheckAction : public Action { @@ -23,6 +20,8 @@ public: bool Execute(Event event) override; }; +// Chromaggus + class BwlUseHourglassSandAction : public Action { public: diff --git a/src/Ai/Raid/BlackwingLair/Strategy/RaidBwlStrategy.cpp b/src/Ai/Raid/BlackwingLair/Strategy/RaidBwlStrategy.cpp index c65a80ecb..ec36b2cde 100644 --- a/src/Ai/Raid/BlackwingLair/Strategy/RaidBwlStrategy.cpp +++ b/src/Ai/Raid/BlackwingLair/Strategy/RaidBwlStrategy.cpp @@ -1,15 +1,13 @@ #include "RaidBwlStrategy.h" -#include "Strategy.h" - void RaidBwlStrategy::InitTriggers(std::vector& triggers) { - triggers.push_back(new TriggerNode("often", - { NextAction("bwl check onyxia scale cloak", ACTION_RAID) })); + triggers.push_back(new TriggerNode("often", { + NextAction("bwl check onyxia scale cloak", ACTION_RAID) })); - triggers.push_back(new TriggerNode("bwl suppression device", - { NextAction("bwl turn off suppression device", ACTION_RAID) })); + triggers.push_back(new TriggerNode("bwl suppression device", { + NextAction("bwl turn off suppression device", ACTION_RAID) })); - triggers.push_back(new TriggerNode("bwl affliction bronze", - { NextAction("bwl use hourglass sand", ACTION_RAID) })); + triggers.push_back(new TriggerNode("bwl affliction bronze", { + NextAction("bwl use hourglass sand", ACTION_RAID) })); } diff --git a/src/Ai/Raid/BlackwingLair/Strategy/RaidBwlStrategy.h b/src/Ai/Raid/BlackwingLair/Strategy/RaidBwlStrategy.h index e09ea2f3e..375ddad71 100644 --- a/src/Ai/Raid/BlackwingLair/Strategy/RaidBwlStrategy.h +++ b/src/Ai/Raid/BlackwingLair/Strategy/RaidBwlStrategy.h @@ -8,9 +8,9 @@ class RaidBwlStrategy : public Strategy { public: RaidBwlStrategy(PlayerbotAI* ai) : Strategy(ai) {} - virtual std::string const getName() override { return "bwl"; } - virtual void InitTriggers(std::vector& triggers) override; - // virtual void InitMultipliers(std::vector &multipliers) override; + std::string const getName() override { return "bwl"; } + void InitTriggers(std::vector& triggers) override; + // void InitMultipliers(std::vector &multipliers) override; }; #endif diff --git a/src/Ai/Raid/BlackwingLair/Trigger/RaidBwlTriggers.cpp b/src/Ai/Raid/BlackwingLair/Trigger/RaidBwlTriggers.cpp index e34e7a9a6..4b4bee1ad 100644 --- a/src/Ai/Raid/BlackwingLair/Trigger/RaidBwlTriggers.cpp +++ b/src/Ai/Raid/BlackwingLair/Trigger/RaidBwlTriggers.cpp @@ -1,24 +1,29 @@ #include "RaidBwlTriggers.h" -#include "SharedDefines.h" +#include "Playerbots.h" +#include "RaidBwlHelpers.h" + +using namespace BlackwingLairHelpers; + +// General bool BwlSuppressionDeviceTrigger::IsActive() { GuidVector gos = AI_VALUE(GuidVector, "nearest game objects"); - for (GuidVector::iterator i = gos.begin(); i != gos.end(); i++) + for (auto i = gos.begin(); i != gos.end(); ++i) { - GameObject* go = botAI->GetGameObject(*i); - if (!go) + const GameObject* go = botAI->GetGameObject(*i); + if (IsActiveSuppressionDeviceInRange(go, bot)) { - continue; + return true; } - if (go->GetEntry() != 179784 || go->GetDistance(bot) >= 15.0f || go->GetGoState() != GO_STATE_READY) - { - continue; - } - return true; } return false; } -bool BwlAfflictionBronzeTrigger::IsActive() { return bot->HasAura(23170); } +// Chromaggus + +bool BwlAfflictionBronzeTrigger::IsActive() +{ + return bot->HasAura(SPELL_BROOD_AFFLICTION_BRONZE); +} diff --git a/src/Ai/Raid/BlackwingLair/Trigger/RaidBwlTriggers.h b/src/Ai/Raid/BlackwingLair/Trigger/RaidBwlTriggers.h index fc19acd5d..0aa290007 100644 --- a/src/Ai/Raid/BlackwingLair/Trigger/RaidBwlTriggers.h +++ b/src/Ai/Raid/BlackwingLair/Trigger/RaidBwlTriggers.h @@ -1,10 +1,10 @@ #ifndef _PLAYERBOT_RAIDBWLTRIGGERS_H #define _PLAYERBOT_RAIDBWLTRIGGERS_H -#include "PlayerbotAI.h" -#include "Playerbots.h" #include "Trigger.h" +// General + class BwlSuppressionDeviceTrigger : public Trigger { public: @@ -12,6 +12,8 @@ public: bool IsActive() override; }; +// Chromaggus + class BwlAfflictionBronzeTrigger : public Trigger { public: diff --git a/src/Ai/Raid/BlackwingLair/Util/RaidBwlHelpers.cpp b/src/Ai/Raid/BlackwingLair/Util/RaidBwlHelpers.cpp new file mode 100644 index 000000000..cc0714bd1 --- /dev/null +++ b/src/Ai/Raid/BlackwingLair/Util/RaidBwlHelpers.cpp @@ -0,0 +1,12 @@ +#include "RaidBwlHelpers.h" + +namespace BlackwingLairHelpers +{ + bool IsActiveSuppressionDeviceInRange(const GameObject* go, const Player* bot) + { + return go && + go->GetEntry() == GO_SUPPRESSION_DEVICE && + go->GetDistance(bot) < 15.0f && + go->GetGoState() == GO_STATE_READY; + } +} diff --git a/src/Ai/Raid/BlackwingLair/Util/RaidBwlHelpers.h b/src/Ai/Raid/BlackwingLair/Util/RaidBwlHelpers.h new file mode 100644 index 000000000..3333d826d --- /dev/null +++ b/src/Ai/Raid/BlackwingLair/Util/RaidBwlHelpers.h @@ -0,0 +1,27 @@ +#ifndef _PLAYERBOT_RAIDBWLHELPERS_H +#define _PLAYERBOT_RAIDBWLHELPERS_H + +#include "Player.h" + +namespace BlackwingLairHelpers +{ + enum BlackwingLairSpells + { + // General + SPELL_ONYXIA_SCALE_CLOAK = 22683, + + // Chromaggus + SPELL_BROOD_AFFLICTION_BRONZE = 23170, + SPELL_HOURGLASS_SAND = 23645 + }; + + enum BlackwingLairGameObjects + { + // General + GO_SUPPRESSION_DEVICE = 179784 + }; + + bool IsActiveSuppressionDeviceInRange(const GameObject* go, const Player* bot); +} + +#endif //_PLAYERBOT_RAIDBWLHELPERS_H