diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 496ea5d7..e139795d 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -654,8 +654,33 @@ 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 -AiPlayerbot.RandomBotArenaTeamCount = 20 +# Teams are created when bots are initialized on server restart. +# You may need to first delete all arena teams, then reinitialize bots. +# Warning: Reinitializing bots completely resets them (command in game: .playerbots rndbot init) +# Bots only join one arena team to avoid queueing issues. Take that into account when increasing count. +# Default: 2v2: 10 (20 Bots), 3v3: 10 (30 bots), 5v5: 5 (25 bots). +AiPlayerbot.RandomBotArenaTeam2v2Count = 10 +AiPlayerbot.RandomBotArenaTeam3v3Count = 10 +AiPlayerbot.RandomBotArenaTeam5v5Count = 5 + +# Arena rating is randomized on team creation. +# Default: Max: 2000, Min: 1000. +AiPlayerbot.RandomBotArenaTeamMaxRating = 2000 +AiPlayerbot.RandomBotArenaTeamMinRating = 1000 # Delete all random bot arena teams AiPlayerbot.DeleteRandomBotArenaTeams = 0 diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index a859c9dd..e90d847f 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -147,6 +147,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); @@ -336,8 +342,12 @@ bool PlayerbotAIConfig::Initialize() randomBotGroupNearby = sConfigMgr->GetOption("AiPlayerbot.RandomBotGroupNearby", true); // arena - randomBotArenaTeamCount = sConfigMgr->GetOption("AiPlayerbot.RandomBotArenaTeamCount", 20); + randomBotArenaTeam2v2Count = sConfigMgr->GetOption("AiPlayerbot.RandomBotArenaTeam2v2Count", 10); + randomBotArenaTeam3v3Count = sConfigMgr->GetOption("AiPlayerbot.RandomBotArenaTeam3v3Count", 10); + randomBotArenaTeam5v5Count = sConfigMgr->GetOption("AiPlayerbot.RandomBotArenaTeam5v5Count", 5); deleteRandomBotArenaTeams = sConfigMgr->GetOption("AiPlayerbot.DeleteRandomBotArenaTeams", false); + randomBotArenaTeamMaxRating = sConfigMgr->GetOption("AiPlayerbot.RandomBotArenaTeamMaxRating", 2000); + randomBotArenaTeamMinRating = sConfigMgr->GetOption("AiPlayerbot.RandomBotArenaTeamMinRating", 1000); selfBotLevel = sConfigMgr->GetOption("AiPlayerbot.SelfBotLevel", 1); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index 129daee3..3971d819 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -102,6 +102,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; @@ -212,6 +218,11 @@ class PlayerbotAIConfig uint32 tweakValue; //Debugging config uint32 randomBotArenaTeamCount; + uint32 randomBotArenaTeamMaxRating; + uint32 randomBotArenaTeamMinRating; + uint32 randomBotArenaTeam2v2Count; + uint32 randomBotArenaTeam3v3Count; + uint32 randomBotArenaTeam5v5Count; bool deleteRandomBotArenaTeams; std::vector randomBotArenaTeams; diff --git a/src/PlayerbotFactory.cpp b/src/PlayerbotFactory.cpp index e8360991..3f7279f8 100644 --- a/src/PlayerbotFactory.cpp +++ b/src/PlayerbotFactory.cpp @@ -5,6 +5,7 @@ #include "PlayerbotFactory.h" #include "AccountMgr.h" #include "AiFactory.h" +#include "ArenaTeam.h" #include "ArenaTeamMgr.h" #include "DBCStores.h" #include "DBCStructure.h" @@ -366,14 +367,14 @@ void PlayerbotFactory::Randomize(bool incremental) //if (pmo) // pmo->finish(); - // if (bot->GetLevel() >= 70) - // { - // pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Arenas"); - // LOG_INFO("playerbots", "Initializing arena teams..."); - // InitArenaTeam(); - // if (pmo) - // pmo->finish(); - // } + if (bot->GetLevel() >= 70) + { + pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Arenas"); + LOG_INFO("playerbots", "Initializing arena teams..."); + InitArenaTeam(); + if (pmo) + pmo->finish(); + } if (!incremental) { bot->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true); @@ -3297,8 +3298,40 @@ void PlayerbotFactory::InitArenaTeam() if (!sPlayerbotAIConfig->IsInRandomAccountList(bot->GetSession()->GetAccountId())) return; + // Currently the teams are only remade after a server restart and if deleteRandomBotArenaTeams = 1 + // This is because randomBotArenaTeams is only empty on server restart. + // A manual reinitalization (.playerbots rndbot init) is also required after the teams have been deleted. if (sPlayerbotAIConfig->randomBotArenaTeams.empty()) - RandomPlayerbotFactory::CreateRandomArenaTeams(); + { + if (sPlayerbotAIConfig->deleteRandomBotArenaTeams) + { + LOG_INFO("playerbots", "Deleting random bot arena teams..."); + + for (auto it = sArenaTeamMgr->GetArenaTeams().begin(); it != sArenaTeamMgr->GetArenaTeams().end(); ++it) + { + ArenaTeam* arenateam = it->second; + if (arenateam->GetCaptain() && arenateam->GetCaptain().IsPlayer()) + { + Player* bot = ObjectAccessor::FindPlayer(arenateam->GetCaptain()); + PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); + if (!botAI || botAI->IsRealPlayer()) + { + continue; + } + else + { + arenateam->Disband(nullptr); + } + } + } + + LOG_INFO("playerbots", "Random bot arena teams deleted"); + } + + RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_2v2, sPlayerbotAIConfig->randomBotArenaTeam2v2Count); + RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_3v3, sPlayerbotAIConfig->randomBotArenaTeam3v3Count); + RandomPlayerbotFactory::CreateRandomArenaTeams(ARENA_TYPE_5v5, sPlayerbotAIConfig->randomBotArenaTeam5v5Count); + } std::vector arenateams; for (std::vector::iterator i = sPlayerbotAIConfig->randomBotArenaTeams.begin(); i != sPlayerbotAIConfig->randomBotArenaTeams.end(); ++i) @@ -3310,28 +3343,48 @@ void PlayerbotFactory::InitArenaTeam() return; } - int index = urand(0, arenateams.size() - 1); - uint32 arenateamID = arenateams[index]; - ArenaTeam* arenateam = sArenaTeamMgr->GetArenaTeamById(arenateamID); - if (!arenateam) + while (!arenateams.empty()) { - LOG_ERROR("playerbots", "Invalid arena team {}", arenateamID); - return; - } - - if (arenateam->GetMembersSize() < ((uint32)arenateam->GetType() * 2) && bot->GetLevel() >= 70) - { - ObjectGuid capt = arenateam->GetCaptain(); - Player* botcaptain = ObjectAccessor::FindPlayer(capt); - - if ((bot && bot->GetArenaTeamId(arenateam->GetSlot())) || sCharacterCache->GetCharacterArenaTeamIdByGuid(bot->GetGUID(), arenateam->GetSlot()) != 0) - return; - - if (botcaptain && botcaptain->GetTeamId() == bot->GetTeamId()) //need? + int index = urand(0, arenateams.size() - 1); + uint32 arenateamID = arenateams[index]; + ArenaTeam *arenateam = sArenaTeamMgr->GetArenaTeamById(arenateamID); + if (!arenateam) { - arenateam->AddMember(bot->GetGUID()); - arenateam->SaveToDB(); + LOG_ERROR("playerbots", "Invalid arena team {}", arenateamID); + arenateams.erase(arenateams.begin() + index); + continue; } + + if (arenateam->GetMembersSize() < ((uint32)arenateam->GetType()) && bot->GetLevel() >= 70) + { + ObjectGuid capt = arenateam->GetCaptain(); + Player* botcaptain = ObjectAccessor::FindPlayer(capt); + + // To avoid bots removing each other from groups when queueing, force them to only be in one team + for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot) + { + uint32 arenaTeamId = bot->GetArenaTeamId(arena_slot); + if (!arenaTeamId) + continue; + + ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(arenaTeamId); + if (team) + { + if (sCharacterCache->GetCharacterArenaTeamIdByGuid(bot->GetGUID(), team->GetSlot()) != 0) + { + return; + } + return; + } + } + + if (botcaptain && botcaptain->GetTeamId() == bot->GetTeamId()) // need? + { + arenateam->AddMember(bot->GetGUID()); + arenateam->SaveToDB(); + } + } + arenateams.erase(arenateams.begin() + index); } bot->SaveToDB(false, false); diff --git a/src/RandomPlayerbotFactory.cpp b/src/RandomPlayerbotFactory.cpp index b1dfae8b..2ee1a1a0 100644 --- a/src/RandomPlayerbotFactory.cpp +++ b/src/RandomPlayerbotFactory.cpp @@ -622,7 +622,7 @@ std::string const RandomPlayerbotFactory::CreateRandomGuildName() return std::move(guildName); } -void RandomPlayerbotFactory::CreateRandomArenaTeams() +void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count) { std::vector randomBots; @@ -639,28 +639,12 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams() while (result->NextRow()); } - if (sPlayerbotAIConfig->deleteRandomBotArenaTeams) - { - LOG_INFO("playerbots", "Deleting random bot arena teams..."); - - for (std::vector::iterator i = randomBots.begin(); i != randomBots.end(); ++i) - { - ObjectGuid captain = ObjectGuid::Create(*i); - ArenaTeam* arenateam = sArenaTeamMgr->GetArenaTeamByCaptain(captain); - if (arenateam) - //sObjectMgr->RemoveArenaTeam(arenateam->GetId()); - arenateam->Disband(nullptr); - } - - LOG_INFO("playerbots", "Random bot arena teams deleted"); - } - uint32 arenaTeamNumber = 0; GuidVector availableCaptains; for (std::vector::iterator i = randomBots.begin(); i != randomBots.end(); ++i) { ObjectGuid captain = ObjectGuid::Create(*i); - ArenaTeam* arenateam = sArenaTeamMgr->GetArenaTeamByCaptain(captain); + ArenaTeam* arenateam = sArenaTeamMgr->GetArenaTeamByCaptain(captain, type); if (arenateam) { ++arenaTeamNumber; @@ -675,7 +659,7 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams() } } - for (; arenaTeamNumber < sPlayerbotAIConfig->randomBotArenaTeamCount; ++arenaTeamNumber) + for (; arenaTeamNumber < count; ++arenaTeamNumber) { std::string const arenaTeamName = CreateRandomArenaTeamName(); if (arenaTeamName.empty()) @@ -702,29 +686,17 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams() continue; } - QueryResult results = CharacterDatabase.Query("SELECT `type` FROM playerbots_arena_team_names WHERE name = '{}'", arenaTeamName.c_str()); - if (!results) - { - LOG_ERROR("playerbots", "No valid types for arena teams"); - return; - } + // Below query no longer required as now user has control over the number of each type of arena team they want to create. + // Keeping commented for potential future reference. + // QueryResult results = CharacterDatabase.Query("SELECT `type` FROM playerbots_arena_team_names WHERE name = '{}'", arenaTeamName.c_str()); + // if (!results) + // { + // LOG_ERROR("playerbots", "No valid types for arena teams"); + // return; + // } - Field* fields = results->Fetch(); - uint8 slot = fields[0].Get(); - - ArenaType type; - switch (slot) - { - case 2: - type = ARENA_TYPE_2v2; - break; - case 3: - type = ARENA_TYPE_3v3; - break; - case 5: - type = ARENA_TYPE_5v5; - break; - } + // Field* fields = results->Fetch(); + // uint8 slot = fields[0].Get(); ArenaTeam* arenateam = new ArenaTeam(); if (!arenateam->Create(player->GetGUID(), type, arenaTeamName, 0, 0, 0, 0, 0)) @@ -736,7 +708,7 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams() arenateam->SetCaptain(player->GetGUID()); // set random rating - arenateam->SetRatingForAll(urand(1500, 2700)); + arenateam->SetRatingForAll(urand(sPlayerbotAIConfig->randomBotArenaTeamMinRating, sPlayerbotAIConfig->randomBotArenaTeamMaxRating)); // set random emblem uint32 backgroundColor = urand(0xFF000000, 0xFFFFFFFF); diff --git a/src/RandomPlayerbotFactory.h b/src/RandomPlayerbotFactory.h index d6a69eba..f022f013 100644 --- a/src/RandomPlayerbotFactory.h +++ b/src/RandomPlayerbotFactory.h @@ -10,10 +10,13 @@ #include #include #include +#include "DBCEnums.h" class Player; class WorldSession; +enum ArenaType : uint8; + class RandomPlayerbotFactory { public: @@ -23,7 +26,7 @@ class RandomPlayerbotFactory Player* CreateRandomBot(WorldSession* session, uint8 cls, std::unordered_map> names); static void CreateRandomBots(); static void CreateRandomGuilds(); - static void CreateRandomArenaTeams(); + static void CreateRandomArenaTeams(ArenaType slot, uint32 count); static std::string const CreateRandomGuildName(); private: diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index 1a424d5e..658e2d2a 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,89 +718,193 @@ 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 + ); } + 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", "BG Queue check finished"); } diff --git a/src/RandomPlayerbotMgr.h b/src/RandomPlayerbotMgr.h index a79bd269..5c33c609 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; + uint32 bgInstanceCount = 0; + uint32 ratedArenaInstanceCount = 0; + uint32 skirmishArenaInstanceCount = 0; + uint32 minLevel = 0; + uint32 maxLevel = 0; + uint32 activeRatedArenaQueue = 0; // 0 = Inactive, 1 = Active + uint32 activeSkirmishArenaQueue = 0; // 0 = Inactive, 1 = Active + uint32 activeBgQueue = 0; // 0 = Inactive, 1 = Active + + // Bots (Arena) + uint32 ratedArenaBotCount = 0; + uint32 skirmishArenaBotCount = 0; + + // Bots (Battleground) + uint32 bgHordeBotCount = 0; + uint32 bgAllianceBotCount = 0; + + // Players (Arena) + uint32 ratedArenaPlayerCount = 0; + uint32 skirmishArenaPlayerCount = 0; + + // Players (Battleground) + uint32 bgHordePlayerCount = 0; + uint32 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..dd668aca 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,88 @@ 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) + uint32 ratedArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount; + uint32 ratedArenaPlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount; + uint32 ratedArenaInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount; + uint32 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. + uint32 skirmishArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount; + uint32 skirmishArenaPlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount; + uint32 skirmishArenaInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount; + uint32 activeSkirmishArenaQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue; + uint32 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 + uint32 bgAllianceBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount; + uint32 bgAlliancePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount; + uint32 bgHordeBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount; + uint32 bgHordePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount; + uint32 activeBgQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeBgQueue; + uint32 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 +313,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 +345,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 +358,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 +434,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 +512,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 +550,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 +558,83 @@ 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) + uint32 ratedArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaBotCount; + uint32 ratedArenaPlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaPlayerCount; + uint32 ratedArenaInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].ratedArenaInstanceCount; + uint32 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. + uint32 skirmishArenaBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaBotCount; + uint32 skirmishArenaPlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaPlayerCount; + uint32 skirmishArenaInstanceCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].skirmishArenaInstanceCount; + uint32 activeSkirmishArenaQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeSkirmishArenaQueue; + uint32 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 + uint32 bgAllianceBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAllianceBotCount; + uint32 bgAlliancePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgAlliancePlayerCount; + uint32 bgHordeBotCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordeBotCount; + uint32 bgHordePlayerCount = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].bgHordePlayerCount; + uint32 activeBgQueue = sRandomPlayerbotMgr->BattlegroundData[queueTypeId][bracketId].activeBgQueue; + uint32 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 +834,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 +900,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 +937,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 +958,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 +1011,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 { diff --git a/src/strategy/actions/BattleGroundTactics.cpp b/src/strategy/actions/BattleGroundTactics.cpp index 07aca77b..b3a4ce85 100644 --- a/src/strategy/actions/BattleGroundTactics.cpp +++ b/src/strategy/actions/BattleGroundTactics.cpp @@ -5177,23 +5177,89 @@ bool ArenaTactics::moveToCenter(Battleground* bg) { return true; } - uint32 Preference = context->GetValue("bg role")->Get(); + uint32 Preference = 6; + + switch (bot->getClass()) + { + case CLASS_PRIEST: + case CLASS_SHAMAN: + case CLASS_DRUID: + Preference = 3; + break; + case CLASS_WARRIOR: + case CLASS_PALADIN: + case CLASS_ROGUE: + case CLASS_DEATH_KNIGHT: + Preference = 6; + break; + case CLASS_HUNTER: + case CLASS_MAGE: + case CLASS_WARLOCK: + Preference = 9; + break; + } + switch (bg->GetBgTypeID()) { case BATTLEGROUND_BE: - if (Preference > 10) - MoveTo(bg->GetMapId(), 6185.0f + frand(-2, +2), 236.0f + frand(-2, +2), 6.0f, false, true); + if (bg->GetTeamStartPosition(bot->GetBgTeamId())->GetPositionY() < 240) + { + if (Preference == 3) + MoveTo(bg->GetMapId(), 6226.65f + frand(-1, +1), 264.36f + frand(-1, +1), 1.31f, false, true); + else if (Preference == 6) + MoveTo(bg->GetMapId(), 6239.89f + frand(-1, +1), 261.11f + frand(-1, +1), 0.89f, false, true); + else + MoveTo(bg->GetMapId(), 6235.60f + frand(-1, +1), 258.27f + frand(-1, +1), 0.89f, false, true); + } else - MoveTo(bg->GetMapId(), 6240.0f + frand(-2, +2), 262.0f + frand(-2, +2), 2.0f, false, true); + { + if (Preference == 3) + MoveTo(bg->GetMapId(), 6265.72f + frand(-1, +1), 271.92f + frand(-1, +1), 3.65f, false, true); + else if (Preference == 6) + MoveTo(bg->GetMapId(), 6239.89f + frand(-1, +1), 261.11f + frand(-1, +1), 0.89f, false, true); + else + MoveTo(bg->GetMapId(), 6250.50f + frand(-1, +1), 266.66f + frand(-1, +1), 2.63f, false, true); + } break; case BATTLEGROUND_RL: - if (Preference < 5) - MoveTo(bg->GetMapId(), 1320.0f + frand(-2, +2), 1672.0f + frand(-2, +2), 38.0f, false, true); + if (bg->GetTeamStartPosition(bot->GetBgTeamId())->GetPositionY() < 1600) + { + if (Preference == 3) + MoveTo(bg->GetMapId(), 1262.14f + frand(-1, +1), 1657.63f + frand(-1, +1), 33.76f, false, true); + else if (Preference == 6) + MoveTo(bg->GetMapId(), 1266.85f + frand(-1, +1), 1663.52f + frand(-1, +1), 34.04f, false, true); + else + MoveTo(bg->GetMapId(), 1274.07f + frand(-1, +1), 1656.36f + frand(-1, +1), 34.58f, false, true); + } else - MoveTo(bg->GetMapId(), 1273.0f + frand(-2, +2), 1666.0f + frand(-2, +2), 36.0f, false, true); + { + if (Preference == 3) + MoveTo(bg->GetMapId(), 1261.93f + frand(-1, +1), 1669.27f + frand(-1, +1), 34.25f, false, true); + else if (Preference == 6) + MoveTo(bg->GetMapId(), 1266.85f + frand(-1, +1), 1663.52f + frand(-1, +1), 34.04f, false, true); + else + MoveTo(bg->GetMapId(), 1266.37f + frand(-1, +1), 1672.40f + frand(-1, +1), 34.21f, false, true); + } break; case BATTLEGROUND_NA: - MoveTo(bg->GetMapId(), 4055.0f + frand(-5, +5), 2921.0f + frand(-5, +5), 15.1f, false, true); + if (bg->GetTeamStartPosition(bot->GetBgTeamId())->GetPositionY() < 2870) + { + if (Preference == 3) + MoveTo(bg->GetMapId(), 4068.85f + frand(-1, +1), 2911.98f + frand(-1, +1), 12.99f, false, true); + else if (Preference == 6) + MoveTo(bg->GetMapId(), 4056.99f + frand(-1, +1), 2919.75f + frand(-1, +1), 13.51f, false, true); + else + MoveTo(bg->GetMapId(), 4056.27f + frand(-1, +1), 2905.33f + frand(-1, +1), 12.90f, false, true); + } + else + { + if (Preference == 3) + MoveTo(bg->GetMapId(), 4043.66f + frand(-1, +1), 2927.93f + frand(-1, +1), 13.17f, false, true); + else if (Preference == 6) + MoveTo(bg->GetMapId(), 4056.99f + frand(-1, +1), 2919.75f + frand(-1, +1), 13.51f, false, true); + else + MoveTo(bg->GetMapId(), 4054.80f + frand(-1, +1), 2934.28f + frand(-1, +1), 13.72f, false, true); + } break; case BATTLEGROUND_DS: if (!MoveTo(bg->GetMapId(), 1291.58f + frand(-5, +5), 790.87f + frand(-5, +5), 7.8f, false, true)) { @@ -5211,8 +5277,5 @@ bool ArenaTactics::moveToCenter(Battleground* bg) break; } - if (urand(0, 100) > 70) - context->GetValue("bg role")->Set(urand(0, 9)); - return true; }