diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 874429e4..876b1b99 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -1273,7 +1273,7 @@ AiPlayerbot.ToxicLinksRepliesChance = 30 # Chance to reply to thunderfury with thunderfury (0-100) AiPlayerbot.ThunderfuryRepliesChance = 40 # Bots will chat in guild about certain events (int) (0-100) -AiPlayerbot.GuildRepliesRate = 100 # Reply someone saying something. +AiPlayerbot.GuildRepliesRate = 100 # Bots will chat in guild about certain events AIPlayerbot.GuildFeedback = 1 # Bots without a master will say their lines diff --git a/src/BroadcastHelper.cpp b/src/BroadcastHelper.cpp index d17bf561..19cd98d9 100644 --- a/src/BroadcastHelper.cpp +++ b/src/BroadcastHelper.cpp @@ -3,6 +3,7 @@ #include "BroadcastHelper.h" #include "ServerFacade.h" #include "Channel.h" +#include "AiFactory.h" BroadcastHelper::BroadcastHelper() {} @@ -662,7 +663,7 @@ bool BroadcastHelper::BroadcastSuggestInstance(PlayerbotAI* ai, std::vectorbroadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestInstance) { std::map placeholders; - placeholders["%my_role"] = ai->GetChatHelper()->FormatClass(bot->GetSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); std::ostringstream itemout; //itemout << "|c00b000b0" << allowedInstances[urand(0, allowedInstances.size() - 1)] << "|r"; @@ -693,7 +694,7 @@ bool BroadcastHelper::BroadcastSuggestQuest(PlayerbotAI* ai, std::vector Quest const* quest = sObjectMgr->GetQuestTemplate(quests[index]); std::map placeholders; - placeholders["%my_role"] = ai->GetChatHelper()->FormatClass(bot->GetSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); placeholders["%quest_link"] = ai->GetChatHelper()->FormatQuest(quest); placeholders["%quest_level"] = std::to_string(quest->GetQuestLevel()); placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass()); @@ -716,7 +717,7 @@ bool BroadcastHelper::BroadcastSuggestGrindMaterials(PlayerbotAI* ai, std::strin { std::map placeholders; - placeholders["%my_role"] = ai->GetChatHelper()->FormatClass(bot->GetSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); placeholders["%category"] = item; placeholders["%my_class"] = ai->GetChatHelper()->FormatClass(bot->getClass()); @@ -739,7 +740,7 @@ bool BroadcastHelper::BroadcastSuggestGrindReputation(PlayerbotAI* ai, std::vect { std::map placeholders; - placeholders["%my_role"] = ai->GetChatHelper()->FormatClass(bot->GetSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); placeholders["%rep_level"] = levels[urand(0, 2)]; std::ostringstream rnd; rnd << urand(1, 5) << "K"; placeholders["%rndK"] = rnd.str(); @@ -793,7 +794,7 @@ bool BroadcastHelper::BroadcastSuggestSomething(PlayerbotAI* ai, Player* bot) if (urand(1, sPlayerbotAIConfig->broadcastChanceMaxValue) <= sPlayerbotAIConfig->broadcastChanceSuggestSomething) { std::map placeholders; - placeholders["%my_role"] = ai->GetChatHelper()->FormatClass(bot->GetSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); AreaTableEntry const* current_area = ai->GetCurrentArea(); AreaTableEntry const* current_zone = ai->GetCurrentZone(); @@ -824,7 +825,7 @@ bool BroadcastHelper::BroadcastSuggestSomethingToxic(PlayerbotAI* ai, Player* bo placeholders["%random_inventory_item_link"] = botItems.size() > 0 ? ai->GetChatHelper()->FormatItem(botItems[rand() % botItems.size()]->GetTemplate()) : BOT_TEXT1("string_empty_link"); - placeholders["%my_role"] = ai->GetChatHelper()->FormatClass(bot->GetSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); AreaTableEntry const* current_area = ai->GetCurrentArea(); AreaTableEntry const* current_zone = ai->GetCurrentZone(); placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area"); @@ -881,7 +882,7 @@ bool BroadcastHelper::BroadcastSuggestToxicLinks(PlayerbotAI* ai, Player* bot) placeholders["%random_taken_quest_or_item_link"] = placeholders["%random_inventory_item_link"]; } - placeholders["%my_role"] = ai->GetChatHelper()->FormatClass(bot->GetSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); AreaTableEntry const* current_area = ai->GetCurrentArea(); AreaTableEntry const* current_zone = ai->GetCurrentZone(); placeholders["%area_name"] = current_area ? ai->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area"); @@ -916,4 +917,4 @@ bool BroadcastHelper::BroadcastSuggestThunderfury(PlayerbotAI* ai, Player* bot) } return false; -} \ No newline at end of file +} diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 83971ab5..cf135e2c 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -345,7 +345,7 @@ void PlayerbotAI::UpdateAIInternal([[maybe_unused]] uint32 elapsed, bool minimal while (!chatReplies.empty()) { ChatQueuedReply& holder = chatReplies.front(); - time_t checkTime = holder.m_time; + time_t& checkTime = holder.m_time; if (checkTime && time(0) < checkTime) { delayedResponses.push_back(std::move(holder)); @@ -940,6 +940,7 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) p >> guid1 >> unused; if (guid1.IsEmpty() || p.size() > p.DEFAULT_SIZE) return; + if (p.GetOpcode() == SMSG_GM_MESSAGECHAT) { p >> textLen; @@ -960,7 +961,7 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) p >> textLen >> message >> chatTag; break; default: - break; + return; } // do not reply to self but always try to reply to real player @@ -970,7 +971,7 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) bool isPaused = time(0) < lastChat; bool shouldReply = false; bool isFromFreeBot = false; - if (!sCharacterCache->GetCharacterNameByGuid(guid1, name)) {/*sould return or ?*/} + sCharacterCache->GetCharacterNameByGuid(guid1, name); uint32 accountId = sCharacterCache->GetCharacterAccountIdByGuid(guid1); isFromFreeBot = sPlayerbotAIConfig->IsInRandomAccountList(accountId); bool isMentioned = message.find(bot->GetName()) != std::string::npos; @@ -2194,19 +2195,16 @@ bool PlayerbotAI::SayToChannel(const std::string& msg, const ChatChannelId& chan return false; AreaTableEntry const* current_zone = GetCurrentZone(); - AreaTableEntry const* current_area = GetCurrentArea(); - if (!current_zone || !current_area) + if (!current_zone) return false; const auto current_str_zone = GetLocalizedAreaName(current_zone); - const auto current_str_area = GetLocalizedAreaName(current_area); - for (auto const& [key, channel] : cMgr->GetChannels()) { //check for current zone if (channel && channel->GetChannelId() == chanId) { - const auto does_contains = channel->GetName().find(current_str_zone) != std::string::npos || channel->GetName().find(current_str_area) != std::string::npos; + const auto does_contains = channel->GetName().find(current_str_zone) != std::string::npos; if (chanId != ChatChannelId::LOOKING_FOR_GROUP && chanId != ChatChannelId::WORLD_DEFENSE && !does_contains) { continue; diff --git a/src/PlayerbotMgr.cpp b/src/PlayerbotMgr.cpp index 0bf0d7ff..cb32d18e 100644 --- a/src/PlayerbotMgr.cpp +++ b/src/PlayerbotMgr.cpp @@ -19,6 +19,7 @@ #include "SharedDefines.h" #include "WorldSession.h" #include "ChannelMgr.h" +#include "BroadcastHelper.h" #include #include #include @@ -523,37 +524,54 @@ void PlayerbotHolder::OnBotLogin(Player* const bot) pkt << ""; // Pass bot->GetSession()->HandleJoinChannel(pkt); } + // join standard channels - AreaTableEntry const* current_zone = sAreaTableStore.LookupEntry(bot->GetAreaId()); + uint8 locale = BroadcastHelper::GetLocale(); + AreaTableEntry const* current_zone = GET_PLAYERBOT_AI(bot)->GetCurrentZone(); ChannelMgr* cMgr = ChannelMgr::forTeam(bot->GetTeamId()); + std::string current_zone_name = current_zone ? GET_PLAYERBOT_AI(bot)->GetLocalizedAreaName(current_zone) : ""; if (current_zone && cMgr) { - const auto current_str_zone = botAI->GetLocalizedAreaName(current_zone); for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i) { ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i); if (!channel) continue; - bool isLfg = (channel->flags & CHANNEL_DBC_FLAG_LFG) != 0; - - // skip non built-in channels or global channel without zone name in pattern - if (!isLfg && (!channel || (channel->flags & 4) == 4)) - continue; - - // new channel Channel* new_channel = nullptr; - if (isLfg) + switch (channel->ChannelID) { - std::string lfgChannelName = channel->pattern[sWorld->GetDefaultDbcLocale()]; - new_channel = cMgr->GetJoinChannel("LookingForGroup", channel->ChannelID); - } - else - { - char new_channel_name_buf[100]; - snprintf(new_channel_name_buf, 100, channel->pattern[sWorld->GetDefaultDbcLocale()], current_str_zone.c_str()); - new_channel = cMgr->GetJoinChannel(new_channel_name_buf, channel->ChannelID); + case ChatChannelId::GENERAL: + case ChatChannelId::LOCAL_DEFENSE: + { + char new_channel_name_buf[100]; + snprintf(new_channel_name_buf, 100, channel->pattern[locale], current_zone_name.c_str()); + new_channel = cMgr->GetJoinChannel(new_channel_name_buf, channel->ChannelID); + break; + } + case ChatChannelId::TRADE: + case ChatChannelId::GUILD_RECRUITMENT: + { + char new_channel_name_buf[100]; + //3459 is ID for a zone named "City" (only exists for the sake of using its name) + //Currently in magons TBC, if you switch zones, then you join "Trade - " and "GuildRecruitment - " + //which is a core bug, should be "Trade - City" and "GuildRecruitment - City" in both 1.12 and TBC + //but if you (actual player) logout in a city and log back in - you join "City" versions + snprintf(new_channel_name_buf, 100, channel->pattern[locale], GET_PLAYERBOT_AI(bot)->GetLocalizedAreaName(GetAreaEntryByAreaID(3459)).c_str()); + new_channel = cMgr->GetJoinChannel(new_channel_name_buf, channel->ChannelID); + break; + } + case ChatChannelId::LOOKING_FOR_GROUP: + case ChatChannelId::WORLD_DEFENSE: + { + new_channel = cMgr->GetJoinChannel(channel->pattern[locale], channel->ChannelID); + break; + } + default: + break; } + if (new_channel) + new_channel->JoinChannel(bot, ""); } } } diff --git a/src/PlayerbotTextMgr.cpp b/src/PlayerbotTextMgr.cpp index 7041185c..872d412d 100644 --- a/src/PlayerbotTextMgr.cpp +++ b/src/PlayerbotTextMgr.cpp @@ -9,7 +9,8 @@ void PlayerbotTextMgr::replaceAll(std::string & str, const std::string & from, c if (from.empty()) return; size_t start_pos = 0; - while ((start_pos = str.find(from, start_pos)) != std::string::npos) { + 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' } diff --git a/src/strategy/actions/SayAction.cpp b/src/strategy/actions/SayAction.cpp index 6f731000..1676aa16 100644 --- a/src/strategy/actions/SayAction.cpp +++ b/src/strategy/actions/SayAction.cpp @@ -2,6 +2,7 @@ * 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 "AiFactory.h" #include "SayAction.h" #include "Event.h" #include "Playerbots.h" @@ -241,7 +242,7 @@ bool ChatReplyAction::HandleToxicLinksReply(Player* bot, ChatChannelSource chatC placeholders["%random_taken_quest_or_item_link"] = placeholders["%random_inventory_item_link"]; } - placeholders["%my_role"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatClass(bot->getClass()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); AreaTableEntry const* current_area = GET_PLAYERBOT_AI(bot)->GetCurrentArea(); AreaTableEntry const* current_zone = GET_PLAYERBOT_AI(bot)->GetCurrentZone(); placeholders["%area_name"] = current_area ? GET_PLAYERBOT_AI(bot)->GetLocalizedAreaName(current_area) : BOT_TEXT1("string_unknown_area"); @@ -303,7 +304,7 @@ bool ChatReplyAction::HandleWTBItemsReply(Player* bot, ChatChannelSource chatCha placeholders["%my_class"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatClass(bot->getClass()); placeholders["%my_race"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatRace(bot->getRace()); placeholders["%my_level"] = std::to_string(bot->GetLevel()); - placeholders["%my_role"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatClass(bot->GetSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); placeholders["%formatted_item_links"] = ""; for (auto matchingItemId : matchingItemIds) @@ -396,7 +397,7 @@ bool ChatReplyAction::HandleLFGQuestsReply(Player* bot, ChatChannelSource chatCh placeholders["%my_class"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatClass(bot->getClass()); placeholders["%my_race"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatRace(bot->getRace()); placeholders["%my_level"] = std::to_string(bot->GetLevel()); - placeholders["%my_role"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatClass(bot, bot->GetActiveSpec()); + placeholders["%my_role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot)); placeholders["%quest_links"] = ""; for (auto matchingQuestId : matchingQuestIds) {