/* * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version. */ #include "PlayerbotAIConfig.h" #include "Config.h" #include "Playerbots.h" #include "PlayerbotFactory.h" #include "RandomItemMgr.h" #include "RandomPlayerbotFactory.h" #include "Talentspec.h" #include "PlayerbotDungeonSuggestionMgr.h" #include template void LoadList(std::string const value, T& list) { std::vector ids = split(value, ','); for (std::vector::iterator i = ids.begin(); i != ids.end(); i++) { uint32 id = atoi((*i).c_str()); // if (!id) // continue; list.push_back(id); } } template void LoadListString(std::string const value, T& list) { std::vector strings = split(value, ','); for (std::vector::iterator i = strings.begin(); i != strings.end(); i++) { std::string const string = *i; if (string.empty()) continue; list.push_back(string); } } bool PlayerbotAIConfig::Initialize() { LOG_INFO("server.loading", "Initializing AI Playerbots by ike3, based on the original Playerbots by blueboy"); enabled = sConfigMgr->GetOption("AiPlayerbot.Enabled", true); if (!enabled) { LOG_INFO("server.loading", "AI Playerbots is Disabled in aiplayerbot.conf"); return false; } globalCoolDown = sConfigMgr->GetOption("AiPlayerbot.GlobalCooldown", 1500); maxWaitForMove = sConfigMgr->GetOption("AiPlayerbot.MaxWaitForMove", 5000); maxMovementSearchTime = sConfigMgr->GetOption("AiPlayerbot.MaxMovementSearchTime", 3); expireActionTime = sConfigMgr->GetOption("AiPlayerbot.ExpireActionTime", 5000); dispelAuraDuration = sConfigMgr->GetOption("AiPlayerbot.DispelAuraDuration", 7000); reactDelay = sConfigMgr->GetOption("AiPlayerbot.ReactDelay", 500); passiveDelay = sConfigMgr->GetOption("AiPlayerbot.PassiveDelay", 10000); repeatDelay = sConfigMgr->GetOption("AiPlayerbot.RepeatDelay", 5000); errorDelay = sConfigMgr->GetOption("AiPlayerbot.ErrorDelay", 5000); rpgDelay = sConfigMgr->GetOption("AiPlayerbot.RpgDelay", 10000); sitDelay = sConfigMgr->GetOption("AiPlayerbot.SitDelay", 30000); returnDelay = sConfigMgr->GetOption("AiPlayerbot.ReturnDelay", 7000); lootDelay = sConfigMgr->GetOption("AiPlayerbot.LootDelay", 1000); farDistance = sConfigMgr->GetOption("AiPlayerbot.FarDistance", 20.0f); sightDistance = sConfigMgr->GetOption("AiPlayerbot.SightDistance", 75.0f); spellDistance = sConfigMgr->GetOption("AiPlayerbot.SpellDistance", 25.0f); shootDistance = sConfigMgr->GetOption("AiPlayerbot.ShootDistance", 25.0f); healDistance = sConfigMgr->GetOption("AiPlayerbot.HealDistance", 25.0f); lootDistance = sConfigMgr->GetOption("AiPlayerbot.LootDistance", 15.0f); fleeDistance = sConfigMgr->GetOption("AiPlayerbot.FleeDistance", 7.5f); aggroDistance = sConfigMgr->GetOption("AiPlayerbot.AggroDistance", 22.0f); tooCloseDistance = sConfigMgr->GetOption("AiPlayerbot.TooCloseDistance", 5.0f); meleeDistance = sConfigMgr->GetOption("AiPlayerbot.MeleeDistance", 1.5f); followDistance = sConfigMgr->GetOption("AiPlayerbot.FollowDistance", 1.5f); whisperDistance = sConfigMgr->GetOption("AiPlayerbot.WhisperDistance", 6000.0f); contactDistance = sConfigMgr->GetOption("AiPlayerbot.ContactDistance", 0.5f); aoeRadius = sConfigMgr->GetOption("AiPlayerbot.AoeRadius", 5.0f); rpgDistance = sConfigMgr->GetOption("AiPlayerbot.RpgDistance", 200.0f); grindDistance = sConfigMgr->GetOption("AiPlayerbot.GrindDistance", 75.0f); reactDistance = sConfigMgr->GetOption("AiPlayerbot.ReactDistance", 150.0f); criticalHealth = sConfigMgr->GetOption("AiPlayerbot.CriticalHealth", 20); lowHealth = sConfigMgr->GetOption("AiPlayerbot.LowHealth", 45); mediumHealth = sConfigMgr->GetOption("AiPlayerbot.MediumHealth", 65); almostFullHealth = sConfigMgr->GetOption("AiPlayerbot.AlmostFullHealth", 85); lowMana = sConfigMgr->GetOption("AiPlayerbot.LowMana", 15); mediumMana = sConfigMgr->GetOption("AiPlayerbot.MediumMana", 40); autoSaveMana = sConfigMgr->GetOption("AiPlayerbot.AutoSaveMana", true); saveManaThreshold = sConfigMgr->GetOption("AiPlayerbot.SaveManaThreshold", 60); autoAvoidAoe = sConfigMgr->GetOption("AiPlayerbot.AutoAvoidAoe", true); tellWhenAvoidAoe = sConfigMgr->GetOption("AiPlayerbot.TellWhenAvoidAoe", true); randomGearLoweringChance = sConfigMgr->GetOption("AiPlayerbot.RandomGearLoweringChance", 0.15f); randomBotMaxLevelChance = sConfigMgr->GetOption("AiPlayerbot.RandomBotMaxLevelChance", 0.15f); randomBotRpgChance = sConfigMgr->GetOption("AiPlayerbot.RandomBotRpgChance", 0.20f); iterationsPerTick = sConfigMgr->GetOption("AiPlayerbot.IterationsPerTick", 100); allowGuildBots = sConfigMgr->GetOption("AiPlayerbot.AllowGuildBots", true); allowPlayerBots = sConfigMgr->GetOption("AiPlayerbot.AllowPlayerBots", false); randomBotMapsAsString = sConfigMgr->GetOption("AiPlayerbot.RandomBotMaps", "0,1,530,571"); LoadList>(randomBotMapsAsString, randomBotMaps); probTeleToBankers = sConfigMgr->GetOption("AiPlayerbot.ProbTeleToBankers", 0.25f); LoadList>(sConfigMgr->GetOption("AiPlayerbot.RandomBotQuestItems", "6948,5175,5176,5177,5178,16309,12382,13704,11000"), randomBotQuestItems); LoadList>(sConfigMgr->GetOption("AiPlayerbot.RandomBotSpellIds", "54197"), randomBotSpellIds); LoadList>(sConfigMgr->GetOption("AiPlayerbot.PvpProhibitedZoneIds", "2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565,3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395"), pvpProhibitedZoneIds); LoadList>(sConfigMgr->GetOption("AiPlayerbot.PvpProhibitedAreaIds", "976,35"), pvpProhibitedAreaIds); LoadList>(sConfigMgr->GetOption("AiPlayerbot.RandomBotQuestIds", "7848,3802,5505,6502,7761"), randomBotQuestIds); botAutologin = sConfigMgr->GetOption("AiPlayerbot.BotAutologin", false); randomBotAutologin = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutologin", true); minRandomBots = sConfigMgr->GetOption("AiPlayerbot.MinRandomBots", 50); maxRandomBots = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBots", 200); randomBotUpdateInterval = sConfigMgr->GetOption("AiPlayerbot.RandomBotUpdateInterval", MINUTE); randomBotCountChangeMinInterval = sConfigMgr->GetOption("AiPlayerbot.RandomBotCountChangeMinInterval", 30 * MINUTE); randomBotCountChangeMaxInterval = sConfigMgr->GetOption("AiPlayerbot.RandomBotCountChangeMaxInterval", 2 * HOUR); minRandomBotInWorldTime = sConfigMgr->GetOption("AiPlayerbot.MinRandomBotInWorldTime", 2 * HOUR); maxRandomBotInWorldTime = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBotInWorldTime", 12 * HOUR); minRandomBotRandomizeTime = sConfigMgr->GetOption("AiPlayerbot.MinRandomBotRandomizeTime", 2 * HOUR); maxRandomBotRandomizeTime = sConfigMgr->GetOption("AiPlayerbot.MaxRandomRandomizeTime", 14 * 24 * HOUR); minRandomBotChangeStrategyTime = sConfigMgr->GetOption("AiPlayerbot.MinRandomBotChangeStrategyTime", 30 * MINUTE); maxRandomBotChangeStrategyTime = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBotChangeStrategyTime", 2 * HOUR); minRandomBotReviveTime = sConfigMgr->GetOption("AiPlayerbot.MinRandomBotReviveTime", MINUTE); maxRandomBotReviveTime = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBotReviveTime", 5 * MINUTE); minRandomBotTeleportInterval = sConfigMgr->GetOption("AiPlayerbot.MinRandomBotTeleportInterval", 1 * HOUR); maxRandomBotTeleportInterval = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBotTeleportInterval", 5 * HOUR); randomBotInWorldWithRotationDisabled = sConfigMgr->GetOption("AiPlayerbot.RandomBotInWorldWithRotationDisabled", 1 * YEAR); randomBotTeleportDistance = sConfigMgr->GetOption("AiPlayerbot.RandomBotTeleportDistance", 100); randomBotsPerInterval = sConfigMgr->GetOption("AiPlayerbot.RandomBotsPerInterval", MINUTE); minRandomBotsPriceChangeInterval = sConfigMgr->GetOption("AiPlayerbot.MinRandomBotsPriceChangeInterval", 2 * HOUR); maxRandomBotsPriceChangeInterval = sConfigMgr->GetOption("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR); randomBotJoinLfg = sConfigMgr->GetOption("AiPlayerbot.RandomBotJoinLfg", true); randomBotSuggestDungeons = sConfigMgr->GetOption("AiPlayerbot.RandomBotSuggestDungeons", true); suggestDungeonsInLowerCaseRandomly = sConfigMgr->GetOption("AiPlayerbot.SuggestDungeonsInLowerCaseRandomly", false); randomBotJoinBG = sConfigMgr->GetOption("AiPlayerbot.RandomBotJoinBG", true); randomBotAutoJoinBG = sConfigMgr->GetOption("AiPlayerbot.RandomBotAutoJoinBG", false); logInGroupOnly = sConfigMgr->GetOption("AiPlayerbot.LogInGroupOnly", true); logValuesPerTick = sConfigMgr->GetOption("AiPlayerbot.LogValuesPerTick", false); fleeingEnabled = sConfigMgr->GetOption("AiPlayerbot.FleeingEnabled", true); summonAtInnkeepersEnabled = sConfigMgr->GetOption("AiPlayerbot.SummonAtInnkeepersEnabled", true); randomBotMinLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotMinLevel", 1); randomBotMaxLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotMaxLevel", 80); randomBotLoginAtStartup = sConfigMgr->GetOption("AiPlayerbot.RandomBotLoginAtStartup", true); randomBotTeleLowerLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotTeleLowerLevel", 3); randomBotTeleHigherLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotTeleHigherLevel", 1); openGoSpell = sConfigMgr->GetOption("AiPlayerbot.OpenGoSpell", 6477); randomChangeMultiplier = sConfigMgr->GetOption("AiPlayerbot.RandomChangeMultiplier", 1.0); randomBotCombatStrategies = sConfigMgr->GetOption("AiPlayerbot.RandomBotCombatStrategies", "-threat"); randomBotNonCombatStrategies = sConfigMgr->GetOption("AiPlayerbot.RandomBotNonCombatStrategies", ""); combatStrategies = sConfigMgr->GetOption("AiPlayerbot.CombatStrategies", "+custom::say"); nonCombatStrategies = sConfigMgr->GetOption("AiPlayerbot.NonCombatStrategies", "+custom::say,+return"); commandPrefix = sConfigMgr->GetOption("AiPlayerbot.CommandPrefix", ""); commandSeparator = sConfigMgr->GetOption("AiPlayerbot.CommandSeparator", "\\\\"); commandServerPort = sConfigMgr->GetOption("AiPlayerbot.CommandServerPort", 8888); perfMonEnabled = sConfigMgr->GetOption("AiPlayerbot.PerfMonEnabled", false); LOG_INFO("server.loading", "---------------------------------------"); LOG_INFO("server.loading", " Loading TalentSpecs "); LOG_INFO("server.loading", "---------------------------------------"); for (uint32 cls = 1; cls < MAX_CLASSES; ++cls) { if (cls == 10) { continue; } for (uint32 spec = 0; spec < MAX_SPECNO; ++spec) { std::ostringstream os; os << "AiPlayerbot.PremadeSpecName." << cls << "." << spec; premadeSpecName[cls][spec] = sConfigMgr->GetOption(os.str().c_str(), "", false); os.str(""); os.clear(); os << "AiPlayerbot.PremadeSpecGlyph." << cls << "." << spec; premadeSpecGlyph[cls][spec] = sConfigMgr->GetOption(os.str().c_str(), "", false); std::vector splitSpecGlyph = split(premadeSpecGlyph[cls][spec], ','); for (std::string &split : splitSpecGlyph) { if (split.size() != 0) { parsedSpecGlyph[cls][spec].push_back(atoi(split.c_str())); } } for (uint32 level = 0; level < MAX_LEVEL; ++level) { std::ostringstream os; os << "AiPlayerbot.PremadeSpecLink." << cls << "." << spec << "." << level; premadeSpecLink[cls][spec][level] = sConfigMgr->GetOption(os.str().c_str(), "", false); parsedSpecLinkOrder[cls][spec][level] = ParseTempTalentsOrder(cls, premadeSpecLink[cls][spec][level]); } } for (uint32 spec = 0; spec < 3; ++spec) { std::ostringstream os; os << "AiPlayerbot.RandomClassSpecProb." << cls << "." << spec; randomClassSpecProb[cls][spec] = sConfigMgr->GetOption(os.str().c_str(), 33); os.str(""); os.clear(); os << "AiPlayerbot.RandomClassSpecIndex." << cls << "." << spec; randomClassSpecIndex[cls][spec] = sConfigMgr->GetOption(os.str().c_str(), spec + 1); } } botCheats.clear(); LoadListString>(sConfigMgr->GetOption("AiPlayerbot.BotCheats", "taxi"), botCheats); botCheatMask = 0; if (std::find(botCheats.begin(), botCheats.end(), "taxi") != botCheats.end()) botCheatMask |= (uint32)BotCheatMask::taxi; if (std::find(botCheats.begin(), botCheats.end(), "gold") != botCheats.end()) botCheatMask |= (uint32)BotCheatMask::gold; if (std::find(botCheats.begin(), botCheats.end(), "health") != botCheats.end()) botCheatMask |= (uint32)BotCheatMask::health; if (std::find(botCheats.begin(), botCheats.end(), "mana") != botCheats.end()) botCheatMask |= (uint32)BotCheatMask::mana; if (std::find(botCheats.begin(), botCheats.end(), "power") != botCheats.end()) botCheatMask |= (uint32)BotCheatMask::power; LoadListString>(sConfigMgr->GetOption("AiPlayerbot.AllowedLogFiles", ""), allowedLogFiles); worldBuffs.clear(); for (uint32 factionId = 0; factionId < 3; factionId++) { for (uint32 classId = 0; classId < MAX_CLASSES; classId++) { for (uint32 minLevel = 0; minLevel < MAX_LEVEL; minLevel++) { for (uint32 maxLevel = 0; maxLevel < MAX_LEVEL; maxLevel++) { loadWorldBuf(factionId, classId, minLevel, maxLevel); } } } } randomBotAccountPrefix = sConfigMgr->GetOption("AiPlayerbot.RandomBotAccountPrefix", "rndbot"); randomBotAccountCount = sConfigMgr->GetOption("AiPlayerbot.RandomBotAccountCount", 200); deleteRandomBotAccounts = sConfigMgr->GetOption("AiPlayerbot.DeleteRandomBotAccounts", false); randomBotGuildCount = sConfigMgr->GetOption("AiPlayerbot.RandomBotGuildCount", 20); deleteRandomBotGuilds = sConfigMgr->GetOption("AiPlayerbot.DeleteRandomBotGuilds", false); guildTaskEnabled = sConfigMgr->GetOption("AiPlayerbot.EnableGuildTasks", true); minGuildTaskChangeTime = sConfigMgr->GetOption("AiPlayerbot.MinGuildTaskChangeTime", 3 * 24 * 3600); maxGuildTaskChangeTime = sConfigMgr->GetOption("AiPlayerbot.MaxGuildTaskChangeTime", 4 * 24 * 3600); minGuildTaskAdvertisementTime = sConfigMgr->GetOption("AiPlayerbot.MinGuildTaskAdvertisementTime", 300); maxGuildTaskAdvertisementTime = sConfigMgr->GetOption("AiPlayerbot.MaxGuildTaskAdvertisementTime", 12 * 3600); minGuildTaskRewardTime = sConfigMgr->GetOption("AiPlayerbot.MinGuildTaskRewardTime", 300); maxGuildTaskRewardTime = sConfigMgr->GetOption("AiPlayerbot.MaxGuildTaskRewardTime", 3600); guildTaskAdvertCleanupTime = sConfigMgr->GetOption("AiPlayerbot.GuildTaskAdvertCleanupTime", 300); guildTaskKillTaskDistance = sConfigMgr->GetOption("AiPlayerbot.GuildTaskKillTaskDistance", 2000); targetPosRecalcDistance = sConfigMgr->GetOption("AiPlayerbot.TargetPosRecalcDistance", 0.1f); // cosmetics (by lidocain) randomBotShowCloak = sConfigMgr->GetOption("AiPlayerbot.RandomBotShowCloak", true); randomBotShowHelmet = sConfigMgr->GetOption("AiPlayerbot.RandomBotShowHelmet", true); // SPP switches enableGreet = sConfigMgr->GetOption("AiPlayerbot.EnableGreet", true); summonWhenGroup = sConfigMgr->GetOption("AiPlayerbot.SummonWhenGroup", true); randomBotFixedLevel = sConfigMgr->GetOption("AiPlayerbot.RandomBotFixedLevel", false); disableRandomLevels = sConfigMgr->GetOption("AiPlayerbot.DisableRandomLevels", false); randomBotRandomPassword = sConfigMgr->GetOption("AiPlayerbot.RandomBotRandomPassword", true); downgradeMaxLevelBot = sConfigMgr->GetOption("AiPlayerbot.DowngradeMaxLevelBot", true); equipmentPersistence = sConfigMgr->GetOption("AiPlayerbot.EquipmentPersistence", false); equipmentPersistenceLevel = sConfigMgr->GetOption("AiPlayerbot.EquipmentPersistenceLevel", 80); groupInvitationPermission = sConfigMgr->GetOption("AiPlayerbot.GroupInvitationPermission", 1); botReviveWhenSummon = sConfigMgr->GetOption("AiPlayerbot.BotReviveWhenSummon", 1); autoInitOnly = sConfigMgr->GetOption("AiPlayerbot.AutoInitOnly", false); autoInitEquipLevelLimitRatio = sConfigMgr->GetOption("AiPlayerbot.AutoInitEquipLevelLimitRatio", 1.0); addClassCommand = sConfigMgr->GetOption("AiPlayerbot.AddClassCommand", 1); maintenanceCommand = sConfigMgr->GetOption("AiPlayerbot.MaintenanceCommand", 1); autoGearCommand = sConfigMgr->GetOption("AiPlayerbot.AutoGearCommand", 1); autoGearQualityLimit = sConfigMgr->GetOption("AiPlayerbot.AutoGearQualityLimit", 3); autoGearScoreLimit = sConfigMgr->GetOption("AiPlayerbot.AutoGearScoreLimit", 0); playerbotsXPrate = sConfigMgr->GetOption("AiPlayerbot.KillXPRate", 1); disableDeathKnightLogin = sConfigMgr->GetOption("AiPlayerbot.DisableDeathKnightLogin", 0); botActiveAlone = sConfigMgr->GetOption("AiPlayerbot.BotActiveAlone", 10); enablePrototypePerformanceDiff = sConfigMgr->GetOption("AiPlayerbot.EnablePrototypePerformanceDiff", false); diffWithPlayer = sConfigMgr->GetOption("AiPlayerbot.DiffWithPlayer", 100); diffEmpty = sConfigMgr->GetOption("AiPlayerbot.DiffEmpty", 200); randombotsWalkingRPG = sConfigMgr->GetOption("AiPlayerbot.RandombotsWalkingRPG", false); randombotsWalkingRPGInDoors = sConfigMgr->GetOption("AiPlayerbot.RandombotsWalkingRPG.InDoors", false); minEnchantingBotLevel = sConfigMgr->GetOption("AiPlayerbot.MinEnchantingBotLevel", 60); limitEnchantExpansion = sConfigMgr->GetOption("AiPlayerbot.LimitEnchantExpansion", 1); randombotStartingLevel = sConfigMgr->GetOption("AiPlayerbot.RandombotStartingLevel", 5); enableRotation = sConfigMgr->GetOption("AiPlayerbot.EnableRotation", false); rotationPoolSize = sConfigMgr->GetOption("AiPlayerbot.RotationPoolSize", 500); gearscorecheck = sConfigMgr->GetOption("AiPlayerbot.GearScoreCheck", false); randomBotPreQuests = sConfigMgr->GetOption("AiPlayerbot.PreQuests", true); // SPP automation freeMethodLoot = sConfigMgr->GetOption("AiPlayerbot.FreeMethodLoot", false); lootRollLevel = sConfigMgr->GetOption("AiPlayerbot.LootRollLevel", 1); autoPickReward = sConfigMgr->GetOption("AiPlayerbot.AutoPickReward", "yes"); autoEquipUpgradeLoot = sConfigMgr->GetOption("AiPlayerbot.AutoEquipUpgradeLoot", true); equipUpgradeThreshold = sConfigMgr->GetOption("AiPlayerbot.EquipUpgradeThreshold", 1.1f); syncQuestWithPlayer = sConfigMgr->GetOption("AiPlayerbot.SyncQuestWithPlayer", true); syncQuestForPlayer = sConfigMgr->GetOption("AiPlayerbot.SyncQuestForPlayer", false); autoTrainSpells = sConfigMgr->GetOption("AiPlayerbot.AutoTrainSpells", "yes"); autoPickTalents = sConfigMgr->GetOption("AiPlayerbot.AutoPickTalents", true); autoUpgradeEquip = sConfigMgr->GetOption("AiPlayerbot.AutoUpgradeEquip", false); autoLearnTrainerSpells = sConfigMgr->GetOption("AiPlayerbot.AutoLearnTrainerSpells", true); autoLearnQuestSpells = sConfigMgr->GetOption("AiPlayerbot.AutoLearnQuestSpells", false); autoTeleportForLevel = sConfigMgr->GetOption("AiPlayerbot.AutoTeleportForLevel", false); autoDoQuests = sConfigMgr->GetOption("AiPlayerbot.AutoDoQuests", false); syncLevelWithPlayers = sConfigMgr->GetOption("AiPlayerbot.SyncLevelWithPlayers", false); freeFood = sConfigMgr->GetOption("AiPlayerbot.FreeFood", true); randomBotSayWithoutMaster = sConfigMgr->GetOption("AiPlayerbot.RandomBotSayWithoutMaster", false); randomBotGroupNearby = sConfigMgr->GetOption("AiPlayerbot.RandomBotGroupNearby", true); // arena randomBotArenaTeamCount = sConfigMgr->GetOption("AiPlayerbot.RandomBotArenaTeamCount", 20); deleteRandomBotArenaTeams = sConfigMgr->GetOption("AiPlayerbot.DeleteRandomBotArenaTeams", false); selfBotLevel = sConfigMgr->GetOption("AiPlayerbot.SelfBotLevel", 1); RandomPlayerbotFactory::CreateRandomBots(); PlayerbotFactory::Init(); sRandomItemMgr->Init(); sRandomItemMgr->InitAfterAhBot(); sPlayerbotTextMgr->LoadBotTexts(); sPlayerbotTextMgr->LoadBotTextChance(); if (!sPlayerbotAIConfig->autoDoQuests) { LOG_INFO("server.loading", "Loading Quest Detail Data..."); sTravelMgr->LoadQuestTravelTable(); } if (sPlayerbotAIConfig->randomBotJoinBG) sRandomPlayerbotMgr->LoadBattleMastersCache(); if (sPlayerbotAIConfig->randomBotSuggestDungeons) { sPlayerbotDungeonSuggestionMgr->LoadDungeonSuggestions(); } LOG_INFO("server.loading", "---------------------------------------"); LOG_INFO("server.loading", " AI Playerbots initialized "); LOG_INFO("server.loading", "---------------------------------------"); return true; } bool PlayerbotAIConfig::IsInRandomAccountList(uint32 id) { return find(randomBotAccounts.begin(), randomBotAccounts.end(), id) != randomBotAccounts.end(); } bool PlayerbotAIConfig::IsInRandomQuestItemList(uint32 id) { return find(randomBotQuestItems.begin(), randomBotQuestItems.end(), id) != randomBotQuestItems.end(); } bool PlayerbotAIConfig::IsPvpProhibited(uint32 zoneId, uint32 areaId) { return IsInPvpProhibitedZone(zoneId) || IsInPvpProhibitedArea(areaId); } bool PlayerbotAIConfig::IsInPvpProhibitedZone(uint32 id) { return find(pvpProhibitedZoneIds.begin(), pvpProhibitedZoneIds.end(), id) != pvpProhibitedZoneIds.end(); } bool PlayerbotAIConfig::IsInPvpProhibitedArea(uint32 id) { return find(pvpProhibitedAreaIds.begin(), pvpProhibitedAreaIds.end(), id) != pvpProhibitedAreaIds.end(); } std::string const PlayerbotAIConfig::GetTimestampStr() { time_t t = time(nullptr); tm* aTm = localtime(&t); // YYYY year // MM month (2 digits 01-12) // DD day (2 digits 01-31) // HH hour (2 digits 00-23) // MM minutes (2 digits 00-59) // SS seconds (2 digits 00-59) char buf[20]; snprintf(buf, 20, "%04d-%02d-%02d %02d-%02d-%02d", aTm->tm_year + 1900, aTm->tm_mon + 1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec); return std::string(buf); } bool PlayerbotAIConfig::openLog(std::string const fileName, char const* mode) { if (!hasLog(fileName)) return false; auto logFileIt = logFiles.find(fileName); if (logFileIt == logFiles.end()) { logFiles.insert(std::make_pair(fileName, std::make_pair(nullptr, false))); logFileIt = logFiles.find(fileName); } FILE* file = logFileIt->second.first; bool fileOpen = logFileIt->second.second; if (fileOpen) //close log file fclose(file); std::string m_logsDir = sConfigMgr->GetOption("LogsDir", "", false); if (!m_logsDir.empty()) { if ((m_logsDir.at(m_logsDir.length() - 1) != '/') && (m_logsDir.at(m_logsDir.length() - 1) != '\\')) m_logsDir.append("/"); } file = fopen((m_logsDir + fileName).c_str(), mode); fileOpen = true; logFileIt->second.first = file; logFileIt->second.second = fileOpen; return true; } void PlayerbotAIConfig::log(std::string const fileName, char const* str, ...) { if (!str) return; std::lock_guard guard(m_logMtx); if (!isLogOpen(fileName) && !openLog(fileName, "a")) return; FILE* file = logFiles.find(fileName)->second.first; va_list ap; va_start(ap, str); vfprintf(file, str, ap); fprintf(file, "\n"); va_end(ap); fflush(file); fflush(stdout); } void PlayerbotAIConfig::loadWorldBuf(uint32 factionId1, uint32 classId1, uint32 minLevel1, uint32 maxLevel1) { std::vector buffs; std::ostringstream os; os << "AiPlayerbot.WorldBuff." << factionId1 << "." << classId1 << "." << minLevel1 << "." << maxLevel1; LoadList>(sConfigMgr->GetOption(os.str().c_str(), "", false), buffs); for (auto buff : buffs) { worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 }; worldBuffs.push_back(wb); } if (maxLevel1 == 0) { std::ostringstream os; os << "AiPlayerbot.WorldBuff." << factionId1 << "." << classId1 << "." << minLevel1; LoadList>(sConfigMgr->GetOption(os.str().c_str(), "", false), buffs); for (auto buff : buffs) { worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 }; worldBuffs.push_back(wb); } } if (maxLevel1 == 0 && minLevel1 == 0) { std::ostringstream os; os << "AiPlayerbot.WorldBuff." << factionId1 << "." << factionId1 << "." << classId1; LoadList>(sConfigMgr->GetOption(os.str().c_str(), "", false), buffs); for (auto buff : buffs) { worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 }; worldBuffs.push_back(wb); } } if (classId1 == 0 && maxLevel1 == 0 && minLevel1 == 0) { std::ostringstream os; os << "AiPlayerbot.WorldBuff." << factionId1; LoadList>(sConfigMgr->GetOption(os.str().c_str(), "", false), buffs); for (auto buff : buffs) { worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 }; worldBuffs.push_back(wb); } } if (factionId1 == 0 && classId1 == 0 && maxLevel1 == 0 && minLevel1 == 0) { std::ostringstream os; os << "AiPlayerbot.WorldBuff"; LoadList>(sConfigMgr->GetOption(os.str().c_str(), "", false), buffs); for (auto buff : buffs) { worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 }; worldBuffs.push_back(wb); } } } static std::vector split(const std::string &str, const std::string &pattern) { std::vector res; if(str == "") return res; // Also add separators to string connections to facilitate intercepting the last paragraph. std::string strs = str + pattern; size_t pos = strs.find(pattern); while(pos != strs.npos) { std::string temp = strs.substr(0, pos); res.push_back(temp); // Remove the split string and split the remaining string strs = strs.substr(pos+1, strs.size()); pos = strs.find(pattern); } return res; } std::vector> PlayerbotAIConfig::ParseTempTalentsOrder(uint32 cls, std::string tab_link) { // check bad link uint32 classMask = 1 << (cls - 1); std::vector> res; std::vector tab_links = split(tab_link, "-"); std::map> spells; std::vector>> orders(3); for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const *talentInfo = sTalentStore.LookupEntry(i); if(!talentInfo) continue; TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab ); if(!talentTabInfo) continue; if( (classMask & talentTabInfo->ClassMask) == 0 ) continue; spells[talentTabInfo->tabpage].push_back(talentInfo); } for (int tab = 0; tab < 3; tab++) { if (tab_links.size() <= tab) { break; } std::sort(spells[tab].begin(), spells[tab].end(), [&](TalentEntry const* lhs, TalentEntry const* rhs) { return lhs->Row != rhs->Row ? lhs->Row < rhs->Row : lhs->Col < rhs->Col; }); for (int i = 0; i < tab_links[tab].size(); i++) { if (i >= spells[tab].size()) { break; } int lvl = tab_links[tab][i] - '0'; if (lvl == 0) continue; orders[tab].push_back({(uint32)tab, spells[tab][i]->Row, spells[tab][i]->Col, (uint32)lvl}); } } // sort by talent tab size std::sort(orders.begin(), orders.end(), [&](auto &lhs, auto &rhs) { return lhs.size() > rhs.size(); }); for (auto &order : orders) { res.insert(res.end(), order.begin(), order.end()); } return res; }