diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index d673cd53e..69c84b4f2 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -89,11 +89,21 @@ AiPlayerbot.MinRandomBots = 500 AiPlayerbot.MaxRandomBots = 500 # Randombot accounts -# If you are not using any expansion at all, you may have to set this manually, in which case please -# ensure that RandomBotAccountCount is at least greater than (MaxRandomBots / 10 + AddClassAccountPoolSize) +# Set to 0 to automatically calculate needed accounts based on MaxRandomBots, EnablePeriodicOnlineOffline +# and its ratio, and AddClassAccountPoolSize. Set manually if you want to create more accounts than needed. +# If the manual value is less than the required, the system will override it with the required value. # Default: 0 (automatic) AiPlayerbot.RandomBotAccountCount = 0 +# Addclass accounts +# Number of accounts created for bots reserved for the addclass command. As with randombots, each account has +# 10 bots (or 9 if WotLK is disabled), one bot for each class. +AiPlayerbot.AddClassAccountPoolSize = 50 + +# Prefix for created bot accounts (of any type). +# Do not change this prefix while there are existing bot accounts. +AiPlayerbot.RandomBotAccountPrefix = "rndbot" + # Delete all randombot accounts # To apply this, set the number to 1 and run the Worldserver. Once deletion is complete, if you would # like to recreate randombots, set the number back to 0 and rerun the Worldserver. @@ -128,9 +138,6 @@ AiPlayerbot.MaxAddedBots = 40 # Default: 1 (enabled) AiPlayerbot.AddClassCommand = 1 -# Set the addclass command account pool size -AiPlayerbot.AddClassAccountPoolSize = 50 - # Bot group invitation permission level (0 = GM only, 1 = accept based on level, 2 = always accept) # Default: 1 (accept based on level) AiPlayerbot.GroupInvitationPermission = 1 @@ -680,9 +687,6 @@ AiPlayerbot.EndFishingWithMaster = 30.0 # Enable/Disable randomly generated password for randombot accounts AiPlayerbot.RandomBotRandomPassword = 0 -# Prefix for account names to create for randombots -AiPlayerbot.RandomBotAccountPrefix = "rndbot" - # Minimum and maximum levels for randombots AiPlayerbot.RandomBotMinLevel = 1 AiPlayerbot.RandomBotMaxLevel = 80 diff --git a/src/Bot/Factory/RandomPlayerbotFactory.cpp b/src/Bot/Factory/RandomPlayerbotFactory.cpp index 530715191..6e5005723 100644 --- a/src/Bot/Factory/RandomPlayerbotFactory.cpp +++ b/src/Bot/Factory/RandomPlayerbotFactory.cpp @@ -334,18 +334,12 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount() sPlayerbotAIConfig.addClassAccountPoolSize == 0 ? 2 : -1); if (!res || res->Fetch()[0].Get() == 0) - { break; - } std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Extra 50ms fixed delay for safety. } } - // Checks if randomBotAccountCount is set, otherwise calculate it dynamically. - if (sPlayerbotAIConfig.randomBotAccountCount > 0) - return sPlayerbotAIConfig.randomBotAccountCount; - // Check existing account types uint32 existingRndBotAccounts = 0; uint32 existingAddClassAccounts = 0; @@ -366,16 +360,14 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount() } while (typeCheck->NextRow()); } - // Determine divisor based on Death Knight login eligibility and requested A&H faction ratio + // Determine divisor based on Death Knight availability and requested A&H faction ratio int divisor = CalculateAvailableCharsPerAccount(); // Calculate max bots int maxBots = sPlayerbotAIConfig.maxRandomBots; - // Take periodic online - offline into account + // Take periodic online/offline into account if (sPlayerbotAIConfig.enablePeriodicOnlineOffline) - { maxBots *= sPlayerbotAIConfig.periodicOnlineOfflineRatio; - } // Calculate number of accounts needed for RNDbots // Result is rounded up for maxBots not cleanly divisible by the divisor @@ -416,11 +408,22 @@ uint32 RandomPlayerbotFactory::CalculateTotalAccountCount() } // Return existing total plus any additional accounts needed - return existingTotal + additionalAccountsNeeded; + uint32 calculatedTotal = existingTotal + additionalAccountsNeeded; + + // Manually set randomBotAccountCount meets the requirements + if (sPlayerbotAIConfig.randomBotAccountCount >= calculatedTotal) + return sPlayerbotAIConfig.randomBotAccountCount; + // Manually set randomBotAccountCount doesn't meet the requirements. Using calculated value + if (sPlayerbotAIConfig.randomBotAccountCount > 0) + LOG_WARN("playerbots", "RandomBotAccountCount ({}) is lower than the required calculated value ({}). Using the calculated value instead.", + sPlayerbotAIConfig.randomBotAccountCount, calculatedTotal); + + return calculatedTotal; } uint32 RandomPlayerbotFactory::CalculateAvailableCharsPerAccount() { + // Death Knight availability according to their login eligibility, and if WotLK is enabled at all. bool noDK = sPlayerbotAIConfig.disableDeathKnightLogin || sWorld->getIntConfig(CONFIG_EXPANSION) != EXPANSION_WRATH_OF_THE_LICH_KING; uint32 availableChars = noDK ? 9 : 10; @@ -434,11 +437,9 @@ uint32 RandomPlayerbotFactory::CalculateAvailableCharsPerAccount() float unavailableRatio = static_cast((std::max(hordeRatio, allianceRatio) - std::min(hordeRatio, allianceRatio))) / (std::max(hordeRatio, allianceRatio) * 2); + // Conservative floor to ensure enough characters (may result in more accounts than needed). if (unavailableRatio != 0) - { - // conservative floor to ensure enough chars (may result in more accounts than needed) availableChars = availableChars - availableChars * unavailableRatio; - } return availableChars; }