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>
This commit is contained in:
bashermens
2026-01-30 21:49:37 +01:00
committed by GitHub
parent a92886032c
commit 13fff46fa0
233 changed files with 2460 additions and 2354 deletions

View File

@@ -22,17 +22,18 @@
#include "Timer.h"
#include "PlayerbotAI.h"
#include "Player.h"
#include "Corpse.h"
bool LowManaTrigger::IsActive()
{
return AI_VALUE2(bool, "has mana", "self target") &&
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->lowMana;
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig.lowMana;
}
bool MediumManaTrigger::IsActive()
{
return AI_VALUE2(bool, "has mana", "self target") &&
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->mediumMana;
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig.mediumMana;
}
bool NoPetTrigger::IsActive()
@@ -72,7 +73,7 @@ bool PetAttackTrigger::IsActive()
bool HighManaTrigger::IsActive()
{
return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->highMana;
return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig.highMana;
}
bool AlmostFullManaTrigger::IsActive()
@@ -82,7 +83,7 @@ bool AlmostFullManaTrigger::IsActive()
bool EnoughManaTrigger::IsActive()
{
return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") > sPlayerbotAIConfig->highMana;
return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") > sPlayerbotAIConfig.highMana;
}
bool RageAvailable::IsActive() { return AI_VALUE2(uint8, "rage", "self target") >= amount; }
@@ -110,9 +111,9 @@ bool HasAggroTrigger::IsActive() { return AI_VALUE2(bool, "has aggro", "current
bool PanicTrigger::IsActive()
{
return AI_VALUE2(uint8, "health", "self target") < sPlayerbotAIConfig->criticalHealth &&
return AI_VALUE2(uint8, "health", "self target") < sPlayerbotAIConfig.criticalHealth &&
(!AI_VALUE2(bool, "has mana", "self target") ||
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->lowMana);
AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig.lowMana);
}
bool OutNumberedTrigger::IsActive()
@@ -248,7 +249,7 @@ bool AoeTrigger::IsActive()
bool NoFoodTrigger::IsActive()
{
bool isRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
bool isRandomBot = sRandomPlayerbotMgr.IsRandomBot(bot);
if (isRandomBot && botAI->HasCheat(BotCheatMask::food))
return false;
@@ -257,7 +258,7 @@ bool NoFoodTrigger::IsActive()
bool NoDrinkTrigger::IsActive()
{
bool isRandomBot = sRandomPlayerbotMgr->IsRandomBot(bot);
bool isRandomBot = sRandomPlayerbotMgr.IsRandomBot(bot);
if (isRandomBot && botAI->HasCheat(BotCheatMask::food))
return false;
@@ -319,11 +320,11 @@ RandomTrigger::RandomTrigger(PlayerbotAI* botAI, std::string const name, int32 p
bool RandomTrigger::IsActive()
{
if (getMSTime() - lastCheck < sPlayerbotAIConfig->repeatDelay)
if (getMSTime() - lastCheck < sPlayerbotAIConfig.repeatDelay)
return false;
lastCheck = getMSTime();
int32 k = (int32)(probability / sPlayerbotAIConfig->randomChangeMultiplier);
int32 k = (int32)(probability / sPlayerbotAIConfig.randomChangeMultiplier);
if (k < 1)
k = 1;
return (rand() % k) == 0;
@@ -381,10 +382,10 @@ bool GenericBoostTrigger::IsActive()
bool HealerShouldAttackTrigger::IsActive()
{
// nobody can help me
if (botAI->GetNearGroupMemberCount(sPlayerbotAIConfig->sightDistance) <= 1)
if (botAI->GetNearGroupMemberCount(sPlayerbotAIConfig.sightDistance) <= 1)
return true;
if (AI_VALUE2(uint8, "health", "party member to heal") < sPlayerbotAIConfig->almostFullHealth)
if (AI_VALUE2(uint8, "health", "party member to heal") < sPlayerbotAIConfig.almostFullHealth)
return false;
// special check for resto druid (dont remove tree of life frequently)
@@ -401,9 +402,9 @@ bool HealerShouldAttackTrigger::IsActive()
if (balance <= 50)
manaThreshold = 85;
else if (balance <= 100)
manaThreshold = sPlayerbotAIConfig->highMana;
manaThreshold = sPlayerbotAIConfig.highMana;
else
manaThreshold = sPlayerbotAIConfig->mediumMana;
manaThreshold = sPlayerbotAIConfig.mediumMana;
if (AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") < manaThreshold)
return false;
@@ -632,7 +633,7 @@ bool ReturnToStayPositionTrigger::IsActive()
if (stayPosition.isSet())
{
const float distance = bot->GetDistance(stayPosition.x, stayPosition.y, stayPosition.z);
return distance > sPlayerbotAIConfig->followDistance;
return distance > sPlayerbotAIConfig.followDistance;
}
return false;

View File

@@ -216,7 +216,7 @@ public:
class AttackerCountTrigger : public Trigger
{
public:
AttackerCountTrigger(PlayerbotAI* botAI, int32 amount, float distance = sPlayerbotAIConfig->sightDistance)
AttackerCountTrigger(PlayerbotAI* botAI, int32 amount, float distance = sPlayerbotAIConfig.sightDistance)
: Trigger(botAI), amount(amount), distance(distance)
{
}
@@ -836,7 +836,7 @@ private:
class SitTrigger : public StayTimeTrigger
{
public:
SitTrigger(PlayerbotAI* botAI) : StayTimeTrigger(botAI, sPlayerbotAIConfig->sitDelay, "sit") {}
SitTrigger(PlayerbotAI* botAI) : StayTimeTrigger(botAI, sPlayerbotAIConfig.sitDelay, "sit") {}
};
class ReturnToStayPositionTrigger : public Trigger
@@ -850,7 +850,7 @@ public:
class ReturnTrigger : public StayTimeTrigger
{
public:
ReturnTrigger(PlayerbotAI* botAI) : StayTimeTrigger(botAI, sPlayerbotAIConfig->returnDelay, "return") {}
ReturnTrigger(PlayerbotAI* botAI) : StayTimeTrigger(botAI, sPlayerbotAIConfig.returnDelay, "return") {}
};
class GiveItemTrigger : public Trigger

View File

@@ -38,4 +38,4 @@ bool AoeInGroupTrigger::IsActive()
threshold = std::min(threshold, 15);
return AI_VALUE2(uint8, "aoe heal", type) >= threshold;
}
}

View File

@@ -48,7 +48,7 @@ class LowHealthTrigger : public HealthInRangeTrigger
{
public:
LowHealthTrigger(PlayerbotAI* botAI, std::string const name = "low health",
float value = sPlayerbotAIConfig->lowHealth, float minValue = 0)
float value = sPlayerbotAIConfig.lowHealth, float minValue = 0)
: HealthInRangeTrigger(botAI, name, value, minValue)
{
}
@@ -60,7 +60,7 @@ class CriticalHealthTrigger : public LowHealthTrigger
{
public:
CriticalHealthTrigger(PlayerbotAI* botAI)
: LowHealthTrigger(botAI, "critical health", sPlayerbotAIConfig->criticalHealth, 0)
: LowHealthTrigger(botAI, "critical health", sPlayerbotAIConfig.criticalHealth, 0)
{
}
};
@@ -69,7 +69,7 @@ class MediumHealthTrigger : public LowHealthTrigger
{
public:
MediumHealthTrigger(PlayerbotAI* botAI)
: LowHealthTrigger(botAI, "medium health", sPlayerbotAIConfig->mediumHealth, 0)
: LowHealthTrigger(botAI, "medium health", sPlayerbotAIConfig.mediumHealth, 0)
{
}
};
@@ -78,8 +78,8 @@ class AlmostFullHealthTrigger : public LowHealthTrigger
{
public:
AlmostFullHealthTrigger(PlayerbotAI* botAI)
: LowHealthTrigger(botAI, "almost full health", sPlayerbotAIConfig->almostFullHealth,
sPlayerbotAIConfig->mediumHealth)
: LowHealthTrigger(botAI, "almost full health", sPlayerbotAIConfig.almostFullHealth,
sPlayerbotAIConfig.mediumHealth)
{
}
};
@@ -88,7 +88,7 @@ class PartyMemberLowHealthTrigger : public HealthInRangeTrigger
{
public:
PartyMemberLowHealthTrigger(PlayerbotAI* botAI, std::string const name = "party member low health",
float value = sPlayerbotAIConfig->lowHealth,
float value = sPlayerbotAIConfig.lowHealth,
float minValue = 0)
: HealthInRangeTrigger(botAI, name, value, minValue)
{
@@ -101,7 +101,7 @@ class PartyMemberCriticalHealthTrigger : public PartyMemberLowHealthTrigger
{
public:
PartyMemberCriticalHealthTrigger(PlayerbotAI* botAI)
: PartyMemberLowHealthTrigger(botAI, "party member critical health", sPlayerbotAIConfig->criticalHealth, 0)
: PartyMemberLowHealthTrigger(botAI, "party member critical health", sPlayerbotAIConfig.criticalHealth, 0)
{
}
};
@@ -110,7 +110,7 @@ class PartyMemberMediumHealthTrigger : public PartyMemberLowHealthTrigger
{
public:
PartyMemberMediumHealthTrigger(PlayerbotAI* botAI)
: PartyMemberLowHealthTrigger(botAI, "party member medium health", sPlayerbotAIConfig->mediumHealth,
: PartyMemberLowHealthTrigger(botAI, "party member medium health", sPlayerbotAIConfig.mediumHealth,
0)
{
}
@@ -120,7 +120,7 @@ class PartyMemberAlmostFullHealthTrigger : public PartyMemberLowHealthTrigger
{
public:
PartyMemberAlmostFullHealthTrigger(PlayerbotAI* botAI)
: PartyMemberLowHealthTrigger(botAI, "party member almost full health", sPlayerbotAIConfig->almostFullHealth,
: PartyMemberLowHealthTrigger(botAI, "party member almost full health", sPlayerbotAIConfig.almostFullHealth,
0)
{
}

View File

@@ -15,11 +15,11 @@ bool LootAvailableTrigger::IsActive()
if (botAI->HasStrategy("stay", BOT_STATE_NON_COMBAT))
{
distanceCheck =
sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "loot target"), CONTACT_DISTANCE);
ServerFacade::instance().IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "loot target"), CONTACT_DISTANCE);
}
else
{
distanceCheck = sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "loot target"),
distanceCheck = ServerFacade::instance().IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "loot target"),
INTERACTION_DISTANCE - 2.0f);
}

View File

@@ -247,7 +247,7 @@ bool EnemyFlagCarrierNear::IsActive()
{
Unit* carrier = AI_VALUE(Unit*, "enemy flag carrier");
if (!carrier || !sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, carrier), 100.f))
if (!carrier || !ServerFacade::instance().IsDistanceLessOrEqualThan(ServerFacade::instance().GetDistance2d(bot, carrier), 100.f))
return false;
// Check if there is another enemy player target closer than the FC
@@ -255,8 +255,8 @@ bool EnemyFlagCarrierNear::IsActive()
if (nearbyEnemy)
{
float distToFC = sServerFacade->GetDistance2d(bot, carrier);
float distToEnemy = sServerFacade->GetDistance2d(bot, nearbyEnemy);
float distToFC = ServerFacade::instance().GetDistance2d(bot, carrier);
float distToEnemy = ServerFacade::instance().GetDistance2d(bot, nearbyEnemy);
// If the other enemy is significantly closer, don't pursue FC
if (distToEnemy + 15.0f < distToFC) // Add small buffer
@@ -283,7 +283,7 @@ bool TeamFlagCarrierNear::IsActive()
}
Unit* carrier = AI_VALUE(Unit*, "team flag carrier");
return carrier && sServerFacade->IsDistanceLessOrEqualThan(sServerFacade->GetDistance2d(bot, carrier), 200.f);
return carrier && ServerFacade::instance().IsDistanceLessOrEqualThan(ServerFacade::instance().GetDistance2d(bot, carrier), 200.f);
}
bool PlayerWantsInBattlegroundTrigger::IsActive()

View File

@@ -34,7 +34,7 @@ bool EnemyTooCloseForSpellTrigger::IsActive()
// bool isBoss = false;
// bool isRaid = false;
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
// float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
// float targetDistance = ServerFacade::instance().GetDistance2d(bot, target) + combatReach;
// if (target->IsCreature())
// {
// Creature* creature = botAI->GetCreature(target->GetGUID());
@@ -48,10 +48,10 @@ bool EnemyTooCloseForSpellTrigger::IsActive()
// isRaid = true;
// // if (isBoss || isRaid)
// // return sServerFacade->IsDistanceLessThan(targetDistance, (sPlayerbotAIConfig->tooCloseDistance +
// // return ServerFacade::instance().IsDistanceLessThan(targetDistance, (sPlayerbotAIConfig.tooCloseDistance +
// combatReach) / 2);
// return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, (sPlayerbotAIConfig->tooCloseDistance +
// return ServerFacade::instance().IsDistanceLessOrEqualThan(targetDistance, (sPlayerbotAIConfig.tooCloseDistance +
// combatReach / 2));
}
@@ -80,7 +80,7 @@ bool EnemyTooCloseForAutoShotTrigger::IsActive()
// bool isBoss = false;
// bool isRaid = false;
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
// float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
// float targetDistance = ServerFacade::instance().GetDistance2d(bot, target) + combatReach;
// if (target->IsCreature())
// {
// Creature* creature = botAI->GetCreature(target->GetGUID());
@@ -93,7 +93,7 @@ bool EnemyTooCloseForAutoShotTrigger::IsActive()
// if (bot->GetMap() && bot->GetMap()->IsRaid())
// isRaid = true;
// return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, 5.0f);
// return ServerFacade::instance().IsDistanceLessOrEqualThan(targetDistance, 5.0f);
}
bool EnemyTooCloseForShootTrigger::IsActive()
@@ -115,7 +115,7 @@ bool EnemyTooCloseForShootTrigger::IsActive()
// bool isBoss = false;
// bool isRaid = false;
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
// float targetDistance = sServerFacade->GetDistance2d(bot, target) + combatReach;
// float targetDistance = ServerFacade::instance().GetDistance2d(bot, target) + combatReach;
// if (target->IsCreature())
// {
// Creature* creature = botAI->GetCreature(target->GetGUID());
@@ -129,9 +129,9 @@ bool EnemyTooCloseForShootTrigger::IsActive()
// isRaid = true;
// // if (isBoss || isRaid)
// // return sServerFacade->IsDistanceLessThan(targetDistance, botAI->GetRange("shoot") + combatReach);
// // return ServerFacade::instance().IsDistanceLessThan(targetDistance, botAI->GetRange("shoot") + combatReach);
// return sServerFacade->IsDistanceLessOrEqualThan(targetDistance, (botAI->GetRange("shoot") + combatReach /
// return ServerFacade::instance().IsDistanceLessOrEqualThan(targetDistance, (botAI->GetRange("shoot") + combatReach /
// 2));
}
@@ -147,8 +147,8 @@ bool EnemyTooCloseForMeleeTrigger::IsActive()
bool EnemyIsCloseTrigger::IsActive()
{
Unit* target = AI_VALUE(Unit*, "current target");
return target && sServerFacade->IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"),
sPlayerbotAIConfig->tooCloseDistance);
return target && ServerFacade::instance().IsDistanceLessOrEqualThan(AI_VALUE2(float, "distance", "current target"),
sPlayerbotAIConfig.tooCloseDistance);
}
bool EnemyWithinMeleeTrigger::IsActive()
@@ -165,7 +165,7 @@ bool OutOfRangeTrigger::IsActive()
return target &&
!bot->IsWithinCombatRange(
target,
dis); // sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", GetTargetName()), distance);
dis); // ServerFacade::instance().IsDistanceGreaterThan(AI_VALUE2(float, "distance", GetTargetName()), distance);
}
EnemyOutOfSpellRangeTrigger::EnemyOutOfSpellRangeTrigger(PlayerbotAI* botAI)
@@ -180,8 +180,8 @@ EnemyOutOfSpellRangeTrigger::EnemyOutOfSpellRangeTrigger(PlayerbotAI* botAI)
// return false;
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
// return target && (sServerFacade->GetDistance2d(bot, target) > (distance + combatReach +
// sPlayerbotAIConfig->contactDistance) || !bot->IsWithinLOSInMap(target));
// return target && (ServerFacade::instance().GetDistance2d(bot, target) > (distance + combatReach +
// sPlayerbotAIConfig.contactDistance) || !bot->IsWithinLOSInMap(target));
// }
// bool EnemyOutOfMeleeTrigger::IsActive()
@@ -190,7 +190,7 @@ EnemyOutOfSpellRangeTrigger::EnemyOutOfSpellRangeTrigger(PlayerbotAI* botAI)
// if (!target)
// return false;
// float targetDistance = sServerFacade->GetDistance2d(bot, target);
// float targetDistance = ServerFacade::instance().GetDistance2d(bot, target);
// return target && (targetDistance > std::max(5.0f, bot->GetCombatReach() + target->GetCombatReach()) ||
// (!bot->IsWithinLOSInMap(target) && targetDistance > 5.0f));
// }
@@ -202,7 +202,7 @@ bool PartyMemberToHealOutOfSpellRangeTrigger::IsActive()
return false;
float combatReach = bot->GetCombatReach() + target->GetCombatReach();
return target && (sServerFacade->GetDistance2d(bot, target) > (distance + sPlayerbotAIConfig->contactDistance) ||
return target && (ServerFacade::instance().GetDistance2d(bot, target) > (distance + sPlayerbotAIConfig.contactDistance) ||
!bot->IsWithinLOSInMap(target));
}
@@ -213,7 +213,7 @@ PartyMemberToHealOutOfSpellRangeTrigger::PartyMemberToHealOutOfSpellRangeTrigger
bool FarFromMasterTrigger::IsActive()
{
return sServerFacade->IsDistanceGreaterThan(AI_VALUE2(float, "distance", "group leader"), distance);
return ServerFacade::instance().IsDistanceGreaterThan(AI_VALUE2(float, "distance", "group leader"), distance);
}
bool TooCloseToCreatureTrigger::TooCloseToCreature(uint32 creatureId, float range, bool alive)

View File

@@ -78,7 +78,7 @@ class EnemyOutOfMeleeTrigger : public OutOfRangeTrigger
{
public:
EnemyOutOfMeleeTrigger(PlayerbotAI* botAI)
: OutOfRangeTrigger(botAI, "enemy out of melee range", sPlayerbotAIConfig->meleeDistance)
: OutOfRangeTrigger(botAI, "enemy out of melee range", sPlayerbotAIConfig.meleeDistance)
{
}

View File

@@ -21,7 +21,7 @@ bool AtDarkPortalAzerothTrigger::IsActive()
{
if (bot->GetAreaId() == 72)
{
if (sServerFacade->GetDistance2d(bot, -11906.9f, -3208.53f) < 20.0f)
if (ServerFacade::instance().GetDistance2d(bot, -11906.9f, -3208.53f) < 20.0f)
{
return true;
}
@@ -34,7 +34,7 @@ bool AtDarkPortalOutlandTrigger::IsActive()
{
if (bot->GetAreaId() == 3539)
{
if (sServerFacade->GetDistance2d(bot, -248.1939f, 921.919f) < 10.0f)
if (ServerFacade::instance().GetDistance2d(bot, -248.1939f, 921.919f) < 10.0f)
{
return true;
}