diff --git a/conf/mod_player_bot_level_brackets.conf.dist b/conf/mod_player_bot_level_brackets.conf.dist index 35277a5..731fc06 100644 --- a/conf/mod_player_bot_level_brackets.conf.dist +++ b/conf/mod_player_bot_level_brackets.conf.dist @@ -51,6 +51,15 @@ BotLevelBrackets.FlaggedProcessLimit = 5 # Valid values: 0 (disabled) / 1 (enabled) BotLevelBrackets.IgnoreGuildBotsWithRealPlayers = 1 +# +# BotLevelBrackets.IgnoreArenaTeamBots +# Description: When enabled, bots that are members of arena teams are excluded from bot bracket calculations +# and will not be level changed or flagged. This prevents bots in arena teams from being +# changed, which would break team compositions. +# Default: 1 (enabled) +# Valid values: 0 (disabled) / 1 (enabled) +BotLevelBrackets.IgnoreArenaTeamBots = 1 + # # BotLevelBrackets.GuildTrackerUpdateFrequency # Description: The frequency (in seconds) at which the persistent guild tracker database is updated. diff --git a/src/mod-player-bot-level-brackets.cpp b/src/mod-player-bot-level-brackets.cpp index 9733e62..d610f06 100644 --- a/src/mod-player-bot-level-brackets.cpp +++ b/src/mod-player-bot-level-brackets.cpp @@ -20,6 +20,8 @@ #include "QueryResult.h" #include #include "Player.h" +#include "PlayerbotAIConfig.h" +#include "ArenaTeamMgr.h" using namespace Acore::ChatCommands; @@ -51,6 +53,8 @@ static uint8 g_RandomBotMaxLevel = 80; static bool g_BotLevelBracketsEnabled = true; // Ignore bots in guilds with a real player online. Default is true. static bool g_IgnoreGuildBotsWithRealPlayers = true; +// Ignore bots in arena teams. Default is true. +static bool g_IgnoreArenaTeamBots = true; // Use vectors to store the level ranges. static std::vector g_AllianceLevelRanges; @@ -111,6 +115,7 @@ static void LoadBotLevelBracketsConfig() { g_BotLevelBracketsEnabled = sConfigMgr->GetOption("BotLevelBrackets.Enabled", true); g_IgnoreGuildBotsWithRealPlayers = sConfigMgr->GetOption("BotLevelBrackets.IgnoreGuildBotsWithRealPlayers", true); + g_IgnoreArenaTeamBots = sConfigMgr->GetOption("BotLevelBrackets.IgnoreArenaTeamBots", true); g_BotDistFullDebugMode = sConfigMgr->GetOption("BotLevelBrackets.FullDebugMode", false); g_BotDistLiteDebugMode = sConfigMgr->GetOption("BotLevelBrackets.LiteDebugMode", false); @@ -660,6 +665,14 @@ static void AdjustBotToRange(Player* bot, int targetRangeIndex, const LevelRange PlayerbotFactory newFactory(bot, newLevel); newFactory.Randomize(false); + // Force reset talents if equipment persistence is enabled and bot rolled to max level + // This is to fix an issue with Playerbots and how Randomization works with Equipment Persistence + if (newLevel == g_RandomBotMaxLevel && sPlayerbotAIConfig->equipmentPersistence) + { + PlayerbotFactory tempFactory(bot, newLevel); + tempFactory.InitTalentsTree(false, true, true); + } + if (g_BotDistFullDebugMode) { PlayerbotAI* botAI = sPlayerbotsMgr->GetPlayerbotAI(bot); @@ -735,6 +748,30 @@ static bool BotInFriendList(Player* bot) } +/** + * @brief Checks if the given bot is a member of any arena team. + * + * This function verifies that the provided Player pointer is valid and + * checks all arena team slots to see if the bot is in any arena team. + * + * @param bot Pointer to the Player object representing the bot. + * @return true if the bot is in an arena team, false otherwise. + */ +static bool BotInArenaTeam(Player* bot) +{ + if (!bot) + return false; + for (uint32 slot = 0; slot < MAX_ARENA_SLOT; ++slot) + { + if (ArenaTeam* team = sArenaTeamMgr->GetArenaTeamById(bot->GetArenaTeamId(slot))) + { + return true; + } + } + return false; +} + + /** * @brief Clamps and balances the level brackets for Alliance and Horde bot distributions. * @@ -1014,6 +1051,12 @@ static void ProcessPendingLevelResets() continue; } + if (g_IgnoreArenaTeamBots && BotInArenaTeam(bot)) + { + it = g_PendingLevelResets.erase(it); + continue; + } + if (bot && bot->IsInWorld() && IsBotSafeForLevelReset(bot)) { AdjustBotToRange(bot, targetRange, it->factionRanges); @@ -1049,6 +1092,16 @@ static int GetOrFlagPlayerBracket(Player* player) return -1; } + if (IsPlayerBot(player) && g_IgnoreGuildBotsWithRealPlayers && BotInGuildWithRealPlayer(player)) + { + return -1; + } + + if (IsPlayerBot(player) && g_IgnoreArenaTeamBots && BotInArenaTeam(player)) + { + return -1; + } + int rangeIndex = GetLevelRangeIndex(player->GetLevel(), player->GetTeamId()); if (rangeIndex >= 0) { @@ -1421,6 +1474,10 @@ public: { continue; } + if (g_IgnoreArenaTeamBots && BotInArenaTeam(player)) + { + continue; + } if (IsAlliancePlayerBot(player)) { totalAllianceBots++;