From f1114d71d204cb71780654b6c5e56c52ef676daf Mon Sep 17 00:00:00 2001 From: CrypticAvacado <176721594+CrypticAvacado@users.noreply.github.com> Date: Mon, 29 Jul 2024 04:53:25 +1200 Subject: [PATCH] Fix rated arena and battleground bot autojoining --- conf/playerbots.conf.dist | 13 + src/PlayerbotAIConfig.cpp | 6 + src/PlayerbotAIConfig.h | 6 + src/RandomPlayerbotMgr.cpp | 350 +++++++++------ src/RandomPlayerbotMgr.h | 37 +- .../actions/BattleGroundJoinAction.cpp | 422 +++++++----------- src/strategy/actions/BattleGroundJoinAction.h | 1 + 7 files changed, 440 insertions(+), 395 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index c3923270..e139795d 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -654,6 +654,19 @@ AiPlayerbot.RandomBotJoinBG = 1 # Enable Auto join BG - bots randomly join WSG and 2v2 Arena if server is not lagging 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 +AiPlayerbot.RandomBotAutoJoinArenaBracket = 14 +AiPlayerbot.RandomBotAutoJoinBGWarsongCount = 0 +AiPlayerbot.RandomBotAutoJoinBGRatedArena2v2Count = 0 +AiPlayerbot.RandomBotAutoJoinBGRatedArena3v3Count = 0 +AiPlayerbot.RandomBotAutoJoinBGRatedArena5v5Count = 0 + # Random bot arena team count # Teams are created when bots are initialized on server restart. # You may need to first delete all arena teams, then reinitialize bots. diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index 3a75bc40..84ef5ba4 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -146,6 +146,12 @@ bool PlayerbotAIConfig::Initialize() suggestDungeonsInLowerCaseRandomly = sConfigMgr->GetOption("AiPlayerbot.SuggestDungeonsInLowerCaseRandomly", false); randomBotJoinBG = sConfigMgr->GetOption("AiPlayerbot.RandomBotJoinBG", true); randomBotAutoJoinBG = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutoJoinBG", false); + randomBotAutoJoinWarsongBracket = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutoJoinWarsongBracket", 14); + randomBotAutoJoinArenaBracket = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutoJoinArenaBracket", 7); + randomBotAutoJoinBGWarsongCount = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutoJoinBGWarsongCount", 0); + randomBotAutoJoinBGRatedArena2v2Count = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutoJoinBGRatedArena2v2Count", 0); + randomBotAutoJoinBGRatedArena3v3Count = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutoJoinBGRatedArena3v3Count", 0); + randomBotAutoJoinBGRatedArena5v5Count = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutoJoinBGRatedArena5v5Count", 0); logInGroupOnly = sConfigMgr->GetOption("AiPlayerbot.LogInGroupOnly", true); logValuesPerTick = sConfigMgr->GetOption("AiPlayerbot.LogValuesPerTick", false); fleeingEnabled = sConfigMgr->GetOption("AiPlayerbot.FleeingEnabled", true); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index 986b1520..24ed0182 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -101,6 +101,12 @@ class PlayerbotAIConfig bool suggestDungeonsInLowerCaseRandomly; bool randomBotJoinBG; bool randomBotAutoJoinBG; + uint32 randomBotAutoJoinWarsongBracket; + uint32 randomBotAutoJoinArenaBracket; + uint32 randomBotAutoJoinBGWarsongCount; + uint32 randomBotAutoJoinBGRatedArena2v2Count; + uint32 randomBotAutoJoinBGRatedArena3v3Count; + uint32 randomBotAutoJoinBGRatedArena5v5Count; bool randomBotLoginAtStartup; uint32 randomBotTeleLowerLevel, randomBotTeleHigherLevel; bool logInGroupOnly, logValuesPerTick; diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index 639acd52..1ed25a76 100644 --- a/src/RandomPlayerbotMgr.cpp +++ b/src/RandomPlayerbotMgr.cpp @@ -192,22 +192,7 @@ RandomPlayerbotMgr::RandomPlayerbotMgr() : PlayerbotHolder(), processTicks(0), t PrepareTeleportCache(); } - for (uint8 i = BG_BRACKET_ID_FIRST; i < MAX_BATTLEGROUND_BRACKETS; ++i) - { - for (uint8 j = BATTLEGROUND_QUEUE_AV; j < MAX_BATTLEGROUND_QUEUE_TYPES; ++j) - { - BgPlayers[j][i][TEAM_ALLIANCE] = 0; - BgPlayers[j][i][TEAM_HORDE] = 0; - BgBots[j][i][TEAM_ALLIANCE] = 0; - BgBots[j][i][TEAM_HORDE] = 0; - ArenaBots[j][i][TEAM_ALLIANCE][TEAM_ALLIANCE] = 0; - ArenaBots[j][i][TEAM_ALLIANCE][TEAM_HORDE] = 0; - ArenaBots[j][i][TEAM_HORDE][TEAM_ALLIANCE] = 0; - ArenaBots[j][i][TEAM_HORDE][TEAM_HORDE] = 0; - NeedBots[j][i][TEAM_ALLIANCE] = false; - NeedBots[j][i][TEAM_HORDE] = false; - } - } + BattlegroundData.clear(); BgCheckTimer = 0; LfgCheckTimer = 0; @@ -617,22 +602,7 @@ void RandomPlayerbotMgr::CheckBgQueue() LOG_INFO("playerbots", "Checking BG Queue..."); - for (uint32 i = BG_BRACKET_ID_FIRST; i < MAX_BATTLEGROUND_BRACKETS; ++i) - { - for (uint32 j = BATTLEGROUND_QUEUE_AV; j < MAX_BATTLEGROUND_QUEUE_TYPES; ++j) - { - BgPlayers[j][i][TEAM_ALLIANCE] = 0; - BgPlayers[j][i][TEAM_HORDE] = 0; - BgBots[j][i][TEAM_ALLIANCE] = 0; - BgBots[j][i][TEAM_HORDE] = 0; - ArenaBots[j][i][TEAM_ALLIANCE][TEAM_ALLIANCE] = 0; - ArenaBots[j][i][TEAM_ALLIANCE][TEAM_HORDE] = 0; - ArenaBots[j][i][TEAM_HORDE][TEAM_ALLIANCE] = 0; - ArenaBots[j][i][TEAM_HORDE][TEAM_HORDE] = 0; - NeedBots[j][i][TEAM_ALLIANCE] = false; - NeedBots[j][i][TEAM_HORDE] = false; - } - } + BattlegroundData.clear(); for (Player* player : players) { @@ -642,14 +612,13 @@ void RandomPlayerbotMgr::CheckBgQueue() if (player->InBattleground() && player->GetBattleground()->GetStatus() == STATUS_WAIT_LEAVE) continue; - for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + TeamId teamId = player->GetTeamId(); + for (uint8 queueType = 0; queueType < PLAYER_MAX_BATTLEGROUND_QUEUES; ++queueType) { - BattlegroundQueueTypeId queueTypeId = player->GetBattlegroundQueueTypeId(i); + BattlegroundQueueTypeId queueTypeId = player->GetBattlegroundQueueTypeId(queueType); if (queueTypeId == BATTLEGROUND_QUEUE_NONE) continue; - TeamId teamId = player->GetTeamId(); - BattlegroundTypeId bgTypeId = sBattlegroundMgr->BGTemplateId(queueTypeId); Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); uint32 mapId = bg->GetMapId(); @@ -659,59 +628,59 @@ void RandomPlayerbotMgr::CheckBgQueue() BattlegroundBracketId bracketId = pvpDiff->GetBracketId(); + BattlegroundData[queueTypeId][bracketId].minLevel = pvpDiff->minLevel; + BattlegroundData[queueTypeId][bracketId].maxLevel = pvpDiff->maxLevel; + + bool isRated = false; if (uint8 arenaType = BattlegroundMgr::BGArenaType(queueTypeId)) { BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(queueTypeId); GroupQueueInfo ginfo; - TeamId tempT = teamId; if (bgQueue.GetPlayerGroupInfoData(player->GetGUID(), &ginfo)) { if (ginfo.IsRated) - { - for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) - { - uint32 arena_team_id = player->GetArenaTeamId(arena_slot); - ArenaTeam* arenateam = sArenaTeamMgr->GetArenaTeamById(arena_team_id); - if (!arenateam) - continue; - - if (arenateam->GetType() != arenaType) - continue; - - Rating[queueTypeId][bracketId][1] = arenateam->GetRating(); - } - } - - teamId = ginfo.IsRated ? TEAM_HORDE : TEAM_ALLIANCE; + isRated = true; } - if (player->InArena()) - { - if (player->GetBattleground()->isRated() && (ginfo.IsRated && ginfo.ArenaTeamId && ginfo.ArenaTeamRating && ginfo.OpponentsTeamRating)) - teamId = TEAM_HORDE; - else - teamId = TEAM_ALLIANCE; - } + if (bgQueue.IsPlayerInvitedToRatedArena(player->GetGUID()) || (player->InArena() && player->GetBattleground()->isRated())) + isRated = true; - ArenaBots[queueTypeId][bracketId][teamId][tempT]++; + if (isRated) + BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount++; + else + BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount++; } - - if (GET_PLAYERBOT_AI(player)) - BgBots[queueTypeId][bracketId][teamId]++; else - BgPlayers[queueTypeId][bracketId][teamId]++; - - if (!player->IsInvitedForBattlegroundInstance() && (!player->InBattleground() || (player->GetBattleground() && player->GetBattleground()->GetBgTypeID() != BattlegroundMgr::BGTemplateId(queueTypeId)))) { - if (BattlegroundMgr::BGArenaType(queueTypeId)) + if (GET_PLAYERBOT_AI(player)) { - NeedBots[queueTypeId][bracketId][teamId] = true; + if (teamId == TEAM_ALLIANCE) + BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount++; + else + BattlegroundData[queueTypeId][bracketId].bgHordeBotCount++; } else { - NeedBots[queueTypeId][bracketId][TEAM_ALLIANCE] = true; - NeedBots[queueTypeId][bracketId][TEAM_HORDE] = true; + if (teamId == TEAM_ALLIANCE) + BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount++; + else + BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount++; + } + } + + if (!player->IsInvitedForBattlegroundInstance() && !player->InBattleground()) + { + if (BattlegroundMgr::BGArenaType(queueTypeId)) + { + if (isRated) + BattlegroundData[queueTypeId][bracketId].activeRatedArenaQueue = 1; + else + BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue = 1; + } + else + { + BattlegroundData[queueTypeId][bracketId].activeBgQueue = 1; } } } @@ -732,14 +701,14 @@ void RandomPlayerbotMgr::CheckBgQueue() if (bot->InBattleground() && bot->GetBattleground()->GetStatus() == STATUS_WAIT_LEAVE) continue; - for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) + TeamId teamId = bot->GetTeamId(); + + for (uint8 queueType = 0; queueType < PLAYER_MAX_BATTLEGROUND_QUEUES; ++queueType) { - BattlegroundQueueTypeId queueTypeId = bot->GetBattlegroundQueueTypeId(i); + BattlegroundQueueTypeId queueTypeId = bot->GetBattlegroundQueueTypeId(queueType); if (queueTypeId == BATTLEGROUND_QUEUE_NONE) continue; - TeamId teamId = bot->GetTeamId(); - BattlegroundTypeId bgTypeId = sBattlegroundMgr->BGTemplateId(queueTypeId); Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); uint32 mapId = bg->GetMapId(); @@ -749,90 +718,191 @@ void RandomPlayerbotMgr::CheckBgQueue() BattlegroundBracketId bracketId = pvpDiff->GetBracketId(); - uint8 arenaType = BattlegroundMgr::BGArenaType(queueTypeId); - if (arenaType) + BattlegroundData[queueTypeId][bracketId].minLevel = pvpDiff->minLevel; + BattlegroundData[queueTypeId][bracketId].maxLevel = pvpDiff->maxLevel; + + if (uint8 arenaType = BattlegroundMgr::BGArenaType(queueTypeId)) { + bool isRated = false; BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(queueTypeId); GroupQueueInfo ginfo; - TeamId tempT = teamId; - if (bgQueue.GetPlayerGroupInfoData(bot->GetGUID(), &ginfo)) - teamId = ginfo.IsRated ? TEAM_HORDE : TEAM_ALLIANCE; - if (bot->InArena()) + if (bgQueue.GetPlayerGroupInfoData(bot->GetGUID(), &ginfo)) { - if (bot->GetBattleground()->isRated() && (ginfo.IsRated && ginfo.ArenaTeamId && ginfo.ArenaTeamRating && ginfo.OpponentsTeamRating)) - teamId = TEAM_HORDE; - else - teamId = TEAM_ALLIANCE; + if (ginfo.IsRated) + isRated = true; } - ArenaBots[queueTypeId][bracketId][teamId][tempT]++; + if (bgQueue.IsPlayerInvitedToRatedArena(bot->GetGUID()) || (bot->InArena() && bot->GetBattleground()->isRated())) + isRated = true; + + if (isRated) + BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount++; + else + BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount++; + } + else + { + if (teamId == TEAM_ALLIANCE) + BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount++; + else + BattlegroundData[queueTypeId][bracketId].bgHordeBotCount++; } - BgBots[queueTypeId][bracketId][teamId]++; + if(bot->InBattleground()) + { + std::vector* instanceIds = nullptr; + uint32 instanceId = bot->GetBattleground()->GetInstanceID(); + bool isArena = false; + bool isRated = false; + + if(bot->InArena()) + { + isArena = true; + if(bot->GetBattleground()->isRated()) + { + isRated = true; + instanceIds = &BattlegroundData[queueTypeId][bracketId].ratedArenaInstances; + } + else + { + instanceIds = &BattlegroundData[queueTypeId][bracketId].skirmishArenaInstances; + } + } + else + { + instanceIds = &BattlegroundData[queueTypeId][bracketId].bgInstances; + } + + if (instanceIds) + { + if (std::find(instanceIds->begin(), instanceIds->end(), instanceId) == instanceIds->end()) + instanceIds->push_back(instanceId); + } + + if (isArena) + { + if (isRated) + BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount = instanceIds->size(); + else + BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount = instanceIds->size(); + } + else + { + BattlegroundData[queueTypeId][bracketId].bgInstanceCount = instanceIds->size(); + } + } } } - for (uint8 i = BG_BRACKET_ID_FIRST; i < MAX_BATTLEGROUND_BRACKETS; ++i) + // Increase instance count if Bots are required to autojoin BG/Arenas + if (sPlayerbotAIConfig->randomBotAutoJoinBG) { - for (uint8 j = BATTLEGROUND_QUEUE_AV; j < MAX_BATTLEGROUND_QUEUE_TYPES; ++j) - { - BattlegroundQueueTypeId queueTypeId = BattlegroundQueueTypeId(j); + uint32 randomBotAutoJoinArenaBracket = sPlayerbotAIConfig->randomBotAutoJoinArenaBracket; + uint32 randomBotAutoJoinWarsongBracket = sPlayerbotAIConfig->randomBotAutoJoinWarsongBracket; + uint32 randomBotAutoJoinBGRatedArena2v2Count = sPlayerbotAIConfig->randomBotAutoJoinBGRatedArena2v2Count; + uint32 randomBotAutoJoinBGRatedArena3v3Count = sPlayerbotAIConfig->randomBotAutoJoinBGRatedArena3v3Count; + uint32 randomBotAutoJoinBGRatedArena5v5Count = sPlayerbotAIConfig->randomBotAutoJoinBGRatedArena5v5Count; + uint32 randomBotAutoJoinBGWarsongCount = sPlayerbotAIConfig->randomBotAutoJoinBGWarsongCount; - if ((BgPlayers[j][i][TEAM_ALLIANCE] + BgBots[j][i][TEAM_ALLIANCE] + BgPlayers[j][i][TEAM_HORDE] + BgBots[j][i][TEAM_HORDE]) == 0) - continue; + BattlegroundData[BATTLEGROUND_QUEUE_2v2][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount = + std::max( + randomBotAutoJoinBGRatedArena2v2Count, + (BattlegroundData[BATTLEGROUND_QUEUE_2v2][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount - + randomBotAutoJoinBGRatedArena2v2Count) + + randomBotAutoJoinBGRatedArena2v2Count + ); - if (uint8 type = BattlegroundMgr::BGArenaType(queueTypeId)) - { - LOG_INFO("playerbots", "ARENA:{} {}: Player (Skirmish:{}, Rated:{}) B (Skirmish:{}, Rated:{}) Total (Skirmish:{} Rated:{})", - type == ARENA_TYPE_2v2 ? "2v2" : type == ARENA_TYPE_3v3 ? "3v3" : "5v5", i == 0 ? "10-19" : i == 1 ? "20-29" : i == 2 ? "30-39" : i == 3 ? "40-49" : - i == 4 ? "50-59" : (i == 5 && MAX_BATTLEGROUND_BRACKETS == 6) ? "60" : (i == 5 && MAX_BATTLEGROUND_BRACKETS == 7) ? "60-69" : - i == 6 ? (i == 6 && MAX_BATTLEGROUND_BRACKETS == 16) ? "70-79" : "70" : "80", - BgPlayers[j][i][TEAM_ALLIANCE], BgPlayers[j][i][TEAM_HORDE], BgBots[j][i][TEAM_ALLIANCE], BgBots[j][i][TEAM_HORDE], - BgPlayers[j][i][TEAM_ALLIANCE] + BgBots[j][i][TEAM_ALLIANCE], BgPlayers[j][i][TEAM_HORDE] + BgBots[j][i][TEAM_HORDE]); + BattlegroundData[BATTLEGROUND_QUEUE_3v3][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount = + std::max( + randomBotAutoJoinBGRatedArena3v3Count, + (BattlegroundData[BATTLEGROUND_QUEUE_3v3][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount - + randomBotAutoJoinBGRatedArena3v3Count) + + randomBotAutoJoinBGRatedArena3v3Count + ); - continue; - } + BattlegroundData[BATTLEGROUND_QUEUE_5v5][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount = + std::max( + randomBotAutoJoinBGRatedArena5v5Count, + (BattlegroundData[BATTLEGROUND_QUEUE_5v5][randomBotAutoJoinArenaBracket].ratedArenaInstanceCount - + randomBotAutoJoinBGRatedArena5v5Count) + + randomBotAutoJoinBGRatedArena5v5Count + ); - BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId); - std::string _bgType; - switch (bgTypeId) - { - case BATTLEGROUND_AV: - _bgType = "AV"; - break; - case BATTLEGROUND_WS: - _bgType = "WSG"; - break; - case BATTLEGROUND_AB: - _bgType = "AB"; - break; - case BATTLEGROUND_EY: - _bgType = "EotS"; - break; - case BATTLEGROUND_RB: - _bgType = "Random"; - break; - case BATTLEGROUND_SA: - _bgType = "SotA"; - break; - case BATTLEGROUND_IC: - _bgType = "IoC"; - break; - default: - _bgType = "Other"; - break; - } - - LOG_INFO("playerbots", "BG:{} {}: Player ({}:{}) Bot ({}:{}) Total (A:{} H:{})", - _bgType, i == 0 ? "10-19" : i == 1 ? "20-29" : i == 2 ? "30-39" : i == 3 ? "40-49" : i == 4 ? "50-59" : (i == 5 && MAX_BATTLEGROUND_BRACKETS == 6) ? "60" : - (i == 5 && MAX_BATTLEGROUND_BRACKETS == 7) ? "60-69" : i == 6 ? (i == 6 && MAX_BATTLEGROUND_BRACKETS == 16) ? "70-79" : "70" : "80", - BgPlayers[j][i][TEAM_ALLIANCE], BgPlayers[j][i][TEAM_HORDE], BgBots[j][i][TEAM_ALLIANCE], BgBots[j][i][TEAM_HORDE], - BgPlayers[j][i][TEAM_ALLIANCE] + BgBots[j][i][TEAM_ALLIANCE], BgPlayers[j][i][TEAM_HORDE] + BgBots[j][i][TEAM_HORDE]); - } + BattlegroundData[BATTLEGROUND_QUEUE_WS][randomBotAutoJoinWarsongBracket].bgInstanceCount = + std::max( + randomBotAutoJoinBGWarsongCount, + (BattlegroundData[BATTLEGROUND_QUEUE_WS][randomBotAutoJoinWarsongBracket].bgInstanceCount - + randomBotAutoJoinBGWarsongCount) + + randomBotAutoJoinBGWarsongCount + ); } - LOG_INFO("playerbots", "BG Queue check finished"); + LogBattlegroundInfo(); +} + +void RandomPlayerbotMgr::LogBattlegroundInfo() +{ + for (const auto& queueTypePair : BattlegroundData) { + uint8 queueType = queueTypePair.first; + + BattlegroundQueueTypeId queueTypeId = BattlegroundQueueTypeId(queueType); + + if (uint8 type = BattlegroundMgr::BGArenaType(queueTypeId)) + { + for (const auto& bracketIdPair : queueTypePair.second) { + auto& bgInfo = bracketIdPair.second; + + LOG_INFO("playerbots", "ARENA:{} {}: Player (Skirmish:{}, Rated:{}) Bots (Skirmish:{}, Rated:{}) Total (Skirmish:{} Rated:{}), Instances (Skirmish:{} Rated:{})", + type == ARENA_TYPE_2v2 ? "2v2" : type == ARENA_TYPE_3v3 ? "3v3" : "5v5", std::to_string(bgInfo.minLevel) + "-" + std::to_string(bgInfo.maxLevel), + bgInfo.skirmishArenaPlayerCount, bgInfo.ratedArenaPlayerCount, bgInfo.skirmishArenaBotCount, bgInfo.ratedArenaBotCount, + bgInfo.skirmishArenaPlayerCount + bgInfo.skirmishArenaBotCount, bgInfo.ratedArenaPlayerCount + bgInfo.ratedArenaBotCount, + bgInfo.skirmishArenaInstanceCount, bgInfo.ratedArenaInstanceCount); + } + continue; + } + + BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId); + std::string _bgType; + switch (bgTypeId) + { + case BATTLEGROUND_AV: + _bgType = "AV"; + break; + case BATTLEGROUND_WS: + _bgType = "WSG"; + break; + case BATTLEGROUND_AB: + _bgType = "AB"; + break; + case BATTLEGROUND_EY: + _bgType = "EotS"; + break; + case BATTLEGROUND_RB: + _bgType = "Random"; + break; + case BATTLEGROUND_SA: + _bgType = "SotA"; + break; + case BATTLEGROUND_IC: + _bgType = "IoC"; + break; + default: + _bgType = "Other"; + break; + } + + for (const auto& bracketIdPair : queueTypePair.second) { + auto& bgInfo = bracketIdPair.second; + + LOG_INFO("playerbots", "BG:{} {}: Player ({}:{}) Bot ({}:{}) Total (A:{} H:{}), Instances {}", + _bgType, std::to_string(bgInfo.minLevel) + "-" + std::to_string(bgInfo.maxLevel), + bgInfo.bgAlliancePlayerCount, bgInfo.bgHordePlayerCount, bgInfo.bgAllianceBotCount, bgInfo.bgHordeBotCount, + bgInfo.bgAlliancePlayerCount + bgInfo.bgAllianceBotCount, bgInfo.bgHordePlayerCount + bgInfo.bgHordeBotCount, + bgInfo.bgInstanceCount); + } + } + LOG_INFO("playerbots", "====== BATTLEGROUND/ARENA Check Finished ======="); } void RandomPlayerbotMgr::CheckLfgQueue() diff --git a/src/RandomPlayerbotMgr.h b/src/RandomPlayerbotMgr.h index a79bd269..4d643dd9 100644 --- a/src/RandomPlayerbotMgr.h +++ b/src/RandomPlayerbotMgr.h @@ -7,6 +7,36 @@ #include "PlayerbotMgr.h" +struct BattlegroundInfo { + std::vector bgInstances; + std::vector ratedArenaInstances; + std::vector skirmishArenaInstances; + int bgInstanceCount = 0; + int ratedArenaInstanceCount = 0; + int skirmishArenaInstanceCount = 0; + int minLevel = 0; + int maxLevel = 0; + int activeRatedArenaQueue = 0; // 0 = Inactive, 1 = Active + int activeSkirmishArenaQueue = 0; // 0 = Inactive, 1 = Active + int activeBgQueue = 0; // 0 = Inactive, 1 = Active + + // Bots (Arena) + int ratedArenaBotCount = 0; + int skirmishArenaBotCount = 0; + + // Bots (Battleground) + int bgHordeBotCount = 0; + int bgAllianceBotCount = 0; + + // Players (Arena) + int ratedArenaPlayerCount = 0; + int skirmishArenaPlayerCount = 0; + + // Players (Battleground) + int bgHordePlayerCount = 0; + int bgAlliancePlayerCount = 0; +}; + class ChatHandler; class PerformanceMonitorOperation; class WorldLocation; @@ -111,17 +141,14 @@ class RandomPlayerbotMgr : public PlayerbotHolder ObjectGuid const GetBattleMasterGUID(Player* bot, BattlegroundTypeId bgTypeId); CreatureData const* GetCreatureDataByEntry(uint32 entry); void LoadBattleMastersCache(); - std::map>> NeedBots; - std::map>> BgBots; + std::map> BattlegroundData; std::map>> VisualBots; - std::map>> BgPlayers; - std::map>>> ArenaBots; - std::map>> Rating; std::map>> Supporters; std::map> LfgDungeons; void CheckBgQueue(); void CheckLfgQueue(); void CheckPlayers(); + void LogBattlegroundInfo(); std::map>> getBattleMastersCache() { return BattleMastersCache; } diff --git a/src/strategy/actions/BattleGroundJoinAction.cpp b/src/strategy/actions/BattleGroundJoinAction.cpp index 30d3c29f..e34d51d6 100644 --- a/src/strategy/actions/BattleGroundJoinAction.cpp +++ b/src/strategy/actions/BattleGroundJoinAction.cpp @@ -63,28 +63,15 @@ bool BGJoinAction::Execute(Event event) bool BGJoinAction::gatherArenaTeam(ArenaType type) { - ArenaTeam* arenateam = nullptr; - for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) - { - ArenaTeam* temp = sArenaTeamMgr->GetArenaTeamById(bot->GetArenaTeamId(arena_slot)); - if (!temp) - continue; - if (temp->GetCaptain() != bot->GetGUID()) - continue; - - if (temp->GetType() != type) - continue; - - if (temp->GetMembersSize() < ((uint32) temp->GetType())) - continue; - - arenateam = temp; - } + ArenaTeam* arenateam = sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID(), type); if (!arenateam) return false; + if (arenateam->GetMembersSize() < ((uint32) arenateam->GetType())) + return false; + GuidVector members; // search for arena team members and make them online @@ -120,6 +107,12 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type) if (member->GetGUID() == bot->GetGUID()) continue; + if(member->InBattleground()) + continue; + + if(member->InBattlegroundQueue()) + continue; + if (member->GetGroup()) member->GetGroup()->RemoveMember(member->GetGUID()); @@ -137,7 +130,6 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type) } Group* group = new Group(); - uint32 count = 1; // disband leaders group if (bot->GetGroup()) @@ -185,7 +177,6 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type) LOG_INFO("playerbots", "Bot {} <{}>: Member of <{}>", member->GetGUID().ToString().c_str(), member->GetName().c_str(), arenateam->GetName().c_str()); - count++; } if (group && group->GetMembersCount() >= (uint32)arenateam->GetType()) @@ -204,7 +195,7 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type) bool BGJoinAction::canJoinBg(BattlegroundQueueTypeId queueTypeId, BattlegroundBracketId bracketId) { - // check if bot can join this bg/bracket + // check if bot can join this bracket for the specific Battleground/Arena type BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId); // check if already in queue @@ -215,7 +206,7 @@ bool BGJoinAction::canJoinBg(BattlegroundQueueTypeId queueTypeId, BattlegroundBr if (!bot->GetBGAccessByLevel(bgTypeId)) return false; - // check bracket + // check if the bracket exists for the bot's level for the specific Battleground/Arena type Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); uint32 mapId = bg->GetMapId(); PvPDifficultyEntry const* pvpDiff = GetBattlegroundBracketByLevel(mapId, bot->GetLevel()); @@ -232,128 +223,86 @@ bool BGJoinAction::canJoinBg(BattlegroundQueueTypeId queueTypeId, BattlegroundBr bool BGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, BattlegroundBracketId bracketId) { - // check if bot should join (queue has real players) BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId); Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(bgTypeId); if (!bg) return false; - bool isArena = false; - bool isRated = false; + TeamId teamId = bot->GetTeamId(); bool noLag = sWorldUpdateTime.GetAverageUpdateTime() < (sRandomPlayerbotMgr->GetPlayers().empty() ? sPlayerbotAIConfig->diffEmpty : sPlayerbotAIConfig->diffWithPlayer) * 1.1; - ArenaType type = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId)); - if (type != ARENA_TYPE_NONE) - isArena = true; - - bool hasPlayers = (sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE]) > 0; - bool hasBots = (sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE]) >= bg->GetMinPlayersPerTeam(); - - if (!sPlayerbotAIConfig->randomBotAutoJoinBG && !hasPlayers) - return false; - - if (!hasPlayers && isArena) // avoid many arena's being created when 1 player queues a skirmish - return false; - - if (!(hasPlayers || hasBots)) - return false; - - if (sPlayerbotAIConfig->enablePrototypePerformanceDiff && !hasPlayers && !noLag) - return false; - uint32 BracketSize = bg->GetMaxPlayersPerTeam() * 2; uint32 TeamSize = bg->GetMaxPlayersPerTeam(); - uint32 ACount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE]; - uint32 HCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE]; + // If performance diff is enabled, only queue if there is no lag + if (sPlayerbotAIConfig->enablePrototypePerformanceDiff && !noLag) + return false; - uint32 BgCount = ACount + HCount; - uint32 SCount = 0; - uint32 RCount = 0; - - TeamId teamId = bot->GetTeamId(); - - if (isArena) - { - uint32 rated_players = sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE]; - if (rated_players) - { - isRated = true; - } - - isArena = true; - BracketSize = (uint32)(type * 2); - TeamSize = type; - ACount = sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][TEAM_ALLIANCE]; - HCount = sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][TEAM_HORDE]; - BgCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE]; - SCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE]; - RCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE]; - } - - // do not try if not a captain of arena team - if (isRated) - { - if (!sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID())) - return false; - - // check if bot has correct team - ArenaTeam* arenateam = nullptr; - for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) - { - ArenaTeam* temp = sArenaTeamMgr->GetArenaTeamById(bot->GetArenaTeamId(arena_slot)); - if (!temp) - continue; - - if (temp->GetType() != type) - continue; - - arenateam = temp; - } - - if (!arenateam) - return false; - - ratedList.push_back(queueTypeId); - } - - // hack fix crash in queue remove event + // If the bot is in a group, only the leader can queue if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID())) return false; - bool needBots = sRandomPlayerbotMgr->NeedBots[queueTypeId][bracketId][isArena ? isRated ? TEAM_HORDE : TEAM_ALLIANCE : teamId]; - - // add more bots if players are not invited or 1st BG instance is full - if (needBots/* || (hasPlayers && BgCount > BracketSize && (BgCount % BracketSize) != 0)*/) - return true; - - // do not join if BG queue is full - if (BgCount >= BracketSize && (ACount >= TeamSize) && (HCount >= TeamSize)) + // Check if bots should join Arena + ArenaType type = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId)); + if (type != ARENA_TYPE_NONE) { + BracketSize = (uint32)(type * 2); + TeamSize = (uint32)type; + + // Check if bots should join Rated Arena (Only captains can queue) + int ratedArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount; + int ratedArenaPlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount; + int ratedArenaInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount; + int activeRatedArenaQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeRatedArenaQueue; + + bool isRated = (ratedArenaBotCount + ratedArenaPlayerCount) < (BracketSize * (activeRatedArenaQueue + ratedArenaInstanceCount)); + + if (isRated) + { + if (sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID(), type)) + { + sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount += TeamSize; + ratedList.push_back(queueTypeId); + return true; + } + } + + // Check if bots should join Skirmish Arena + // We have extra bots queue because same faction can vs each other but can't be in the same group. + int skirmishArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount; + int skirmishArenaPlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount; + int skirmishArenaInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount; + int activeSkirmishArenaQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue; + int maxRequiredSkirmishBots = BracketSize * (activeSkirmishArenaQueue + skirmishArenaInstanceCount); + if (maxRequiredSkirmishBots != 0) + maxRequiredSkirmishBots = maxRequiredSkirmishBots + TeamSize; + + if ((skirmishArenaBotCount + skirmishArenaPlayerCount) < maxRequiredSkirmishBots) + { + return true; + } + return false; } - if (!isArena && ((ACount >= TeamSize && teamId == TEAM_ALLIANCE) || (HCount >= TeamSize && teamId == TEAM_HORDE))) + // Check if bots should join Battleground + int bgAllianceBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount; + int bgAlliancePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount; + int bgHordeBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount; + int bgHordePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount; + int activeBgQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeBgQueue; + int bgInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgInstanceCount; + + if(teamId == TEAM_ALLIANCE) { - return false; + if((bgAllianceBotCount + bgAlliancePlayerCount) < TeamSize * (activeBgQueue + bgInstanceCount)) + return true; + } else { + if((bgHordeBotCount + bgHordePlayerCount) < TeamSize * (activeBgQueue + bgInstanceCount)) + return true; } - if (isArena && (((ACount >= TeamSize && HCount > 0) && teamId == TEAM_ALLIANCE) || ((HCount >= TeamSize && ACount > 0) && teamId == TEAM_HORDE))) - { - return false; - } - - if (isArena && (((ACount > TeamSize && HCount == 0) && teamId == TEAM_HORDE) || ((HCount > TeamSize && ACount == 0) && teamId == TEAM_ALLIANCE))) - { - return false; - } - - if (isArena && ((!isRated && SCount >= BracketSize) || (isRated && RCount >= BracketSize))) - { - return false; - } - - return true; + return false; } bool BGJoinAction::isUseful() @@ -362,25 +311,31 @@ bool BGJoinAction::isUseful() if (!sPlayerbotAIConfig->randomBotJoinBG) return false; - // can't queue in BG + // can't queue while in BG/Arena if (bot->InBattleground()) return false; - // do not try right after login - if ((time(nullptr) - bot->GetInGameTime()) < 30) + // can't queue while in BG/Arena queue + if (bot->InBattlegroundQueue()) + return false; + + // do not try right after login (currently not working) + if ((time(nullptr) - bot->GetInGameTime()) < 120) return false; // check level if (bot->GetLevel() < 10) return false; - // do not try if with player master or in combat/group + // do not try if with player master if (GET_PLAYERBOT_AI(bot)->HasActivePlayerMaster()) return false; - if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID())) + // do not try if in group, if in group only leader can queue + if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID())) return false; + // do not try if in combat if (bot->IsInCombat()) return false; @@ -388,7 +343,8 @@ bool BGJoinAction::isUseful() if (!bot->CanJoinToBattleground()) return false; - // check if has free queue slots + // check if has free queue slots (pointless as already making sure not in queue) + // keeping just in case. if (!bot->HasFreeBattlegroundQueueId()) return false; @@ -400,13 +356,12 @@ bool BGJoinAction::isUseful() bgList.clear(); ratedList.clear(); - for (int i = BG_BRACKET_ID_FIRST; i < MAX_BATTLEGROUND_BRACKETS; ++i) + for (int bracket = BG_BRACKET_ID_FIRST; bracket < MAX_BATTLEGROUND_BRACKETS; ++bracket) { - for (int j = BATTLEGROUND_QUEUE_AV; j < MAX_BATTLEGROUND_QUEUE_TYPES; ++j) + for (int queueType = BATTLEGROUND_QUEUE_AV; queueType < MAX_BATTLEGROUND_QUEUE_TYPES; ++queueType) { - BattlegroundQueueTypeId queueTypeId = BattlegroundQueueTypeId(j); - BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId); - BattlegroundBracketId bracketId = BattlegroundBracketId(i); + BattlegroundQueueTypeId queueTypeId = BattlegroundQueueTypeId(queueType); + BattlegroundBracketId bracketId = BattlegroundBracketId(bracket); if (!canJoinBg(queueTypeId, bracketId)) continue; @@ -477,14 +432,15 @@ bool BGJoinAction::JoinQueue(uint32 type) //Unit* unit = botAI->GetUnit(AI_VALUE2(CreatureData const*, "bg master", bgTypeId)); Unit* unit = botAI->GetUnit(sRandomPlayerbotMgr->GetBattleMasterGUID(bot, bgTypeId)); if (!unit && isArena) - { + { botAI->GetAiObjectContext()->GetValue("bg type")->Set(0); LOG_DEBUG("playerbots", "Bot {} could not find Battlemaster to join", bot->GetGUID().ToString().c_str()); return false; } + // This breaks groups as refresh includes a remove from group function call. // refresh food/regs - sRandomPlayerbotMgr->Refresh(bot); + //sRandomPlayerbotMgr->Refresh(bot); bool joinAsGroup = bot->GetGroup() && bot->GetGroup()->GetLeaderGUID() == bot->GetGUID(); @@ -554,21 +510,25 @@ bool BGJoinAction::JoinQueue(uint32 type) if (isArena) { - if (isRated) + if (!isRated) { - sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE] += TeamSize; - sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][teamId] += TeamSize; - } - else - { - sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE]++; - sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][teamId]++; + sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount++; } } else if (!joinAsGroup) - sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][teamId]++; + { + if(teamId == TEAM_ALLIANCE) + sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount++; + else + sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount++; + } else - sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][teamId] += bot->GetGroup()->GetMembersCount(); + { + if(teamId == TEAM_ALLIANCE) + sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount += bot->GetGroup()->GetMembersCount(); + else + sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount += bot->GetGroup()->GetMembersCount(); + } botAI->GetAiObjectContext()->GetValue("bg type")->Set(0); @@ -588,6 +548,7 @@ bool BGJoinAction::JoinQueue(uint32 type) return true; } +// Not sure if this has ever worked, but it should be similar to BGJoinAction::shouldJoinBg bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, BattlegroundBracketId bracketId) { BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(queueTypeId); @@ -595,106 +556,81 @@ bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battleg if (!bg) return false; - bool isArena = false; - bool isRated = false; - - ArenaType type = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId)); - if (type != ARENA_TYPE_NONE) - isArena = true; + TeamId teamId = bot->GetTeamId(); + bool noLag = sWorldUpdateTime.GetAverageUpdateTime() < (sRandomPlayerbotMgr->GetPlayers().empty() ? sPlayerbotAIConfig->diffEmpty : sPlayerbotAIConfig->diffWithPlayer) * 1.1; uint32 BracketSize = bg->GetMaxPlayersPerTeam() * 2; uint32 TeamSize = bg->GetMaxPlayersPerTeam(); - uint32 ACount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE]; - uint32 HCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE]; + // If performance diff is enabled, only queue if there is no lag + if (sPlayerbotAIConfig->enablePrototypePerformanceDiff && !noLag) + return false; - uint32 BgCount = ACount + HCount; - uint32 SCount, RCount = 0; - - TeamId teamId = bot->GetTeamId(); - - if (isArena) - { - uint32 rated_players = sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE]; - if (rated_players) - { - isRated = true; - } - - isArena = true; - BracketSize = (uint32)(type * 2); - TeamSize = type; - ACount = sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][TEAM_ALLIANCE]; - HCount = sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][TEAM_HORDE]; - BgCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE]; - SCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_ALLIANCE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_ALLIANCE]; - RCount = sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][TEAM_HORDE] + sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][TEAM_HORDE]; - } - - // do not try if not a captain of arena team - - if (isRated) - { - if (!sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID())) - return false; - - // check if bot has correct team - ArenaTeam* arenateam = nullptr; - for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) - { - ArenaTeam* temp = sArenaTeamMgr->GetArenaTeamById(bot->GetArenaTeamId(arena_slot)); - if (!temp) - continue; - - if (temp->GetType() != type) - continue; - - arenateam = temp; - } - - if (!arenateam) - return false; - - ratedList.push_back(queueTypeId); - } - - // hack fix crash in queue remove event + // If the bot is in a group, only the leader can queue if (bot->GetGroup() && !bot->GetGroup()->IsLeader(bot->GetGUID())) return false; - bool needBots = sRandomPlayerbotMgr->NeedBots[queueTypeId][bracketId][isArena ? isRated ? TEAM_HORDE : TEAM_ALLIANCE : teamId]; - - // add more bots if players are not invited or 1st BG instance is full - if (needBots/* || (hasPlayers && BgCount > BracketSize && (BgCount % BracketSize) != 0)*/) - return true; - - // do not join if BG queue is full - if (BgCount >= BracketSize && (ACount >= TeamSize) && (HCount >= TeamSize)) + // Check if bots should join Arena + ArenaType type = ArenaType(BattlegroundMgr::BGArenaType(queueTypeId)); + if (type != ARENA_TYPE_NONE) { + BracketSize = (uint32)(type * 2); + TeamSize = (uint32)type; + + // Check if bots should join Rated Arena (Only captains can queue) + int ratedArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount; + int ratedArenaPlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount; + int ratedArenaInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount; + int activeRatedArenaQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeRatedArenaQueue; + + bool isRated = (ratedArenaBotCount + ratedArenaPlayerCount) < (BracketSize * (activeRatedArenaQueue + ratedArenaInstanceCount)); + + if (isRated) + { + if (sArenaTeamMgr->GetArenaTeamByCaptain(bot->GetGUID(), type)) + { + sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount += TeamSize; + ratedList.push_back(queueTypeId); + return true; + } + } + + // Check if bots should join Skirmish Arena + // We have extra bots queue because same faction can vs each other but can't be in the same group. + int skirmishArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount; + int skirmishArenaPlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount; + int skirmishArenaInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount; + int activeSkirmishArenaQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue; + int maxRequiredSkirmishBots = BracketSize * (activeSkirmishArenaQueue + skirmishArenaInstanceCount); + if (maxRequiredSkirmishBots != 0) + maxRequiredSkirmishBots = maxRequiredSkirmishBots + TeamSize; + + if ((skirmishArenaBotCount + skirmishArenaPlayerCount) < maxRequiredSkirmishBots) + { + return true; + } + return false; } - if (!isArena && ((ACount >= TeamSize && teamId == TEAM_ALLIANCE) || (HCount >= TeamSize && teamId == TEAM_HORDE))) + // Check if bots should join Battleground + int bgAllianceBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount; + int bgAlliancePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount; + int bgHordeBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount; + int bgHordePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount; + int activeBgQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeBgQueue; + int bgInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgInstanceCount; + + if(teamId == TEAM_ALLIANCE) { - return false; + if((bgAllianceBotCount + bgAlliancePlayerCount) < TeamSize * (activeBgQueue + bgInstanceCount)) + return true; + } else { + if((bgHordeBotCount + bgHordePlayerCount) < TeamSize * (activeBgQueue + bgInstanceCount)) + return true; } - if (isArena && (((ACount >= TeamSize && HCount > 0) && teamId == TEAM_ALLIANCE) || ((HCount >= TeamSize && ACount > 0) && teamId == TEAM_HORDE))) - { - return false; - } - - if (isArena && (((ACount > TeamSize && HCount == 0) && teamId == TEAM_HORDE) || ((HCount > TeamSize && ACount == 0) && teamId == TEAM_ALLIANCE))) - { - return false; - } - - if (isArena && ((!isRated && SCount >= BracketSize) || (isRated && RCount >= BracketSize))) - { - return false; - } - - return true; + return false; } bool BGLeaveAction::Execute(Event event) @@ -894,18 +830,6 @@ bool BGStatusAction::Execute(Event event) LOG_INFO("playerbots", "Bot {} <{}> ({} {}): Received BG status TIME_REMOVE for {} {}", bot->GetGUID().ToString().c_str(), bot->GetName(), bot->GetLevel(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", isArena ? "Arena" : "BG", _bgType); - if (Battleground* bg = bot->GetBattleground()) - { - if (isArena) - { - sRandomPlayerbotMgr->ArenaBots[queueTypeId][bracketId][isRated ? TEAM_HORDE : TEAM_ALLIANCE][teamId]--; - teamId = isRated ? TEAM_HORDE : TEAM_ALLIANCE; - } - - sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][teamId]--; - sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][teamId] = 0; - } - // remove warsong strategy if (IsRandomBot) botAI->SetMaster(nullptr); @@ -972,9 +896,6 @@ bool BGStatusAction::Execute(Event event) bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket); action = 0x1; - // bg started so players should get invites by now - sRandomPlayerbotMgr->NeedBots[queueTypeId][bracketId][isArena ? TeamId(isRated) : bot->GetTeamId()] = false; - WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20); packet << type << unk2 << (uint32)_bgTypeId << unk << action; bot->GetSession()->HandleBattleFieldPortOpcode(packet); @@ -1012,7 +933,12 @@ bool BGStatusAction::Execute(Event event) if (leaveQ && ((bot->GetGroup() && bot->GetGroup()->IsLeader(bot->GetGUID())) || !(bot->GetGroup() || botAI->GetMaster()))) { TeamId teamId = bot->GetTeamId(); - bool realPlayers = sRandomPlayerbotMgr->BgPlayers[queueTypeId][bracketId][teamId]; + bool realPlayers = false; + if (isRated) + realPlayers = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount > 0; + else + realPlayers = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount > 0; + if (realPlayers) return false; @@ -1028,7 +954,6 @@ bool BGStatusAction::Execute(Event event) botAI->GetAiObjectContext()->GetValue("bg type")->Set(0); botAI->GetAiObjectContext()->GetValue("bg role")->Set(0); botAI->GetAiObjectContext()->GetValue("arena type")->Set(0); - sRandomPlayerbotMgr->BgBots[queueTypeId][bracketId][teamId]--; return true; } @@ -1082,9 +1007,6 @@ bool BGStatusAction::Execute(Event event) action = 0x1; - // bg started so players should get invites by now - sRandomPlayerbotMgr->NeedBots[queueTypeId][bracketId][isArena ? isRated ? TEAM_HORDE : TEAM_ALLIANCE : teamId] = false; - WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20); packet << type << unk2 << (uint32)_bgTypeId << unk << action; bot->GetSession()->HandleBattleFieldPortOpcode(packet); diff --git a/src/strategy/actions/BattleGroundJoinAction.h b/src/strategy/actions/BattleGroundJoinAction.h index b112d508..8248ebac 100644 --- a/src/strategy/actions/BattleGroundJoinAction.h +++ b/src/strategy/actions/BattleGroundJoinAction.h @@ -14,6 +14,7 @@ struct CreatureData; enum ArenaType : uint8; enum BattlegroundQueueTypeId : uint8; +enum BattlegroundBracketId : uint8; class BGJoinAction : public Action {