diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index c7d23eed..0c220c81 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -1459,14 +1459,10 @@ 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, ... diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 94bc7d2d..4b037f7e 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -4095,7 +4095,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) @@ -4181,12 +4181,18 @@ ActivePiorityType PlayerbotAI::GetPriorityType(ActivityType activityType) return ActivePiorityType::PLAYER_GUILD; //IN_INACTIVE_MAP - if (bot->IsBeingTeleported() || !bot->IsInWorld() || !HasRealPlayers(bot->GetMap())) - return ActivePiorityType::IN_INACTIVE_MAP; + if (bot->IsBeingTeleported() || + !bot->IsInWorld() || + !HasRealPlayers(bot->GetMap()) || + !bot->GetMap()->IsGridLoaded(bot->GetPositionX(), bot->GetPositionY())) + return ActivePiorityType::IN_INACTIVE_MAP; //IN_ACTIVE_MAP - if (!bot->IsBeingTeleported() && bot->IsInWorld() && HasRealPlayers(bot->GetMap())) - return ActivePiorityType::IN_ACTIVE_MAP; + if (!bot->IsBeingTeleported() && + bot->IsInWorld() && + HasRealPlayers(bot->GetMap()) && + bot->GetMap()->IsGridLoaded(bot->GetPositionX(), bot->GetPositionY())) + return ActivePiorityType::IN_ACTIVE_MAP; // IN_ACTIVE_AREA if (activityType == OUT_OF_PARTY_ACTIVITY || activityType == GRIND_ACTIVITY) @@ -4198,46 +4204,6 @@ ActivePiorityType PlayerbotAI::GetPriorityType(ActivityType activityType) return ActivePiorityType::IN_ACTIVE_AREA; } -// 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) -{ - 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::PLAYER_FRIEND: - case ActivePiorityType::PLAYER_GUILD: - return {0, 50}; - case ActivePiorityType::IN_ACTIVE_AREA: - return {30, 100}; - case ActivePiorityType::IN_ACTIVE_MAP: - return {50, 100}; - case ActivePiorityType::IN_INACTIVE_MAP: - return {70, 100}; - case ActivePiorityType::IN_EMPTY_SERVER: - return {80, 100}; - default: - return {90, 100}; - } - - return {90, 100}; -} - bool PlayerbotAI::AllowActive(ActivityType activityType) { // General exceptions @@ -4299,26 +4265,25 @@ bool PlayerbotAI::AllowActive(ActivityType activityType) } } - // GetPriorityBracket acitivity - float activePerc = 100; + uint32 botActiveAlonePerc = sPlayerbotAIConfig->botActiveAlone > 100 ? 100 : sPlayerbotAIConfig->botActiveAlone; + uint32 mod = botActiveAlonePerc; + if (botActiveAlonePerc <= 0) return false; + if (botActiveAlonePerc >= 100) return true; + 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) ? sPlayerbotAIConfig->botActiveAlone : 100; + // float activityPercentage = sRandomPlayerbotMgr->getActivityPercentage(); + 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); + //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, + 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 +4300,70 @@ bool PlayerbotAI::AllowActivity(ActivityType activityType, bool checkNow) return allowed; } +uint32 PlayerbotAI::SmartScaleActivity(ActivePiorityType type, uint32 botActiveAlonePerc) +{ + uint32 maxDiff = sWorldUpdateTime.GetPercentile(90); + //uint32 maxDiff = sWorldUpdateTime.GetMaxUpdateTimeOfCurrentTable(); + //uint32 maxDiff = sWorldUpdateTime.GetMaxUpdateTime(); + if (maxDiff > 500) + return 0; + + float ActivePiorityTypeMod = 1; + 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: + // we always enforce 100% with the above acitivities + // otherwise it will effect the pve gameplay. + return 100; + case ActivePiorityType::IS_ALWAYS_ACTIVE: + case ActivePiorityType::IN_COMBAT: + ActivePiorityTypeMod = 0.9; + break; + case ActivePiorityType::IN_BG_QUEUE: + case ActivePiorityType::IN_LFG: + ActivePiorityTypeMod = 0.7; + break; + case ActivePiorityType::NEARBY_PLAYER: + case ActivePiorityType::PLAYER_FRIEND: + case ActivePiorityType::PLAYER_GUILD: + case ActivePiorityType::IN_ACTIVE_AREA: + ActivePiorityTypeMod = 0.6; + break; + case ActivePiorityType::IN_ACTIVE_MAP: + case ActivePiorityType::IN_INACTIVE_MAP: + ActivePiorityTypeMod = 0.5; + break; + case ActivePiorityType::IN_EMPTY_SERVER: + ActivePiorityTypeMod = 0.4; + break; + default: + ActivePiorityTypeMod = 0.5; + break; + } + + if (maxDiff > 250) + return ActivePiorityTypeMod * (botActiveAlonePerc * 2) / 10; + if (maxDiff > 220) + return ActivePiorityTypeMod * (botActiveAlonePerc * 3) / 10; + if (maxDiff > 190) + return ActivePiorityTypeMod * (botActiveAlonePerc * 4) / 10; + if (maxDiff > 160) + return ActivePiorityTypeMod * (botActiveAlonePerc * 5) / 10; + if (maxDiff > 130) + return ActivePiorityTypeMod * (botActiveAlonePerc * 6) / 10; + if (maxDiff > 100) + return ActivePiorityTypeMod * (botActiveAlonePerc * 8) / 10; + if (maxDiff > 80) + return ActivePiorityTypeMod * (botActiveAlonePerc * 9) / 10; + + + 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..90024f2b 100644 --- a/src/PlayerbotAI.h +++ b/src/PlayerbotAI.h @@ -547,9 +547,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..53a7b720 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -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 9991144a..8ace6b8d 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)) @@ -402,27 +397,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..7d0670e2 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; 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;