From 73831c16c001e987b01d4e43e5711b82445a0dd3 Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Tue, 29 Oct 2024 01:15:26 +0100 Subject: [PATCH] [performance] new baseline (#644) --- conf/playerbots.conf.dist | 10 +- src/PlayerbotAI.cpp | 207 +++++++++--------- src/PlayerbotAI.h | 9 +- src/PlayerbotAIConfig.cpp | 6 +- src/PlayerbotAIConfig.h | 2 - src/RandomPlayerbotMgr.cpp | 27 +-- src/RandomPlayerbotMgr.h | 11 +- .../actions/BattleGroundJoinAction.cpp | 15 -- 8 files changed, 115 insertions(+), 172 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index b644c6c9..8d7bf12e 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -728,7 +728,7 @@ AiPlayerbot.FastReactInBG = 1 # # All In seconds -AiPlayerbot.RandomBotUpdateInterval = 20 +AiPlayerbot.RandomBotUpdateInterval = 1 AiPlayerbot.RandomBotCountChangeMinInterval = 1800 AiPlayerbot.RandomBotCountChangeMaxInterval = 7200 AiPlayerbot.MinRandomBotInWorldTime = 3600 @@ -1459,17 +1459,11 @@ AiPlayerbot.BotActiveAlone = 100 # Specify smart scaling is enabled or not. # The default is 1. When enabled (smart) scales the 'BotActiveAlone' value. -AiPlayerbot.botActiveAloneSmartScale = 1 - # Only when botLevel is between WhenMinLevel and WhenMaxLevel. +AiPlayerbot.botActiveAloneSmartScale = 1 AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel = 1 AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel = 80 -# The server will tune bot activity to reach the desired server tick speed (in ms) -# bots will only join battleground when there is no lag based on latency diffs below -AiPlayerbot.botActiveAloneSmartScaleDiffWithPlayer = 100 -AiPlayerbot.botActiveAloneSmartScaleDiffEmpty = 200 - # Premade spell to avoid (undetected spells) # spellid-radius, ... AiPlayerbot.PremadeAvoidAoe = 62234-4 diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 023ec7b6..af993980 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -31,6 +31,7 @@ #include "ObjectGuid.h" #include "PerformanceMonitor.h" #include "Player.h" +#include "GameTime.h" #include "PlayerbotAIConfig.h" #include "PlayerbotDbStore.h" #include "PlayerbotMgr.h" @@ -4095,7 +4096,7 @@ ActivePiorityType PlayerbotAI::GetPriorityType(ActivityType activityType) for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) { Player* member = gref->GetSource(); - if (!member || !member->IsInWorld() && member->GetMapId() != bot->GetMapId()) + if (!member || (!member->IsInWorld() && member->GetMapId() != bot->GetMapId())) continue; if (member == bot) @@ -4106,11 +4107,11 @@ ActivePiorityType PlayerbotAI::GetPriorityType(ActivityType activityType) if (!memberBotAI || memberBotAI->HasRealPlayerMaster()) return ActivePiorityType::IN_GROUP_WITH_REAL_PLAYER; - //IN_GROUP_WITH_REAL_PLAYER + //ALLOWED_PARTY_ACTIVITY if (group->IsLeader(member->GetGUID())) { if (!memberBotAI->AllowActivity(PARTY_ACTIVITY)) - return ActivePiorityType::IN_GROUP_WITH_REAL_PLAYER; + return ActivePiorityType::ALLOWED_PARTY_ACTIVITY; } } } @@ -4180,145 +4181,103 @@ ActivePiorityType PlayerbotAI::GetPriorityType(ActivityType activityType) if (IsInRealGuild()) return ActivePiorityType::PLAYER_GUILD; - //IN_INACTIVE_MAP - if (bot->IsBeingTeleported() || !bot->IsInWorld() || !HasRealPlayers(bot->GetMap())) - return ActivePiorityType::IN_INACTIVE_MAP; + + //IN_NOT_ACTIVE_MAP + if (Map* map = bot->GetMap()) + { + if (map->GetEntry()->IsWorldMap()) + { + if (!HasRealPlayers(map)) + return ActivePiorityType::IN_NOT_ACTIVE_MAP; + + if (!map->IsGridLoaded(bot->GetPositionX(), bot->GetPositionY())) + return ActivePiorityType::IN_NOT_ACTIVE_MAP; + } + } //IN_ACTIVE_MAP - if (!bot->IsBeingTeleported() && bot->IsInWorld() && HasRealPlayers(bot->GetMap())) - return ActivePiorityType::IN_ACTIVE_MAP; + if (Map* map = bot->GetMap()) + { + if (map->GetEntry()->IsWorldMap()) + { + if (HasRealPlayers(map)) + return ActivePiorityType::IN_ACTIVE_MAP; + } + } // IN_ACTIVE_AREA if (activityType == OUT_OF_PARTY_ACTIVITY || activityType == GRIND_ACTIVITY) { if (HasManyPlayersNearby(20, sPlayerbotAIConfig->sightDistance)) - return ActivePiorityType::IN_ACTIVE_AREA; + return ActivePiorityType::IN_VERY_ACTIVE_AREA; } - return ActivePiorityType::IN_ACTIVE_AREA; + return ActivePiorityType::DEFAULT; } -// Returns the lower and upper bracket for bots to be active. -// Ie. { 10, 20 } means all bots in this bracket will be inactive below 10% activityMod, -// and will be active above 20% activityMod and scale between those values. -std::pair PlayerbotAI::GetPriorityBracket(ActivePiorityType type) +bool PlayerbotAI::AllowActive(ActivityType activityType) { + // no activity allowed during bot initialization during first + // few minutes after starting the server based on maxRandomBots. + if (!sRandomPlayerbotMgr->isBotInitCompleted() && + GameTime::GetUptime().count() < sPlayerbotAIConfig->maxRandomBots * 0.15) + return false; + + // General exceptions + if (activityType == PACKET_ACTIVITY) + return true; + + ActivePiorityType type = GetPriorityType(activityType); switch (type) { case ActivePiorityType::HAS_REAL_PLAYER_MASTER: case ActivePiorityType::IS_REAL_PLAYER: case ActivePiorityType::IN_GROUP_WITH_REAL_PLAYER: case ActivePiorityType::IN_INSTANCE: - case ActivePiorityType::VISIBLE_FOR_PLAYER: - return {0, 0}; - case ActivePiorityType::IS_ALWAYS_ACTIVE: case ActivePiorityType::IN_COMBAT: - return {0, 10}; - case ActivePiorityType::IN_BG_QUEUE: - return {0, 20}; - case ActivePiorityType::IN_LFG: - return {0, 30}; case ActivePiorityType::NEARBY_PLAYER: - return {0, 40}; + case ActivePiorityType::VISIBLE_FOR_PLAYER: + case ActivePiorityType::IS_ALWAYS_ACTIVE: + return true; + break; + case ActivePiorityType::ALLOWED_PARTY_ACTIVITY: + return false; + break; + case ActivePiorityType::IN_BG_QUEUE: + case ActivePiorityType::IN_LFG: case ActivePiorityType::PLAYER_FRIEND: case ActivePiorityType::PLAYER_GUILD: - return {0, 50}; - case ActivePiorityType::IN_ACTIVE_AREA: - case ActivePiorityType::IN_EMPTY_SERVER: - return {50, 100}; case ActivePiorityType::IN_ACTIVE_MAP: - return {70, 100}; - case ActivePiorityType::IN_INACTIVE_MAP: - return {80, 100}; + case ActivePiorityType::IN_NOT_ACTIVE_MAP: + case ActivePiorityType::IN_EMPTY_SERVER: default: - return {90, 100}; + break; } - return {90, 100}; -} + // Bots do not need to move using PathGenerator. + if (activityType == DETAILED_MOVE_ACTIVITY) return false; -bool PlayerbotAI::AllowActive(ActivityType activityType) -{ - // General exceptions - if (activityType == PACKET_ACTIVITY) - return true; + // All exceptions are now done, below is the code to have a specified % of bots + // active at all times. The default is 10%. With 0.1% of all bots going active + // or inactive each minute. + if (sPlayerbotAIConfig->botActiveAlone <= 0) return false; - ActivePiorityType type = GetPriorityType(activityType); - if (activityType == DETAILED_MOVE_ACTIVITY) - { - switch (type) - { - case ActivePiorityType::HAS_REAL_PLAYER_MASTER: - case ActivePiorityType::IS_REAL_PLAYER: - case ActivePiorityType::IN_GROUP_WITH_REAL_PLAYER: - case ActivePiorityType::IN_INSTANCE: - case ActivePiorityType::VISIBLE_FOR_PLAYER: - case ActivePiorityType::IN_COMBAT: - case ActivePiorityType::NEARBY_PLAYER: - return true; - break; - case ActivePiorityType::IS_ALWAYS_ACTIVE: - case ActivePiorityType::IN_BG_QUEUE: - case ActivePiorityType::IN_LFG: - case ActivePiorityType::PLAYER_FRIEND: - case ActivePiorityType::PLAYER_GUILD: - case ActivePiorityType::IN_ACTIVE_AREA: - case ActivePiorityType::IN_EMPTY_SERVER: - case ActivePiorityType::IN_ACTIVE_MAP: - case ActivePiorityType::IN_INACTIVE_MAP: - default: - break; - } - } - else if (activityType == REACT_ACTIVITY) - { - switch (type) - { - case ActivePiorityType::HAS_REAL_PLAYER_MASTER: - case ActivePiorityType::IS_REAL_PLAYER: - case ActivePiorityType::IN_GROUP_WITH_REAL_PLAYER: - case ActivePiorityType::IN_INSTANCE: - case ActivePiorityType::VISIBLE_FOR_PLAYER: - case ActivePiorityType::IS_ALWAYS_ACTIVE: - case ActivePiorityType::IN_COMBAT: - return true; - break; - case ActivePiorityType::NEARBY_PLAYER: - case ActivePiorityType::IN_BG_QUEUE: - case ActivePiorityType::IN_LFG: - case ActivePiorityType::PLAYER_FRIEND: - case ActivePiorityType::PLAYER_GUILD: - case ActivePiorityType::IN_ACTIVE_AREA: - case ActivePiorityType::IN_EMPTY_SERVER: - case ActivePiorityType::IN_ACTIVE_MAP: - case ActivePiorityType::IN_INACTIVE_MAP: - default: - return false; - break; - } - } + // Normalize the configured botActiveAlone value, and set as default mod. + uint32 botActiveAlonePerc = sPlayerbotAIConfig->botActiveAlone > 100 ? 100 : sPlayerbotAIConfig->botActiveAlone; + uint32 mod = botActiveAlonePerc; - // GetPriorityBracket acitivity - float normalizedBotActiveAlone = sPlayerbotAIConfig->botActiveAlone > 100 ? 100 : sPlayerbotAIConfig->botActiveAlone; - float activePerc = normalizedBotActiveAlone; if (sPlayerbotAIConfig->botActiveAloneSmartScale && bot->GetLevel() >= sPlayerbotAIConfig->botActiveAloneSmartScaleWhenMinLevel && bot->GetLevel() <= sPlayerbotAIConfig->botActiveAloneSmartScaleWhenMaxLevel) { - std::pair priorityBracket = GetPriorityBracket(type); - if (!priorityBracket.second) return true; - float activityPercentage = sRandomPlayerbotMgr->getActivityPercentage(); - if (priorityBracket.first >= activityPercentage) return false; - if (priorityBracket.second <= activityPercentage && priorityBracket.second < 100) return true; - activePerc = (activityPercentage - priorityBracket.first) / (priorityBracket.second - priorityBracket.first); - activePerc *= (priorityBracket.second == 100) ? normalizedBotActiveAlone : 100; + mod = SmartScaleActivity(type, botActiveAlonePerc); } - // The last number if the amount it cycles per min. Currently set to 1% of the active bots. - uint32 ActivityNumber = GetFixedBotNumer(BotTypeNumber::ACTIVITY_TYPE_NUMBER, 100, activePerc * 0.01f); + uint32 ActivityNumber = GetFixedBotNumer(BotTypeNumber::ACTIVITY_TYPE_NUMBER, 100, + botActiveAlonePerc * static_cast(mod) / 100 * 0.01f); - // The given percentage of bots should be active and rotate 1% of those active bots each minute. - return ActivityNumber <= (activePerc); + // The given percentage of bots should be active and rotate 1% of those active bots each minute. + return ActivityNumber <= (botActiveAlonePerc * mod) / 100; } bool PlayerbotAI::AllowActivity(ActivityType activityType, bool checkNow) @@ -4335,6 +4294,42 @@ bool PlayerbotAI::AllowActivity(ActivityType activityType, bool checkNow) return allowed; } +uint32 PlayerbotAI::SmartScaleActivity(ActivePiorityType type, uint32 botActiveAlonePerc) +{ + uint32 maxDiff = sWorldUpdateTime.GetMaxUpdateTime(); + if (maxDiff > 1000) return false; + switch (type) + { + case ActivePiorityType::IN_BG_QUEUE: + case ActivePiorityType::IN_LFG: + if (maxDiff > 100) return 80; + if (maxDiff > 50) return 90; + break; + case ActivePiorityType::PLAYER_FRIEND: + case ActivePiorityType::PLAYER_GUILD: + case ActivePiorityType::IN_ACTIVE_MAP: + if (maxDiff > 200) return 10; + if (maxDiff > 150) return 25; + if (maxDiff > 100) return 50; + if (maxDiff > 50) return 80; + break; + case ActivePiorityType::IN_VERY_ACTIVE_AREA: // Many bots nearby. Do not do heavy area checks. + case ActivePiorityType::IN_NOT_ACTIVE_MAP: + if (maxDiff > 100) return 10; + if (maxDiff > 50) return 25; + else return 30; + case ActivePiorityType::IN_EMPTY_SERVER: + return 10; + default: + if (maxDiff > 200) return 10; + if (maxDiff > 150) return 25; + if (maxDiff > 100) return 50; + break; + } + + return botActiveAlonePerc; +} + bool PlayerbotAI::IsOpposing(Player* player) { return IsOpposing(player->getRace(), bot->getRace()); } bool PlayerbotAI::IsOpposing(uint8 race1, uint8 race2) diff --git a/src/PlayerbotAI.h b/src/PlayerbotAI.h index d1a2f292..03fbe7fe 100644 --- a/src/PlayerbotAI.h +++ b/src/PlayerbotAI.h @@ -255,11 +255,12 @@ enum class ActivePiorityType : uint8 NEARBY_PLAYER = 9, PLAYER_FRIEND = 10, PLAYER_GUILD = 11, - IN_ACTIVE_AREA = 12, + IN_VERY_ACTIVE_AREA = 12, IN_ACTIVE_MAP = 13, - IN_INACTIVE_MAP = 14, + IN_NOT_ACTIVE_MAP = 14, IN_EMPTY_SERVER = 15, - MAX_TYPE + ALLOWED_PARTY_ACTIVITY = 16, + DEFAULT }; enum ActivityType @@ -547,9 +548,9 @@ public: bool HasPlayerNearby(float range = sPlayerbotAIConfig->reactDistance); bool HasManyPlayersNearby(uint32 trigerrValue = 20, float range = sPlayerbotAIConfig->sightDistance); ActivePiorityType GetPriorityType(ActivityType activityType); - std::pair GetPriorityBracket(ActivePiorityType type); bool AllowActive(ActivityType activityType); bool AllowActivity(ActivityType activityType = ALL_ACTIVITY, bool checkNow = false); + uint32 SmartScaleActivity(ActivePiorityType type, uint32 botActiveAlonePerc); // Check if player is safe to use. bool IsSafe(Player* player); diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index 816a345f..7bf16079 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -156,7 +156,7 @@ bool PlayerbotAIConfig::Initialize() randomBotAutologin = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutologin", true); minRandomBots = sConfigMgr->GetOption("AiPlayerbot.MinRandomBots", 50); maxRandomBots = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBots", 200); - randomBotUpdateInterval = sConfigMgr->GetOption("AiPlayerbot.RandomBotUpdateInterval", 20); + randomBotUpdateInterval = sConfigMgr->GetOption("AiPlayerbot.RandomBotUpdateInterval", 1); randomBotCountChangeMinInterval = sConfigMgr->GetOption("AiPlayerbot.RandomBotCountChangeMinInterval", 30 * MINUTE); randomBotCountChangeMaxInterval = @@ -470,10 +470,6 @@ bool PlayerbotAIConfig::Initialize() sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel", 1); botActiveAloneSmartScaleWhenMaxLevel = sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel", 80); - botActiveAloneSmartScaleDiffWithPlayer = - sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleDiffWithPlayer", 100); - botActiveAloneSmartScaleDiffEmpty = - sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleDiffEmpty", 200); randombotsWalkingRPG = sConfigMgr->GetOption("AiPlayerbot.RandombotsWalkingRPG", false); randombotsWalkingRPGInDoors = sConfigMgr->GetOption("AiPlayerbot.RandombotsWalkingRPG.InDoors", false); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index 5ac3fa4a..0f34b41e 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -266,8 +266,6 @@ public: bool botActiveAloneSmartScale; uint32 botActiveAloneSmartScaleWhenMinLevel; uint32 botActiveAloneSmartScaleWhenMaxLevel; - uint32 botActiveAloneSmartScaleDiffWithPlayer; - uint32 botActiveAloneSmartScaleDiffEmpty; bool freeMethodLoot; int32 lootRollLevel; diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index 37acca8d..9020f8ce 100644 --- a/src/RandomPlayerbotMgr.cpp +++ b/src/RandomPlayerbotMgr.cpp @@ -292,11 +292,6 @@ void RandomPlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/) if (!sPlayerbotAIConfig->randomBotAutologin || !sPlayerbotAIConfig->enabled) return; - if (sPlayerbotAIConfig->botActiveAloneSmartScale) - { - ScaleBotActivity(); - } - uint32 maxAllowedBotCount = GetEventValue(0, "bot_count"); if (!maxAllowedBotCount || (maxAllowedBotCount < sPlayerbotAIConfig->minRandomBots || maxAllowedBotCount > sPlayerbotAIConfig->maxRandomBots)) @@ -318,6 +313,7 @@ void RandomPlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/) // when server is balancing bots then boost (decrease value of) the nextCheckDelay till // onlineBotCount reached the AllowedBotCount. + setIsBotInitCompleted(onlineBotCount < maxAllowedBotCount); uint32 updateIntervalTurboBoost = onlineBotCount < maxAllowedBotCount ? 1 : sPlayerbotAIConfig->randomBotUpdateInterval; SetNextCheckDelay(updateIntervalTurboBoost * (onlineBotFocus + 25) * 10); @@ -402,27 +398,6 @@ void RandomPlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/) } } -void RandomPlayerbotMgr::ScaleBotActivity() -{ - float activityPercentage = getActivityPercentage(); - - // if (activityPercentage >= 100.0f || activityPercentage <= 0.0f) pid.reset(); //Stop integer buildup during - // max/min activity - - // % increase/decrease wanted diff , avg diff - float activityPercentageMod = pid.calculate(sRandomPlayerbotMgr->GetPlayers().empty() ? - sPlayerbotAIConfig->botActiveAloneSmartScaleDiffEmpty : - sPlayerbotAIConfig->botActiveAloneSmartScaleDiffWithPlayer, - sWorldUpdateTime.GetAverageUpdateTime()); - - activityPercentage = activityPercentageMod + 50; - - // Cap the percentage between 0 and 100. - activityPercentage = std::max(0.0f, std::min(100.0f, activityPercentage)); - - setActivityPercentage(activityPercentage); -} - uint32 RandomPlayerbotMgr::AddRandomBots() { uint32 maxAllowedBotCount = GetEventValue(0, "bot_count"); diff --git a/src/RandomPlayerbotMgr.h b/src/RandomPlayerbotMgr.h index 5c35aefa..b5208656 100644 --- a/src/RandomPlayerbotMgr.h +++ b/src/RandomPlayerbotMgr.h @@ -103,8 +103,7 @@ public: void LogPlayerLocation(); void UpdateAIInternal(uint32 elapsed, bool minimal = false) override; -private: - void ScaleBotActivity(); +//private: public: uint32 activeBots = 0; @@ -164,11 +163,11 @@ public: return BattleMastersCache; } - float getActivityMod() { return activityMod; } - float getActivityPercentage() { return activityMod * 100.0f; } - void setActivityPercentage(float percentage) { activityMod = percentage / 100.0f; } static uint8 GetTeamClassIdx(bool isAlliance, uint8 claz) { return isAlliance * 20 + claz; } + bool isBotInitCompleted() const { return _isBotInitCompleted; } + void setIsBotInitCompleted(bool completed) { _isBotInitCompleted = completed; } + void PrepareAddclassCache(); std::map> addclassCache; protected: @@ -177,7 +176,7 @@ protected: private: // pid values are set in constructor botPID pid = botPID(1, 50, -50, 0, 0, 0); - float activityMod = 0.25; + bool _isBotInitCompleted = false; uint32 GetEventValue(uint32 bot, std::string const event); std::string const GetEventData(uint32 bot, std::string const event); uint32 SetEventValue(uint32 bot, std::string const event, uint32 value, uint32 validIn, diff --git a/src/strategy/actions/BattleGroundJoinAction.cpp b/src/strategy/actions/BattleGroundJoinAction.cpp index 349ae410..541ce2a4 100644 --- a/src/strategy/actions/BattleGroundJoinAction.cpp +++ b/src/strategy/actions/BattleGroundJoinAction.cpp @@ -234,17 +234,9 @@ bool BGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battlegroun return false; TeamId teamId = bot->GetTeamId(); - bool noLag = sWorldUpdateTime.GetAverageUpdateTime() < (sRandomPlayerbotMgr->GetPlayers().empty() ? - sPlayerbotAIConfig->botActiveAloneSmartScaleDiffEmpty : - sPlayerbotAIConfig->botActiveAloneSmartScaleDiffWithPlayer) * 1.1; - uint32 BracketSize = bg->GetMaxPlayersPerTeam() * 2; uint32 TeamSize = bg->GetMaxPlayersPerTeam(); - // If performance diff is enabled, only queue if there is no lag - if (sPlayerbotAIConfig->botActiveAloneSmartScale && !noLag) - return false; - // If the bot is in a group, only the leader can queue if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID())) return false; @@ -577,17 +569,10 @@ bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battleg return false; TeamId teamId = bot->GetTeamId(); - bool noLag = sWorldUpdateTime.GetAverageUpdateTime() < (sRandomPlayerbotMgr->GetPlayers().empty() ? - sPlayerbotAIConfig->botActiveAloneSmartScaleDiffEmpty : - sPlayerbotAIConfig->botActiveAloneSmartScaleDiffWithPlayer) * 1.1; uint32 BracketSize = bg->GetMaxPlayersPerTeam() * 2; uint32 TeamSize = bg->GetMaxPlayersPerTeam(); - // If performance diff is enabled, only queue if there is no lag - if (sPlayerbotAIConfig->botActiveAloneSmartScale && !noLag) - return false; - // If the bot is in a group, only the leader can queue if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID())) return false;