Skip to content

Commit

Permalink
Feature: Have bots auto join/start all supported BG's (if enabled) (#877
Browse files Browse the repository at this point in the history
)

* Update RandomPlayerbotMgr.cpp

* Update playerbots.conf.dist

* Update PlayerbotAIConfig.h

* Update PlayerbotAIConfig.cpp

* Update playerbots.conf.dist

* Update playerbots.conf.dist

* Updated information

* Update RandomPlayerbotMgr.cpp

Avoid reverting https://github.com/liyunfan1223/mod-playerbots/pull/870/files

* Update playerbots.conf.dist

set capitals on Random

* Final update on settings documentation

* Update playerbots.conf.dist

* Fix bots loving to do BG's a bit too much

* Final fix bots over-queuing

* pt2 - Limit over-queuing to ~1 instance

Try and prevent over-queuing to a max of 1 instance.

* Add new queue instead of instance if necessary

* Update RandomPlayerbotMgr.cpp

* Final commit

* Update RandomPlayerbotMgr.cpp

* Fix timer

* Updated docu

* Update playerbots.conf.dist

* Update RandomPlayerbotMgr.cpp

Set BgCheckTimer to 45 as it is sufficient.
  • Loading branch information
nl-saw authored Jan 20, 2025
1 parent 2025fa4 commit be21018
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 70 deletions.
56 changes: 47 additions & 9 deletions conf/playerbots.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -768,18 +768,56 @@ AiPlayerbot.AutoTeleportForLevel = 1
# Enable BG/Arena for random Bots
AiPlayerbot.RandomBotJoinBG = 1

# Enable Auto join BG - bots randomly join WSG and 2v2 Arena if server is not lagging
# Enable Auto join BG - have bots start BG's and Arenas on their own
AiPlayerbot.RandomBotAutoJoinBG = 0

# Required for RandomBotAutoJoinBG
# Currently you can select 1 bracket (level range) for bots to auto join.
# Brackets for warsong 0:10-19, 1:20-29, 2:30-39, 3:40-49 etc. Default: 7 (level 80)
# Brackets for rated arena: 0:10-14, 1:15-19 etc. Default: 14 (80-84)
# For lower level ranges to work in Rated Arena, custom code changes need to be made.
# Count = amount of games Bots auto fill. (Count 1 for WSG = 20 bots).
AiPlayerbot.RandomBotAutoJoinWarsongBracket = 7
# Required Configuration for RandomBotAutoJoinBG
#
# Known issue: When enabling a lot of brackats in combination with multiple instances,
# can lead to more instances created by bots than intended (over-queuing).
#
# This section controls the level brackets and
# automatic bot participation in battlegrounds and arenas.
#
# Brackets:
# - Specify the level ranges for bots to auto-join:
# - Warsong Gulch (WS): 0 = 10-19, 1 = 20-29, 2 = 30-39, ..., 7 = 80 (default: 7)
# - Rated Arena: 0 = 10-14, 1 = 15-19, ..., 14 = 80-84 (default: 14)
# - Multiple brackets can be specified as a comma-separated list (e.g., "0,2,5").
#
# Counts:
# - Specify the number of Battlegrounds to auto-fill per bracket.
# - For battlegrounds, Count is the number of bots per bracket. For example:
# - Warsong Gulch Count = 1 adds 20 bots (10 per team).
# - Ensure there are enough eligible bots to meet the specified counts.
#
# Arena Considerations:
# - Rated Arena brackets default to level 80-84 (bracket 14).
# - Custom code changes are required for lower-level arena brackets to function properly.
#
# Battleground bracket range possibilities:
# AiPlayerbot.RandomBotAutoJoinICBrackets = 0,1
# AiPlayerbot.RandomBotAutoJoinEYBrackets = 0,1,2
# AiPlayerbot.RandomBotAutoJoinAVBrackets = 0,1,2,3
# AiPlayerbot.RandomBotAutoJoinABBrackets = 0,1,2,3,4,5,6
# AiPlayerbot.RandomBotAutoJoinWSBrackets = 0,1,2,3,4,5,6,7

AiPlayerbot.RandomBotAutoJoinICBrackets = 1
AiPlayerbot.RandomBotAutoJoinEYBrackets = 2
AiPlayerbot.RandomBotAutoJoinAVBrackets = 3
AiPlayerbot.RandomBotAutoJoinABBrackets = 6
AiPlayerbot.RandomBotAutoJoinWSBrackets = 7

# Battlegrounds count (per bracket!):
AiPlayerbot.RandomBotAutoJoinBGICCount = 0
AiPlayerbot.RandomBotAutoJoinBGEYCount = 1
AiPlayerbot.RandomBotAutoJoinBGAVCount = 0
AiPlayerbot.RandomBotAutoJoinBGABCount = 1
AiPlayerbot.RandomBotAutoJoinBGWSCount = 1

# Arena configuration:
AiPlayerbot.RandomBotAutoJoinArenaBracket = 14
AiPlayerbot.RandomBotAutoJoinBGWarsongCount = 0

AiPlayerbot.RandomBotAutoJoinBGRatedArena2v2Count = 0
AiPlayerbot.RandomBotAutoJoinBGRatedArena3v3Count = 0
AiPlayerbot.RandomBotAutoJoinBGRatedArena5v5Count = 0
Expand Down
16 changes: 14 additions & 2 deletions src/PlayerbotAIConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,21 @@ bool PlayerbotAIConfig::Initialize()

randomBotJoinBG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinBG", true);
randomBotAutoJoinBG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutoJoinBG", false);
randomBotAutoJoinWarsongBracket = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinWarsongBracket", 14);

randomBotAutoJoinArenaBracket = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinArenaBracket", 7);
randomBotAutoJoinBGWarsongCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGWarsongCount", 0);

randomBotAutoJoinICBrackets = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotAutoJoinICBrackets", "0,1");
randomBotAutoJoinEYBrackets = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotAutoJoinEYBrackets", "0,1,2");
randomBotAutoJoinAVBrackets = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotAutoJoinAVBrackets", "0,1,2,3");
randomBotAutoJoinABBrackets = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotAutoJoinABBrackets", "0,1,2,3,4,5,6");
randomBotAutoJoinWSBrackets = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotAutoJoinWSBrackets", "0,1,2,3,4,5,6,7");

randomBotAutoJoinBGICCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGICCount", 0);
randomBotAutoJoinBGEYCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGEYCount", 0);
randomBotAutoJoinBGAVCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGAVCount", 0);
randomBotAutoJoinBGABCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGABCount", 0);
randomBotAutoJoinBGWSCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGWSCount", 0);

randomBotAutoJoinBGRatedArena2v2Count =
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena2v2Count", 0);
randomBotAutoJoinBGRatedArena3v3Count =
Expand Down
17 changes: 15 additions & 2 deletions src/PlayerbotAIConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,25 @@ class PlayerbotAIConfig

bool randomBotJoinBG;
bool randomBotAutoJoinBG;
uint32 randomBotAutoJoinWarsongBracket;

std::string randomBotAutoJoinICBrackets;
std::string randomBotAutoJoinEYBrackets;
std::string randomBotAutoJoinAVBrackets;
std::string randomBotAutoJoinABBrackets;
std::string randomBotAutoJoinWSBrackets;

uint32 randomBotAutoJoinBGICCount;
uint32 randomBotAutoJoinBGEYCount;
uint32 randomBotAutoJoinBGAVCount;
uint32 randomBotAutoJoinBGABCount;
uint32 randomBotAutoJoinBGWSCount;

uint32 randomBotAutoJoinArenaBracket;
uint32 randomBotAutoJoinBGWarsongCount;

uint32 randomBotAutoJoinBGRatedArena2v2Count;
uint32 randomBotAutoJoinBGRatedArena3v3Count;
uint32 randomBotAutoJoinBGRatedArena5v5Count;

bool randomBotLoginAtStartup;
uint32 randomBotTeleLowerLevel, randomBotTeleHigherLevel;
bool logInGroupOnly, logValuesPerTick;
Expand Down
133 changes: 76 additions & 57 deletions src/RandomPlayerbotMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ void RandomPlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/)

if (sPlayerbotAIConfig->randomBotJoinBG /* && !players.empty()*/)
{
if (time(nullptr) > (BgCheckTimer + 30))
if (time(nullptr) > (BgCheckTimer + 45))
sRandomPlayerbotMgr->CheckBgQueue();
}

Expand Down Expand Up @@ -622,20 +622,39 @@ void RandomPlayerbotMgr::LoadBattleMastersCache()
LOG_INFO("playerbots", ">> Loaded {} battlemaster entries", count);
}

std::vector<uint32> parseBrackets(const std::string& str)
{
std::vector<uint32> brackets;
std::stringstream ss(str);
std::string item;

while (std::getline(ss, item, ','))
{
brackets.push_back(static_cast<uint32>(std::stoi(item)));
}

return brackets;
}

void RandomPlayerbotMgr::CheckBgQueue()
{
if (!BgCheckTimer)
if (!BgCheckTimer) {
BgCheckTimer = time(nullptr);
return; // Exit immediately after initializing the timer
}

if (time(nullptr) < BgCheckTimer + 30)
return;
if (time(nullptr) < BgCheckTimer) {
return; // No need to proceed if the current time is less than the timer
}

// Update the timer to the current time
BgCheckTimer = time(nullptr);

LOG_DEBUG("playerbots", "Checking BG Queue...");

BattlegroundData.clear();

// Initialize Battleground Data
for (int bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket)
{
for (int queueType = BATTLEGROUND_QUEUE_AV; queueType < MAX_BATTLEGROUND_QUEUE_TYPES; ++queueType)
Expand All @@ -644,6 +663,7 @@ void RandomPlayerbotMgr::CheckBgQueue()
}
}

// Process players
for (Player* player : players)
{
if (!player->InBattlegroundQueue())
Expand All @@ -654,6 +674,7 @@ void RandomPlayerbotMgr::CheckBgQueue()
continue;

TeamId teamId = player->GetTeamId();

for (uint8 queueType = 0; queueType < PLAYER_MAX_BATTLEGROUND_QUEUES; ++queueType)
{
BattlegroundQueueTypeId queueTypeId = player->GetBattlegroundQueueTypeId(queueType);
Expand All @@ -668,7 +689,6 @@ void RandomPlayerbotMgr::CheckBgQueue()
continue;

BattlegroundBracketId bracketId = pvpDiff->GetBracketId();

BattlegroundData[queueTypeId][bracketId].minLevel = pvpDiff->minLevel;
BattlegroundData[queueTypeId][bracketId].maxLevel = pvpDiff->maxLevel;

Expand All @@ -680,12 +700,10 @@ void RandomPlayerbotMgr::CheckBgQueue()

if (bgQueue.GetPlayerGroupInfoData(player->GetGUID(), &ginfo))
{
if (ginfo.IsRated)
isRated = true;
isRated = ginfo.IsRated;
}

if (bgQueue.IsPlayerInvitedToRatedArena(player->GetGUID()) ||
(player->InArena() && player->GetBattleground()->isRated()))
if (bgQueue.IsPlayerInvitedToRatedArena(player->GetGUID()) || (player->InArena() && player->GetBattleground()->isRated()))
isRated = true;

if (isRated)
Expand Down Expand Up @@ -728,16 +746,10 @@ void RandomPlayerbotMgr::CheckBgQueue()
}
}

for (PlayerBotMap::iterator i = playerBots.begin(); i != playerBots.end(); ++i)
// Process player bots
for (auto& [guid, bot] : playerBots)
{
Player* bot = i->second;
if (!bot || !bot->IsInWorld())
continue;

if (!bot->InBattlegroundQueue())
continue;

if (!IsRandomBot(bot))
if (!bot || !bot->IsInWorld() || !bot->InBattlegroundQueue() || !IsRandomBot(bot))
continue;

Battleground* bg = bot->GetBattleground();
Expand All @@ -760,7 +772,6 @@ void RandomPlayerbotMgr::CheckBgQueue()
continue;

BattlegroundBracketId bracketId = pvpDiff->GetBracketId();

BattlegroundData[queueTypeId][bracketId].minLevel = pvpDiff->minLevel;
BattlegroundData[queueTypeId][bracketId].maxLevel = pvpDiff->maxLevel;

Expand All @@ -772,12 +783,10 @@ void RandomPlayerbotMgr::CheckBgQueue()

if (bgQueue.GetPlayerGroupInfoData(bot->GetGUID(), &ginfo))
{
if (ginfo.IsRated)
isRated = true;
isRated = ginfo.IsRated;
}

if (bgQueue.IsPlayerInvitedToRatedArena(bot->GetGUID()) ||
(bot->InArena() && bot->GetBattleground()->isRated()))
if (bgQueue.IsPlayerInvitedToRatedArena(bot->GetGUID()) || (bot->InArena() && bot->GetBattleground()->isRated()))
isRated = true;

if (isRated)
Expand Down Expand Up @@ -818,11 +827,8 @@ void RandomPlayerbotMgr::CheckBgQueue()
instanceIds = &BattlegroundData[queueTypeId][bracketId].bgInstances;
}

if (instanceIds)
{
if (std::find(instanceIds->begin(), instanceIds->end(), instanceId) == instanceIds->end())
instanceIds->push_back(instanceId);
}
if (instanceIds && std::find(instanceIds->begin(), instanceIds->end(), instanceId) == instanceIds->end())
instanceIds->push_back(instanceId);

if (isArena)
{
Expand All @@ -839,39 +845,52 @@ void RandomPlayerbotMgr::CheckBgQueue()
}
}

// Increase instance count if Bots are required to autojoin BG/Arenas
if (sPlayerbotAIConfig->randomBotAutoJoinBG)
// If enabled, wait for all bots to have logged in before queueing for Arena's / BG's
if (sPlayerbotAIConfig->randomBotAutoJoinBG && playerBots.size() >= GetMaxAllowedBotCount())
{
uint32 randomBotAutoJoinArenaBracket = sPlayerbotAIConfig->randomBotAutoJoinArenaBracket;
uint32 randomBotAutoJoinWarsongBracket = sPlayerbotAIConfig->randomBotAutoJoinWarsongBracket;
uint32 randomBotAutoJoinArenaBracket = sPlayerbotAIConfig->randomBotAutoJoinArenaBracket;
uint32 randomBotAutoJoinBGRatedArena2v2Count = sPlayerbotAIConfig->randomBotAutoJoinBGRatedArena2v2Count;
uint32 randomBotAutoJoinBGRatedArena3v3Count = sPlayerbotAIConfig->randomBotAutoJoinBGRatedArena3v3Count;
uint32 randomBotAutoJoinBGRatedArena5v5Count = sPlayerbotAIConfig->randomBotAutoJoinBGRatedArena5v5Count;
uint32 randomBotAutoJoinBGWarsongCount = sPlayerbotAIConfig->randomBotAutoJoinBGWarsongCount;

BattlegroundData[BATTLEGROUND_QUEUE_2v2][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount =
std::max(randomBotAutoJoinBGRatedArena2v2Count,
(BattlegroundData[BATTLEGROUND_QUEUE_2v2][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount -
randomBotAutoJoinBGRatedArena2v2Count) +
randomBotAutoJoinBGRatedArena2v2Count);

BattlegroundData[BATTLEGROUND_QUEUE_3v3][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount =
std::max(randomBotAutoJoinBGRatedArena3v3Count,
(BattlegroundData[BATTLEGROUND_QUEUE_3v3][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount -
randomBotAutoJoinBGRatedArena3v3Count) +
randomBotAutoJoinBGRatedArena3v3Count);

BattlegroundData[BATTLEGROUND_QUEUE_5v5][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount =
std::max(randomBotAutoJoinBGRatedArena5v5Count,
(BattlegroundData[BATTLEGROUND_QUEUE_5v5][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount -
randomBotAutoJoinBGRatedArena5v5Count) +
randomBotAutoJoinBGRatedArena5v5Count);

BattlegroundData[BATTLEGROUND_QUEUE_WS][randomBotAutoJoinWarsongBracket].bgInstanceCount =
std::max(randomBotAutoJoinBGWarsongCount,
(BattlegroundData[BATTLEGROUND_QUEUE_WS][randomBotAutoJoinWarsongBracket].bgInstanceCount -
randomBotAutoJoinBGWarsongCount) +
randomBotAutoJoinBGWarsongCount);

uint32 randomBotAutoJoinBGICCount = sPlayerbotAIConfig->randomBotAutoJoinBGICCount;
uint32 randomBotAutoJoinBGEYCount = sPlayerbotAIConfig->randomBotAutoJoinBGEYCount;
uint32 randomBotAutoJoinBGAVCount = sPlayerbotAIConfig->randomBotAutoJoinBGAVCount;
uint32 randomBotAutoJoinBGABCount = sPlayerbotAIConfig->randomBotAutoJoinBGABCount;
uint32 randomBotAutoJoinBGWSCount = sPlayerbotAIConfig->randomBotAutoJoinBGWSCount;

std::vector<uint32> icBrackets = parseBrackets(sPlayerbotAIConfig->randomBotAutoJoinICBrackets);
std::vector<uint32> eyBrackets = parseBrackets(sPlayerbotAIConfig->randomBotAutoJoinEYBrackets);
std::vector<uint32> avBrackets = parseBrackets(sPlayerbotAIConfig->randomBotAutoJoinAVBrackets);
std::vector<uint32> abBrackets = parseBrackets(sPlayerbotAIConfig->randomBotAutoJoinABBrackets);
std::vector<uint32> wsBrackets = parseBrackets(sPlayerbotAIConfig->randomBotAutoJoinWSBrackets);

auto updateRatedArenaInstanceCount = [&](uint32 queueType, uint32 bracket, uint32 minCount) {
if (BattlegroundData[queueType][bracket].activeRatedArenaQueue == 0 &&
BattlegroundData[queueType][bracket].ratedArenaInstanceCount < minCount)
BattlegroundData[queueType][bracket].activeRatedArenaQueue = 1;
};

auto updateBGInstanceCount = [&](uint32 queueType, std::vector<uint32> brackets, uint32 minCount) {
for (uint32 bracket : brackets)
{
if (BattlegroundData[queueType][bracket].activeBgQueue == 0 &&
BattlegroundData[queueType][bracket].bgInstanceCount < minCount)
BattlegroundData[queueType][bracket].activeBgQueue = 1;
}
};

// Update rated arena instance counts
updateRatedArenaInstanceCount(BATTLEGROUND_QUEUE_2v2, randomBotAutoJoinArenaBracket, randomBotAutoJoinBGRatedArena2v2Count);
updateRatedArenaInstanceCount(BATTLEGROUND_QUEUE_3v3, randomBotAutoJoinArenaBracket, randomBotAutoJoinBGRatedArena3v3Count);
updateRatedArenaInstanceCount(BATTLEGROUND_QUEUE_5v5, randomBotAutoJoinArenaBracket, randomBotAutoJoinBGRatedArena5v5Count);

// Update battleground instance counts
updateBGInstanceCount(BATTLEGROUND_QUEUE_IC, icBrackets, randomBotAutoJoinBGICCount);
updateBGInstanceCount(BATTLEGROUND_QUEUE_EY, eyBrackets, randomBotAutoJoinBGEYCount);
updateBGInstanceCount(BATTLEGROUND_QUEUE_AV, avBrackets, randomBotAutoJoinBGAVCount);
updateBGInstanceCount(BATTLEGROUND_QUEUE_AB, abBrackets, randomBotAutoJoinBGABCount);
updateBGInstanceCount(BATTLEGROUND_QUEUE_WS, wsBrackets, randomBotAutoJoinBGWSCount);
}

LogBattlegroundInfo();
Expand Down

0 comments on commit be21018

Please sign in to comment.