Files
mod-playerbots/src/Ai/Base/Actions/WorldBuffAction.cpp
bashermens 13fff46fa0 Improper singletons migration to clean Meyer's singletons (cherry-pick) (#2082)
# Pull Request

- Applies the clean and corrected singletons, Meyer pattern. (cherry
picked from @SmashingQuasar )

Testing by just playing the game in various ways. Been tested by myself
@Celandriel and @SmashingQuasar
---

## Complexity & Impact

- Does this change add new decision branches?
    - [x] No
    - [ ] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [x] No
    - [ ] Yes (**describe and justify impact**)

- Could this logic scale poorly under load?
    - [x] No
    - [ ] Yes (**explain why**)

---

## Defaults & Configuration

- Does this change modify default bot behavior?
    - [x] No
    - [ ] Yes (**explain why**)

---

## AI Assistance

- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
    - [x] No
    - [ ] Yes (**explain below**)
---

## Final Checklist

- [x] Stability is not compromised
- [x] Performance impact is understood, tested, and acceptable
- [x] Added logic complexity is justified and explained
- [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: Nicolas Lebacq <nicolas.cordier@outlook.com>
Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com>
2026-01-30 21:49:37 +01:00

100 lines
2.8 KiB
C++

/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license, you may redistribute it
* and/or modify it under version 3 of the License, or (at your option), any later version.
*/
#include "WorldBuffAction.h"
#include "AiFactory.h"
#include "Event.h"
#include "Playerbots.h"
bool WorldBuffAction::Execute(Event event)
{
std::string const text = event.getParam();
std::vector<uint32> buffs = NeedWorldBuffs(bot); // Get matching buffs
for (auto& wb : buffs)
{
bot->AddAura(wb, bot);
}
return false;
}
std::vector<uint32> WorldBuffAction::NeedWorldBuffs(Unit* unit)
{
std::vector<uint32> retVec;
if (sPlayerbotAIConfig.worldBuffs.empty())
return retVec;
FactionTemplateEntry const* humanFaction = sFactionTemplateStore.LookupEntry(1);
uint32 factionId =
(Unit::GetFactionReactionTo(unit->GetFactionTemplateEntry(), humanFaction) >= REP_NEUTRAL) ? 1 : 2;
Player* bot = unit->ToPlayer();
if (!bot)
return retVec;
uint8 botClass = bot->getClass();
uint8 botLevel = bot->GetLevel();
uint8 tab = AiFactory::GetPlayerSpecTab(bot);
// We'll store the final "effective" spec ID here.
// For non-Feral druids (and all other classes),
// effectiveSpec = tab by default.
uint8 effectiveSpec = tab;
// If this is a druid in the Feral tab, decide Bear vs. Cat
if (botClass == CLASS_DRUID && tab == 1) // 1 = feral
{
bool isBear = bot->HasTalent(16931, bot->GetActiveSpec()); // Thick Hide rank 3
if (!isBear)
{
// If not bear, then treat it as "cat" spec = 3
effectiveSpec = 3;
}
// If bear, effectiveSpec remains 1
}
// If this is a Death Knight in the Blood tab, decide Tank vs. DPS
if (botClass == CLASS_DEATH_KNIGHT && tab == 0) // 0 = Blood
{
bool isTank = bot->HasTalent(55226, bot->GetActiveSpec()); // Blade Barrier rank 5
if (!isTank)
{
// If not tank, then treat it as DPS spec = 3
effectiveSpec = 3;
}
// If tank, effectiveSpec remains unchanged
}
for (auto const& wb : sPlayerbotAIConfig.worldBuffs)
{
// Faction check
if (wb.factionId != 0 && wb.factionId != factionId)
continue;
// Class check
if (wb.classId != 0 && wb.classId != botClass)
continue;
// Level check
if (wb.minLevel != 0 && wb.minLevel > botLevel)
continue;
if (wb.maxLevel != 0 && wb.maxLevel < botLevel)
continue;
// Already has aura?
if (bot->HasAura(wb.spellId))
continue;
// Final check: does the world-buff spec ID match our effective spec?
if (wb.specId == effectiveSpec)
retVec.push_back(wb.spellId);
}
return retVec;
}