diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 19761738..244fa991 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -488,6 +488,34 @@ AiPlayerbot.RPWarningCooldown = 30 # Default: 1 (enabled) AiPlayerbot.MaintenanceCommand = 1 +# Enable/Disable specific maintenance command functionality for alt bots +# Disable to prevent players from giving free bags, spells, skill levels etc to their alt bots +# Default: 1 (enabled) +AiPlayerbot.AltMaintenanceAmmo = 1 +AiPlayerbot.AltMaintenanceFood = 1 +AiPlayerbot.AltMaintenanceReagents = 1 +AiPlayerbot.AltMaintenanceConsumables = 1 +AiPlayerbot.AltMaintenancePotions = 1 + +AiPlayerbot.AltMaintenanceBags = 1 +AiPlayerbot.AltMaintenanceMounts = 1 +AiPlayerbot.AltMaintenanceSkills = 1 + +AiPlayerbot.AltMaintenanceClassSpells = 1 +AiPlayerbot.AltMaintenanceAvailableSpells = 1 +AiPlayerbot.AltMaintenanceSpecialSpells = 1 +AiPlayerbot.AltMaintenanceTalentTree = 1 +AiPlayerbot.AltMaintenanceGlyphs = 1 +AiPlayerbot.AltMaintenanceGemsEnchants = 1 + +AiPlayerbot.AltMaintenancePet = 1 +AiPlayerbot.AltMaintenancePetTalents = 1 + +AiPlayerbot.AltMaintenanceReputation = 1 +AiPlayerbot.AltMaintenanceAttunementQuests = 1 +AiPlayerbot.AltMaintenanceKeyring = 1 + + # Enable/Disable autogear command, which automatically upgrades bots' gear; the quality is limited by AutoGearQualityLimit and AutoGearScoreLimit # Default: 1 (enabled) AiPlayerbot.AutoGearCommand = 1 @@ -569,21 +597,10 @@ AiPlayerbot.RandomBotRandomPassword = 0 # Prefix for account names to create for randombots AiPlayerbot.RandomBotAccountPrefix = "rndbot" -# Minimum and maximum initialization levels for randombots +# Minimum and maximum levels for randombots AiPlayerbot.RandomBotMinLevel = 1 AiPlayerbot.RandomBotMaxLevel = 80 -# Minimum and maximum level range for randombots allowed to login -# If level filtration is used, minRandomBots and maxRandomBots might be automatically adjusted to lower values, -# depending on available eligible bots in the database -# Default Min,Max: 1,80 (no level filtration) -AiPlayerbot.RandomBotMinLoginLevel = 1 -AiPlayerbot.RandomBotMaxLoginLevel = 80 - -# log-out randombots if they they level outside the allowed login range -# Default: 0 (disabled) -AiPlayerbot.RandomBotLogoutOutsideLoginRange = 0 - # Sync max randombot level with max level of online players # Default: 0 (disabled) AiPlayerbot.SyncLevelWithPlayers = 0 diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index 80cdeb97..65b6f5bc 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -86,9 +86,6 @@ bool PlayerbotAIConfig::Initialize() rpWarningCooldown = sConfigMgr->GetOption("AiPlayerbot.RPWarningCooldown", 30); disabledWithoutRealPlayerLoginDelay = sConfigMgr->GetOption("AiPlayerbot.DisabledWithoutRealPlayerLoginDelay", 30); disabledWithoutRealPlayerLogoutDelay = sConfigMgr->GetOption("AiPlayerbot.DisabledWithoutRealPlayerLogoutDelay", 300); - randomBotMinLoginLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotMinLoginLevel", 1); - randomBotMaxLoginLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotMaxLoginLevel", 80); - randomBotLogoutOutsideLoginRange = sConfigMgr->GetOption("AiPlayerbot.RandomBotLogoutOutsideLoginRange", false); farDistance = sConfigMgr->GetOption("AiPlayerbot.FarDistance", 20.0f); sightDistance = sConfigMgr->GetOption("AiPlayerbot.SightDistance", 75.0f); @@ -553,6 +550,27 @@ bool PlayerbotAIConfig::Initialize() addClassCommand = sConfigMgr->GetOption("AiPlayerbot.AddClassCommand", 1); addClassAccountPoolSize = sConfigMgr->GetOption("AiPlayerbot.AddClassAccountPoolSize", 50); maintenanceCommand = sConfigMgr->GetOption("AiPlayerbot.MaintenanceCommand", 1); + + altMaintenanceAttunementQs = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceAttunementQuests", true); + altMaintenanceBags = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceBags", true); + altMaintenanceAmmo = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceAmmo", true); + altMaintenanceFood = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceFood", true); + altMaintenanceReagents = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceReagents", true); + altMaintenanceConsumables = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceConsumables", true); + altMaintenancePotions = sConfigMgr->GetOption("AiPlayerbot.AltMaintenancePotions", true); + altMaintenanceTalentTree = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceTalentTree", true); + altMaintenancePet = sConfigMgr->GetOption("AiPlayerbot.AltMaintenancePet", true); + altMaintenancePetTalents = sConfigMgr->GetOption("AiPlayerbot.AltMaintenancePetTalents", true); + altMaintenanceClassSpells = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceClassSpells", true); + altMaintenanceAvailableSpells = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceAvailableSpells", true); + altMaintenanceSkills = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceSkills", true); + altMaintenanceReputation = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceReputation", true); + altMaintenanceSpecialSpells = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceSpecialSpells", true); + altMaintenanceMounts = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceMounts", true); + altMaintenanceGlyphs = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceGlyphs", true); + altMaintenanceKeyring = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceKeyring", true); + altMaintenanceGemsEnchants = sConfigMgr->GetOption("AiPlayerbot.AltMaintenanceGemsEnchants", true); + autoGearCommand = sConfigMgr->GetOption("AiPlayerbot.AutoGearCommand", 1); autoGearCommandAltBots = sConfigMgr->GetOption("AiPlayerbot.AutoGearCommandAltBots", 1); autoGearQualityLimit = sConfigMgr->GetOption("AiPlayerbot.AutoGearQualityLimit", 3); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index e7b404d8..391b991a 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -247,8 +247,6 @@ public: std::string randomBotCombatStrategies, randomBotNonCombatStrategies; bool applyInstanceStrategies; uint32 randomBotMinLevel, randomBotMaxLevel; - uint32 randomBotMinLoginLevel, randomBotMaxLoginLevel; - bool randomBotLogoutOutsideLoginRange; float randomChangeMultiplier; // std::string premadeLevelSpec[MAX_CLASSES][10][91]; //lvl 10 - 100 @@ -393,6 +391,25 @@ public: int32 addClassCommand; int32 addClassAccountPoolSize; int32 maintenanceCommand; + bool altMaintenanceAttunementQs, + altMaintenanceBags, + altMaintenanceAmmo, + altMaintenanceFood, + altMaintenanceReagents, + altMaintenanceConsumables, + altMaintenancePotions, + altMaintenanceTalentTree, + altMaintenancePet, + altMaintenancePetTalents, + altMaintenanceClassSpells, + altMaintenanceAvailableSpells, + altMaintenanceSkills, + altMaintenanceReputation, + altMaintenanceSpecialSpells, + altMaintenanceMounts, + altMaintenanceGlyphs, + altMaintenanceKeyring, + altMaintenanceGemsEnchants; int32 autoGearCommand, autoGearCommandAltBots, autoGearQualityLimit, autoGearScoreLimit; uint32 useGroundMountAtMinLevel; diff --git a/src/Playerbots.cpp b/src/Playerbots.cpp index 926e1f4e..b5334ba7 100644 --- a/src/Playerbots.cpp +++ b/src/Playerbots.cpp @@ -87,8 +87,7 @@ public: PLAYERHOOK_ON_BEFORE_CRITERIA_PROGRESS, PLAYERHOOK_ON_BEFORE_ACHI_COMPLETE, PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT, - PLAYERHOOK_ON_GIVE_EXP, - PLAYERHOOK_ON_LEVEL_CHANGED + PLAYERHOOK_ON_GIVE_EXP }) {} void OnPlayerLogin(Player* player) override @@ -122,33 +121,6 @@ public: } } - void OnPlayerLevelChanged(Player* player, uint8 oldLevel) override - { - // Check if feature is enabled and required objects are valid - if (!sPlayerbotAIConfig || !sPlayerbotAIConfig->randomBotLogoutOutsideLoginRange || !sRandomPlayerbotMgr) - return; - - // Only apply to bots from rndBotTypeAccounts (type 1) - uint32 accountId = player->GetSession()->GetAccountId(); - if (!sRandomPlayerbotMgr->IsAccountType(accountId, 1)) - return; - - uint32 newLevel = player->GetLevel(); - - // Check if the new level is outside the allowed login range - if (newLevel < sPlayerbotAIConfig->randomBotMinLoginLevel || - newLevel > sPlayerbotAIConfig->randomBotMaxLoginLevel) - { - LOG_INFO("playerbots", "Bot {} changed levels from {} to {}, outside login range ({}-{}). Marking for logout", - player->GetName(), oldLevel, newLevel, - sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel); - - // Mark the bot for removal in the next update cycle - sRandomPlayerbotMgr->MarkBotForLogout(player->GetGUID().GetCounter()); - sRandomPlayerbotMgr->ForceRecount(); - } - } - void OnPlayerAfterUpdate(Player* player, uint32 diff) override { if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player)) diff --git a/src/RandomPlayerbotMgr.cpp b/src/RandomPlayerbotMgr.cpp index 61b1df49..6d06303c 100644 --- a/src/RandomPlayerbotMgr.cpp +++ b/src/RandomPlayerbotMgr.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include "AccountMgr.h" #include "AiFactory.h" @@ -375,76 +374,13 @@ void RandomPlayerbotMgr::UpdateAIInternal(uint32 elapsed, bool /*minimal*/) }*/ uint32 maxAllowedBotCount = GetEventValue(0, "bot_count"); - - // Check if level filtering is active and populate eligible bots - if (!levelFilterAdjusted && IsLevelFilterActive()) + if (!maxAllowedBotCount || (maxAllowedBotCount < sPlayerbotAIConfig->minRandomBots || + maxAllowedBotCount > sPlayerbotAIConfig->maxRandomBots)) { - PopulateEligibleBots(); - - // Count total eligible bots from RNDbot accounts - uint32 eligibleBotCount = 0; - - for (uint32 accountId : rndBotTypeAccounts) - { - QueryResult result = CharacterDatabase.Query( - "SELECT COUNT(*) FROM characters WHERE account = {} AND level >= {} AND level <= {}", - accountId, sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel - ); - - if (result) - { - Field* fields = result->Fetch(); - eligibleBotCount += fields[0].Get(); - } - } - - if (eligibleBotCount > 0) - { - // Cap eligible bots by maxRandomBots - uint32 effectiveMaxBots = std::min(eligibleBotCount, sPlayerbotAIConfig->maxRandomBots); - - LOG_INFO("playerbots", "Level filter active: {} eligible bots found in range {}-{}. Effective maximum: {} bots.", - eligibleBotCount, sPlayerbotAIConfig->randomBotMinLoginLevel, - sPlayerbotAIConfig->randomBotMaxLoginLevel, effectiveMaxBots); - - if (effectiveMaxBots >= sPlayerbotAIConfig->minRandomBots) - { - maxAllowedBotCount = urand(sPlayerbotAIConfig->minRandomBots, effectiveMaxBots); - } - else - { - maxAllowedBotCount = effectiveMaxBots; - } - - SetEventValue(0, "bot_count", maxAllowedBotCount, - urand(sPlayerbotAIConfig->randomBotCountChangeMinInterval, - sPlayerbotAIConfig->randomBotCountChangeMaxInterval)); - - currentBots.clear(); - levelFilterAdjusted = true; - } - else - { - LOG_ERROR("playerbots", "No eligible bots found with level filter {}-{}. Change the level range.", - sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel); - SetEventValue(0, "bot_count", 0, INT_MAX); - maxAllowedBotCount = 0; - currentBots.clear(); - levelFilterAdjusted = true; - } - } - else if (!levelFilterAdjusted) - { - // Normal bot count logic (no level filtering) - if (!maxAllowedBotCount || (maxAllowedBotCount < sPlayerbotAIConfig->minRandomBots || - maxAllowedBotCount > sPlayerbotAIConfig->maxRandomBots)) - { - maxAllowedBotCount = urand(sPlayerbotAIConfig->minRandomBots, sPlayerbotAIConfig->maxRandomBots); - SetEventValue(0, "bot_count", maxAllowedBotCount, - urand(sPlayerbotAIConfig->randomBotCountChangeMinInterval, - sPlayerbotAIConfig->randomBotCountChangeMaxInterval)); - } - levelFilterAdjusted = true; + maxAllowedBotCount = urand(sPlayerbotAIConfig->minRandomBots, sPlayerbotAIConfig->maxRandomBots); + SetEventValue(0, "bot_count", maxAllowedBotCount, + urand(sPlayerbotAIConfig->randomBotCountChangeMinInterval, + sPlayerbotAIConfig->randomBotCountChangeMaxInterval)); } GetBots(); @@ -836,41 +772,23 @@ uint32 RandomPlayerbotMgr::AddRandomBots() for (uint32 accountId : accountsToUse) { - // Lambda to process results regardless of query type - auto processResults = [&](auto result) - { - if (!result) - return; + CharacterDatabasePreparedStatement* stmt = + CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID); + stmt->SetData(0, accountId); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) + continue; - do - { - Field* fields = result->Fetch(); - CharacterInfo info; - info.guid = fields[0].Get(); - info.rClass = fields[1].Get(); - info.rRace = fields[2].Get(); - info.accountId = accountId; - allCharacters.push_back(info); - } while (result->NextRow()); - }; - - if (IsLevelFilterActive()) + do { - // Custom query with level filtering - auto result = CharacterDatabase.Query( - "SELECT guid, class, race FROM characters WHERE account = {} AND level >= {} AND level <= {}", - accountId, sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel - ); - processResults(result); - } - else - { - CharacterDatabasePreparedStatement* stmt = - CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID); - stmt->SetData(0, accountId); - auto result = CharacterDatabase.Query(stmt); - processResults(result); - } + Field* fields = result->Fetch(); + CharacterInfo info; + info.guid = fields[0].Get(); + info.rClass = fields[1].Get(); + info.rRace = fields[2].Get(); + info.accountId = accountId; + allCharacters.push_back(info); + } while (result->NextRow()); } // Shuffle for class balance @@ -2753,55 +2671,17 @@ void RandomPlayerbotMgr::GetBots() stmt->SetData(0, 0); stmt->SetData(1, "add"); uint32 maxAllowedBotCount = GetEventValue(0, "bot_count"); - if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt)) { do { Field* fields = result->Fetch(); uint32 bot = fields[0].Get(); - if (GetEventValue(bot, "add")) - { - // Single query to get both account and level - QueryResult charResult = CharacterDatabase.Query("SELECT account, level FROM characters WHERE guid = {}", bot); - if (!charResult) - continue; - - Field* charFields = charResult->Fetch(); - uint32 botAccountId = charFields[0].Get(); - uint32 botLevel = charFields[1].Get(); - - // Skip if not an RNDbot account - bool isRndBotAccount = false; - for (uint32 accountId : rndBotTypeAccounts) - { - if (accountId == botAccountId) - { - isRndBotAccount = true; - break; - } - } - - if (!isRndBotAccount) - continue; - - // If level filtering is active, check bot level - if (IsLevelFilterActive()) - { - // Skip bots outside the allowed level range - if (botLevel < sPlayerbotAIConfig->randomBotMinLoginLevel || - botLevel > sPlayerbotAIConfig->randomBotMaxLoginLevel) - { - continue; - } - } - currentBots.push_back(bot); - if (currentBots.size() >= maxAllowedBotCount) - break; - } + if (currentBots.size() >= maxAllowedBotCount) + break; } while (result->NextRow()); } } @@ -2829,51 +2709,6 @@ std::vector RandomPlayerbotMgr::GetBgBots(uint32 bracket) return std::move(BgBots); } -void RandomPlayerbotMgr::PopulateEligibleBots() -{ - if (!sPlayerbotAIConfig || !(sPlayerbotAIConfig->randomBotMinLoginLevel > 1 || - sPlayerbotAIConfig->randomBotMaxLoginLevel < 80)) - return; - - LOG_INFO("playerbots", "Populating eligible bots for level filter ({}-{})...", - sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel); - - bool botsAdded = false; - - // Use only RNDbot type accounts (type 1) - for (uint32 accountId : rndBotTypeAccounts) - { - QueryResult result = CharacterDatabase.Query( - "SELECT guid, level, online FROM characters WHERE account = {} AND level >= {} AND level <= {}", - accountId, sPlayerbotAIConfig->randomBotMinLoginLevel, sPlayerbotAIConfig->randomBotMaxLoginLevel - ); - - if (result) - { - do - { - Field* fields = result->Fetch(); - uint32 botGuid = fields[0].Get(); - bool isOnline = fields[2].Get(); - - // Skip bots that are already online or already have "add" event - if (isOnline || GetEventValue(botGuid, "add")) - continue; - - uint32 add_time = urand(sPlayerbotAIConfig->minRandomBotInWorldTime, - sPlayerbotAIConfig->maxRandomBotInWorldTime); - SetEventValue(botGuid, "add", 1, add_time); - botsAdded = true; - } while (result->NextRow()); - } - } - - if (botsAdded) - { - currentBots.clear(); // Force reload - } -} - uint32 RandomPlayerbotMgr::GetEventValue(uint32 bot, std::string const event) { // load all events at once on first event load @@ -2901,13 +2736,23 @@ uint32 RandomPlayerbotMgr::GetEventValue(uint32 bot, std::string const event) } CachedEvent& e = eventCache[bot][event]; + /*if (e.IsEmpty()) + { + QueryResult results = PlayerbotsDatabase.Query("SELECT `value`, `time`, validIn, `data` FROM + playerbots_random_bots WHERE owner = 0 AND bot = {} AND event = {}", bot, event.c_str()); - bool shouldExpire = (time(0) - e.lastChangeTime) >= e.validIn && - event != "specNo" && - event != "specLink" && - !(event == "bot_count" && IsLevelFilterActive()); // Don't expire bot_count when level filtering is active + if (results) + { + Field* fields = results->Fetch(); + e.value = fields[0].Get(); + e.lastChangeTime = fields[1].Get(); + e.validIn = fields[2].Get(); + e.data = fields[3].Get(); + } + } + */ - if (shouldExpire) + if ((time(0) - e.lastChangeTime) >= e.validIn && event != "specNo" && event != "specLink") e.value = 0; return e.value; diff --git a/src/RandomPlayerbotMgr.h b/src/RandomPlayerbotMgr.h index 0906ef54..be624328 100644 --- a/src/RandomPlayerbotMgr.h +++ b/src/RandomPlayerbotMgr.h @@ -193,14 +193,6 @@ public: void AssignAccountTypes(); bool IsAccountType(uint32 accountId, uint8 accountType); - // Allowed login range management - void ForceRecount() { SetEventValue(0, "bot_count", 0, 0); } - void MarkBotForLogout(uint32 bot) - { - SetEventValue(bot, "add", 0, 0); // Clear the "add" event to trigger logout - SetEventValue(bot, "logout", 1, 1); // Also set logout for clarity - } - protected: void OnBotLoginInternal(Player* const bot) override; @@ -245,16 +237,6 @@ private: std::vector rndBotTypeAccounts; // Accounts marked as RNDbot (type 1) std::vector addClassTypeAccounts; // Accounts marked as AddClass (type 2) - // Login level filtering - bool levelFilterAdjusted = false; - void PopulateEligibleBots(); - bool IsLevelFilterActive() const - { - return sPlayerbotAIConfig && - (sPlayerbotAIConfig->randomBotMinLoginLevel > 1 || - sPlayerbotAIConfig->randomBotMaxLoginLevel < 80); - } - //void ScaleBotActivity(); // Deprecated function }; diff --git a/src/strategy/actions/TrainerAction.cpp b/src/strategy/actions/TrainerAction.cpp index 2de9d283..c5509cf8 100644 --- a/src/strategy/actions/TrainerAction.cpp +++ b/src/strategy/actions/TrainerAction.cpp @@ -170,26 +170,89 @@ bool MaintenanceAction::Execute(Event event) botAI->TellMaster("I'm maintaining"); PlayerbotFactory factory(bot, bot->GetLevel()); - factory.InitAttunementQuests(); - factory.InitBags(false); - factory.InitAmmo(); - factory.InitFood(); - factory.InitReagents(); - factory.InitConsumables(); - factory.InitPotions(); - factory.InitTalentsTree(true); - factory.InitPet(); - factory.InitPetTalents(); - factory.InitClassSpells(); - factory.InitAvailableSpells(); - factory.InitSkills(); - factory.InitReputation(); - factory.InitSpecialSpells(); - factory.InitMounts(); - factory.InitGlyphs(false); - factory.InitKeyring(); - if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel) - factory.ApplyEnchantAndGemsNew(); + + if (!botAI->IsAlt()) + { + factory.InitAttunementQuests(); + factory.InitBags(false); + factory.InitAmmo(); + factory.InitFood(); + factory.InitReagents(); + factory.InitConsumables(); + factory.InitPotions(); + factory.InitTalentsTree(true); + factory.InitPet(); + factory.InitPetTalents(); + factory.InitClassSpells(); + factory.InitAvailableSpells(); + factory.InitSkills(); + factory.InitReputation(); + factory.InitSpecialSpells(); + factory.InitMounts(); + factory.InitGlyphs(false); + factory.InitKeyring(); + if (bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel) + factory.ApplyEnchantAndGemsNew(); + } + else + { + if (sPlayerbotAIConfig->altMaintenanceAttunementQs) + factory.InitAttunementQuests(); + + if (sPlayerbotAIConfig->altMaintenanceBags) + factory.InitBags(false); + + if (sPlayerbotAIConfig->altMaintenanceAmmo) + factory.InitAmmo(); + + if (sPlayerbotAIConfig->altMaintenanceFood) + factory.InitFood(); + + if (sPlayerbotAIConfig->altMaintenanceReagents) + factory.InitReagents(); + + if (sPlayerbotAIConfig->altMaintenanceConsumables) + factory.InitConsumables(); + + if (sPlayerbotAIConfig->altMaintenancePotions) + factory.InitPotions(); + + if (sPlayerbotAIConfig->altMaintenanceTalentTree) + factory.InitTalentsTree(true); + + if (sPlayerbotAIConfig->altMaintenancePet) + factory.InitPet(); + + if (sPlayerbotAIConfig->altMaintenancePetTalents) + factory.InitPetTalents(); + + if (sPlayerbotAIConfig->altMaintenanceClassSpells) + factory.InitClassSpells(); + + if (sPlayerbotAIConfig->altMaintenanceAvailableSpells) + factory.InitAvailableSpells(); + + if (sPlayerbotAIConfig->altMaintenanceSkills) + factory.InitSkills(); + + if (sPlayerbotAIConfig->altMaintenanceReputation) + factory.InitReputation(); + + if (sPlayerbotAIConfig->altMaintenanceSpecialSpells) + factory.InitSpecialSpells(); + + if (sPlayerbotAIConfig->altMaintenanceMounts) + factory.InitMounts(); + + if (sPlayerbotAIConfig->altMaintenanceGlyphs) + factory.InitGlyphs(false); + + if (sPlayerbotAIConfig->altMaintenanceKeyring) + factory.InitKeyring(); + + if (sPlayerbotAIConfig->altMaintenanceGemsEnchants && bot->GetLevel() >= sPlayerbotAIConfig->minEnchantingBotLevel) + factory.ApplyEnchantAndGemsNew(); + } bot->DurabilityRepairAll(false, 1.0f, false); bot->SendTalentsInfoData(false);