/* * 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 "PlayerbotTextMgr.h" #include "Playerbots.h" #include "WorldSessionMgr.h" void PlayerbotTextMgr::replaceAll(std::string& str, const std::string& from, const std::string& to) { if (from.empty()) return; size_t start_pos = 0; while ((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' } } void PlayerbotTextMgr::LoadBotTexts() { LOG_INFO("playerbots", "Loading playerbots texts..."); uint32 count = 0; if (PreparedQueryResult result = PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TEXT))) { do { std::map text; Field* fields = result->Fetch(); std::string name = fields[0].Get(); text[0] = fields[1].Get(); uint8 sayType = fields[2].Get(); uint8 replyType = fields[3].Get(); for (uint8 i = 1; i < MAX_LOCALES; ++i) { text[i] = fields[i + 3].Get(); } botTexts[name].push_back(BotTextEntry(name, text, sayType, replyType)); ++count; } while (result->NextRow()); } LOG_INFO("playerbots", "{} playerbots texts loaded", count); } void PlayerbotTextMgr::LoadBotTextChance() { if (botTextChance.empty()) { QueryResult results = PlayerbotsDatabase.Query("SELECT name, probability FROM ai_playerbot_texts_chance"); if (results) { do { Field* fields = results->Fetch(); std::string name = fields[0].Get(); uint32 probability = fields[1].Get(); botTextChance[name] = probability; } while (results->NextRow()); } } } // general texts std::string PlayerbotTextMgr::GetBotText(std::string name) { if (botTexts.empty()) { LOG_ERROR("playerbots", "Can't get bot text {}! No bots texts loaded!", name); return ""; } if (botTexts[name].empty()) { LOG_ERROR("playerbots", "Can't get bot text {}! No bots texts for this name!", name); return ""; } std::vector& list = botTexts[name]; BotTextEntry textEntry = list[urand(0, list.size() - 1)]; return !textEntry.m_text[GetLocalePriority()].empty() ? textEntry.m_text[GetLocalePriority()] : textEntry.m_text[0]; } std::string PlayerbotTextMgr::GetBotText(std::string name, std::map placeholders) { std::string botText = GetBotText(name); if (botText.empty()) return ""; for (std::map::iterator i = placeholders.begin(); i != placeholders.end(); ++i) replaceAll(botText, i->first, i->second); return botText; } // chat replies std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::map placeholders) { if (botTexts.empty()) { LOG_ERROR("playerbots", "Can't get bot text reply {}! No bots texts loaded!", replyType); return ""; } if (botTexts["reply"].empty()) { LOG_ERROR("playerbots", "Can't get bot text reply {}! No bots texts replies!", replyType); return ""; } std::vector& list = botTexts["reply"]; std::vector proper_list; for (auto text : list) { if (text.m_replyType == replyType) proper_list.push_back(text); } if (proper_list.empty()) return ""; BotTextEntry textEntry = proper_list[urand(0, proper_list.size() - 1)]; std::string botText = !textEntry.m_text[GetLocalePriority()].empty() ? textEntry.m_text[GetLocalePriority()] : textEntry.m_text[0]; for (auto& placeholder : placeholders) replaceAll(botText, placeholder.first, placeholder.second); return botText; } std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::string name) { std::map placeholders; placeholders["%s"] = name; return GetBotText(replyType, placeholders); } // probabilities bool PlayerbotTextMgr::rollTextChance(std::string name) { if (!botTextChance[name]) return true; return urand(0, 100) < botTextChance[name]; } bool PlayerbotTextMgr::GetBotText(std::string name, std::string& text) { if (!rollTextChance(name)) return false; text = GetBotText(name); return !text.empty(); } bool PlayerbotTextMgr::GetBotText(std::string name, std::string& text, std::map placeholders) { if (!rollTextChance(name)) return false; text = GetBotText(name, placeholders); return !text.empty(); } void PlayerbotTextMgr::AddLocalePriority(uint32 locale) { if (!locale) return; botTextLocalePriority[locale]++; } uint32 PlayerbotTextMgr::GetLocalePriority() { uint32 topLocale = 0; // if no real players online, reset top locale if (!sWorldSessionMgr->GetActiveSessionCount()) { ResetLocalePriority(); return 0; } for (uint8 i = 0; i < MAX_LOCALES; ++i) { if (botTextLocalePriority[i] > topLocale) topLocale = i; } return topLocale; } void PlayerbotTextMgr::ResetLocalePriority() { for (uint8 i = 0; i < MAX_LOCALES; ++i) { botTextLocalePriority[i] = 0; } }