mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-17 10:45:43 +00:00
Chat refactor quests and generic + suggest
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
#include "Event.h"
|
||||
#include "PlayerbotFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
bool AutoLearnSpellAction::Execute(Event event)
|
||||
{
|
||||
@@ -30,18 +30,12 @@ bool AutoLearnSpellAction::Execute(Event event)
|
||||
|
||||
void AutoLearnSpellAction::LearnSpells(std::ostringstream* out)
|
||||
{
|
||||
BroadcastHelper::BroadcastLevelup(botAI, bot);
|
||||
if (sPlayerbotAIConfig->autoLearnTrainerSpells)
|
||||
LearnTrainerSpells(out);
|
||||
|
||||
if (sPlayerbotAIConfig->autoLearnQuestSpells)
|
||||
LearnQuestSpells(out);
|
||||
|
||||
if (sPlayerbotAIConfig->randomBotGuildTalk)
|
||||
{
|
||||
std::map<std::string, std::string> args;
|
||||
args["%my_level"] = std::to_string(bot->GetLevel());
|
||||
botAI->SayToGuild(BOT_TEXT2("broadcast_levelup_generic", args));
|
||||
}
|
||||
}
|
||||
|
||||
void AutoLearnSpellAction::LearnTrainerSpells(std::ostringstream* out)
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "GuildPackets.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
Player* GuidManageAction::GetPlayer(Event event)
|
||||
{
|
||||
@@ -167,6 +168,7 @@ bool GuildManageNearbyAction::Execute(Event event)
|
||||
{
|
||||
if (!urand(0, 10))
|
||||
{
|
||||
BroadcastHelper::BroadcastGuildMemberPromotion(botAI, bot, player);
|
||||
botAI->DoSpecificAction("guild promote", Event("guild management", guid), true);
|
||||
|
||||
continue;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "GuildMgr.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
bool InviteToGroupAction::Execute(Event event)
|
||||
{
|
||||
@@ -76,6 +77,26 @@ bool InviteNearbyToGroupAction::Execute(Event event)
|
||||
if (sServerFacade->GetDistance2d(bot, player) > sPlayerbotAIConfig->sightDistance)
|
||||
continue;
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
|
||||
if (!botAI->HasActivePlayerMaster())
|
||||
{
|
||||
if (guild && bot->GetGuildId() == player->GetGuildId())
|
||||
{
|
||||
BroadcastHelper::BroadcastGuildGroupOrRaidInvite(botAI, bot, player, group);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%player"] = player->GetName();
|
||||
|
||||
if (group && group->isRaidGroup())
|
||||
bot->Say(BOT_TEXT2("join_raid", placeholders), (bot->GetTeamId() == TEAM_ALLIANCE ? LANG_COMMON : LANG_ORCISH));
|
||||
else
|
||||
bot->Say(BOT_TEXT2("join_group", placeholders), (bot->GetTeamId() == TEAM_ALLIANCE ? LANG_COMMON : LANG_ORCISH));
|
||||
}
|
||||
}
|
||||
|
||||
return Invite(player);
|
||||
}
|
||||
|
||||
@@ -125,6 +146,8 @@ std::vector<Player*> InviteGuildToGroupAction::getGuildMembers()
|
||||
|
||||
bool InviteGuildToGroupAction::Execute(Event event)
|
||||
{
|
||||
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
|
||||
|
||||
for (auto& member : getGuildMembers())
|
||||
{
|
||||
Player* player = member;
|
||||
@@ -165,6 +188,8 @@ bool InviteGuildToGroupAction::Execute(Event event)
|
||||
if (!botAI && sServerFacade->GetDistance2d(bot, player) > sPlayerbotAIConfig->sightDistance)
|
||||
continue;
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
BroadcastHelper::BroadcastGuildGroupOrRaidInvite(botAI, bot, player, group);
|
||||
return Invite(player);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
bool LootAction::Execute(Event event)
|
||||
{
|
||||
@@ -417,19 +418,7 @@ bool StoreLootAction::Execute(Event event)
|
||||
if (proto->Quality >= ITEM_QUALITY_RARE && !urand(0, 1) && botAI->HasStrategy("emote", BOT_STATE_NON_COMBAT))
|
||||
botAI->PlayEmote(TEXT_EMOTE_CHEER);
|
||||
|
||||
if (sPlayerbotAIConfig->randomBotGuildTalk && urand(0, 10) && proto->Quality >= ITEM_QUALITY_RARE)
|
||||
{
|
||||
std::map<std::string, std::string> args;
|
||||
args["%item"] = chat->FormatItem(proto);
|
||||
botAI->SayToGuild(BOT_TEXT2("loot_command", args));
|
||||
}
|
||||
|
||||
// std::ostringstream out;
|
||||
// out << "Looting " << chat->FormatItem(proto);
|
||||
// botAI->TellMasterNoFacing(out.str());
|
||||
|
||||
//ItemUsage usage = AI_VALUE2(ItemUsage, "item usage", proto->ItemId);
|
||||
//LOG_ERROR("playerbots", "Bot {} is looting {} {} for usage {}.", bot->GetName().c_str(), itemcount, proto->Name1.c_str(), usage);
|
||||
BroadcastHelper::BroadcastLootingItem(botAI, bot, proto);
|
||||
}
|
||||
|
||||
AI_VALUE(LootObjectStack*, "available loot")->Remove(guid);
|
||||
|
||||
@@ -10,64 +10,6 @@
|
||||
|
||||
bool QueryItemUsageAction::Execute(Event event)
|
||||
{
|
||||
if (!GetMaster() && !sPlayerbotAIConfig->randomBotSayWithoutMaster)
|
||||
return false;
|
||||
|
||||
if (!sPlayerbotAIConfig->sayWhenCollectingItems)
|
||||
return false;
|
||||
|
||||
WorldPacket& data = event.getPacket();
|
||||
if (!data.empty())
|
||||
{
|
||||
data.rpos(0);
|
||||
|
||||
ObjectGuid guid;
|
||||
data >> guid;
|
||||
if (guid != bot->GetGUID())
|
||||
return false;
|
||||
|
||||
uint32 received;
|
||||
uint32 created;
|
||||
uint32 isShowChatMessage;
|
||||
uint32 notUsed;
|
||||
uint32 itemId;
|
||||
uint32 suffixFactor;
|
||||
uint32 itemRandomPropertyId;
|
||||
uint32 count;
|
||||
uint32 invCount;
|
||||
uint8 bagSlot;
|
||||
|
||||
data >> received; // 0=looted, 1=from npc
|
||||
data >> created; // 0=received, 1=created
|
||||
data >> isShowChatMessage; // IsShowChatMessage
|
||||
data >> bagSlot; // item slot, but when added to stack: 0xFFFFFFFF
|
||||
|
||||
data >> notUsed;
|
||||
data >> itemId;
|
||||
data >> suffixFactor;
|
||||
data >> itemRandomPropertyId;
|
||||
data >> count;
|
||||
// data >> invCount; // [-ZERO] count of items in inventory
|
||||
|
||||
ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!item)
|
||||
return false;
|
||||
|
||||
bot->Say(QueryItem(item, count, GetCount(item)), LANG_UNIVERSAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string const text = event.getParam();
|
||||
ItemIds items = chat->parseItems(text);
|
||||
for (uint32 itemId : items)
|
||||
{
|
||||
ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
botAI->TellMaster(QueryItem(item, 0, GetCount(item)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "Playerbots.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
bool QuestAction::Execute(Event event)
|
||||
{
|
||||
@@ -226,6 +227,7 @@ bool QuestAction::AcceptQuest(Quest const* quest, ObjectGuid questGiver)
|
||||
|
||||
if (bot->GetQuestStatus(questId) != QUEST_STATUS_NONE && bot->GetQuestStatus(questId) != QUEST_STATUS_REWARDED)
|
||||
{
|
||||
BroadcastHelper::BroadcastQuestAccepted(botAI, bot, quest);
|
||||
out << "Accepted " << chat->FormatQuest(quest);
|
||||
botAI->TellMaster(out);
|
||||
return true;
|
||||
@@ -253,13 +255,17 @@ bool QuestUpdateCompleteAction::Execute(Event event)
|
||||
Quest const* qInfo = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (qInfo)
|
||||
{
|
||||
const std::string text_quest = ChatHelper::FormatQuest(qInfo);
|
||||
std::map<std::string, std::string> placeholders;
|
||||
const auto format = ChatHelper::FormatQuest(qInfo);
|
||||
placeholders["%quest_link"] = format;
|
||||
|
||||
if (botAI->HasStrategy("debug quest", BotState::BOT_STATE_NON_COMBAT) || botAI->HasStrategy("debug rpg", BotState::BOT_STATE_COMBAT))
|
||||
{
|
||||
LOG_INFO("playerbots", "{} => Quest [ {} ] completed", bot->GetName(), qInfo->GetTitle());
|
||||
bot->Say("Quest [ " + text_quest + " ] completed", LANG_UNIVERSAL);
|
||||
bot->Say("Quest [ " + format + " ] completed", LANG_UNIVERSAL);
|
||||
}
|
||||
botAI->TellMasterNoFacing("Quest completed " + text_quest);
|
||||
botAI->TellMasterNoFacing("Quest completed " + format);
|
||||
BroadcastHelper::BroadcastQuestUpdateComplete(botAI, bot, qInfo);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -276,9 +282,38 @@ bool QuestUpdateAddKillAction::Execute(Event event)
|
||||
uint32 entry, questId, available, required;
|
||||
p >> questId >> entry >> available >> required;
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Update progression kill questid {" << std::to_string(questId) << "} {" << std::to_string(available) << "} / {" << std::to_string(required) << "}";
|
||||
botAI->TellMasterNoFacing(ss.str());
|
||||
const Quest* qInfo = sObjectMgr->GetQuestTemplate(questId);
|
||||
if (qInfo && (entry & 0x80000000))
|
||||
{
|
||||
entry &= 0x7FFFFFFF;
|
||||
const GameObjectTemplate* info = sObjectMgr->GetGameObjectTemplate(entry);
|
||||
if (info)
|
||||
BroadcastHelper::BroadcastQuestUpdateAddKill(botAI, bot, qInfo, available, required, info->name);
|
||||
}
|
||||
else if (qInfo)
|
||||
{
|
||||
CreatureTemplate const* info = sObjectMgr->GetCreatureTemplate(entry);
|
||||
if (info)
|
||||
{
|
||||
BroadcastHelper::BroadcastQuestUpdateAddKill(botAI, bot, qInfo, available, required, info->Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%quest_id"] = questId;
|
||||
placeholders["%available"] = available;
|
||||
placeholders["%required"] = required;
|
||||
|
||||
if (botAI->HasStrategy("debug quest", BotState::BOT_STATE_COMBAT) || botAI->HasStrategy("debug quest", BotState::BOT_STATE_NON_COMBAT))
|
||||
{
|
||||
LOG_INFO("playerbots", "{} => {}", bot->GetName(), BOT_TEXT2("%available/%required for questId: %quest_id", placeholders));
|
||||
botAI->Say(BOT_TEXT2("%available/%required for questId: %quest_id", placeholders));
|
||||
}
|
||||
|
||||
botAI->TellMasterNoFacing(BOT_TEXT2("%available/%required for questId: %quest_id", placeholders));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -292,11 +327,29 @@ bool QuestUpdateAddItemAction::Execute(Event event)
|
||||
|
||||
Player* requester = event.getOwner() ? event.getOwner() : GetMaster();
|
||||
auto const* itemPrototype = sObjectMgr->GetItemTemplate(itemId);
|
||||
if (itemPrototype)
|
||||
{
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%item_link"] = botAI->GetChatHelper()->FormatItem(itemPrototype);
|
||||
uint32 availableItemsCount = botAI->GetInventoryItemsCountWithId(itemId);
|
||||
placeholders["%quest_obj_available"] = std::to_string(availableItemsCount);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "Update progression itemid {" << std::to_string(itemId) << "} count: {" << std::to_string(count) << "}";
|
||||
botAI->TellMasterNoFacing(ss.str());
|
||||
for (const auto& pair : botAI->GetCurrentQuestsRequiringItemId(itemId))
|
||||
{
|
||||
placeholders["%quest_link"] = chat->FormatQuest(pair.first);
|
||||
uint32 requiredItemsCount = pair.second;
|
||||
placeholders["%quest_obj_required"] = std::to_string(requiredItemsCount);
|
||||
if (botAI->HasStrategy("debug quest", BotState::BOT_STATE_COMBAT) || botAI->HasStrategy("debug quest", BotState::BOT_STATE_NON_COMBAT))
|
||||
{
|
||||
const auto text = BOT_TEXT2("%quest_link - %item_link %quest_obj_available/%quest_obj_required", placeholders);
|
||||
botAI->Say(text);
|
||||
LOG_INFO("playerbots", "{} => {}", bot->GetName(), text);
|
||||
}
|
||||
|
||||
BroadcastHelper::BroadcastQuestUpdateAddItem(botAI, bot, pair.first, availableItemsCount, requiredItemsCount, itemPrototype);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -320,7 +373,10 @@ bool QuestUpdateFailedTimerAction::Execute(Event event)
|
||||
|
||||
if (qInfo)
|
||||
{
|
||||
botAI->TellMaster("Failed timer for " + botAI->GetChatHelper()->FormatQuest(qInfo) +", abandoning");
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%quest_link"] = botAI->GetChatHelper()->FormatQuest(qInfo);
|
||||
botAI->TellMaster(BOT_TEXT2("Failed timer for %quest_link, abandoning", placeholders));
|
||||
BroadcastHelper::BroadcastQuestUpdateFailedTimer(botAI, bot, qInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -122,7 +122,7 @@ bool SayAction::isUseful()
|
||||
return (time(nullptr) - lastSaid) > 30;
|
||||
}
|
||||
|
||||
void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32 guid2, std::string msg, std::string chanName, std::string name)
|
||||
void ChatReplyAction::ChatReplyDo(Player* bot, uint32& type, uint32& guid1, uint32& guid2, std::string& msg, std::string& chanName, std::string& name)
|
||||
{
|
||||
ChatReplyType replyType = REPLY_NOT_UNDERSTAND; // default not understand
|
||||
std::string respondsText = "";
|
||||
@@ -165,7 +165,7 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
||||
}
|
||||
|
||||
//toxic links
|
||||
if (msg.starts_with("gnomes")
|
||||
if (msg.starts_with(sPlayerbotAIConfig->toxicLinksPrefix)
|
||||
&& (GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllItemIds(msg).size() > 0 || GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllQuestIds(msg).size() > 0))
|
||||
{
|
||||
HandleToxicLinksReply(bot, chatChannelSource, msg, name);
|
||||
@@ -179,10 +179,11 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
||||
return;
|
||||
}
|
||||
|
||||
SendGeneralResponse(bot, chatChannelSource, GenerateReplyMessage(bot, msg, guid1, name), name);
|
||||
auto messageRepy = GenerateReplyMessage(bot, msg, guid1, name);
|
||||
SendGeneralResponse(bot, chatChannelSource, messageRepy, name);
|
||||
}
|
||||
|
||||
bool ChatReplyAction::HandleThunderfuryReply(Player* bot, ChatChannelSource chatChannelSource, std::string msg, std::string name)
|
||||
bool ChatReplyAction::HandleThunderfuryReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name)
|
||||
{
|
||||
std::map<std::string, std::string> placeholders;
|
||||
const auto thunderfury = sObjectMgr->GetItemTemplate(19019);
|
||||
@@ -208,17 +209,164 @@ bool ChatReplyAction::HandleThunderfuryReply(Player* bot, ChatChannelSource chat
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatReplyAction::HandleToxicLinksReply(Player* bot, ChatChannelSource chatChannelSource, std::string msg, std::string name)
|
||||
bool ChatReplyAction::HandleToxicLinksReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name)
|
||||
{
|
||||
//quests
|
||||
std::vector<uint32> incompleteQuests;
|
||||
for (uint16 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
|
||||
{
|
||||
uint32 questId = bot->GetQuestSlotQuestId(slot);
|
||||
if (!questId)
|
||||
continue;
|
||||
|
||||
QuestStatus status = bot->GetQuestStatus(questId);
|
||||
if (status == QUEST_STATUS_INCOMPLETE || status == QUEST_STATUS_NONE)
|
||||
incompleteQuests.push_back(questId);
|
||||
}
|
||||
|
||||
//items
|
||||
std::vector<Item*> botItems = GET_PLAYERBOT_AI(bot)->GetInventoryAndEquippedItems();
|
||||
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%random_inventory_item_link"] = botItems.size() > 0 ? GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatItem(botItems[rand() % botItems.size()]->GetTemplate()) : BOT_TEXT1("string_empty_link");
|
||||
placeholders["%prefix"] = sPlayerbotAIConfig->toxicLinksPrefix;
|
||||
|
||||
if (incompleteQuests.size() > 0)
|
||||
{
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(incompleteQuests[rand() % incompleteQuests.size()]);
|
||||
placeholders["%random_taken_quest_or_item_link"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatQuest(quest);
|
||||
}
|
||||
else
|
||||
{
|
||||
placeholders["%random_taken_quest_or_item_link"] = placeholders["%random_inventory_item_link"];
|
||||
}
|
||||
|
||||
placeholders["%my_role"] = GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatClass(bot->getClass());
|
||||
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");
|
||||
placeholders["%zone_name"] = current_zone ? GET_PLAYERBOT_AI(bot)->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
|
||||
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());
|
||||
|
||||
switch (chatChannelSource)
|
||||
{
|
||||
case ChatChannelSource::SRC_WORLD:
|
||||
{
|
||||
GET_PLAYERBOT_AI(bot)->SayToWorld(BOT_TEXT2("suggest_toxic_links", placeholders));
|
||||
break;
|
||||
}
|
||||
case ChatChannelSource::SRC_GENERAL:
|
||||
{
|
||||
GET_PLAYERBOT_AI(bot)->SayToChannel(BOT_TEXT2("suggest_toxic_links", placeholders), ChatChannelId::GENERAL);
|
||||
break;
|
||||
}
|
||||
case ChatChannelSource::SRC_GUILD:
|
||||
{
|
||||
GET_PLAYERBOT_AI(bot)->SayToGuild(BOT_TEXT2("suggest_toxic_links", placeholders));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<time_t>("last said", "chat")->Set(time(0) + urand(5, 60));
|
||||
|
||||
return true;
|
||||
}
|
||||
bool ChatReplyAction::HandleWTBItemsReply(Player* bot, ChatChannelSource chatChannelSource, std::string msg, std::string name)
|
||||
bool ChatReplyAction::HandleWTBItemsReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name)
|
||||
{
|
||||
GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<time_t>("last said", "chat")->Set(time(0) + urand(5, 60));
|
||||
auto messageItemIds = GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllItemIds(msg);
|
||||
|
||||
if (messageItemIds.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<uint32> matchingItemIds;
|
||||
|
||||
for (auto messageItemId : messageItemIds)
|
||||
{
|
||||
if (GET_PLAYERBOT_AI(bot)->HasItemInInventory(messageItemId))
|
||||
{
|
||||
matchingItemIds.insert(messageItemId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!matchingItemIds.empty())
|
||||
{
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%other_name"] = name;
|
||||
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");
|
||||
placeholders["%zone_name"] = current_zone ? GET_PLAYERBOT_AI(bot)->GetLocalizedAreaName(current_zone) : BOT_TEXT1("string_unknown_area");
|
||||
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["%formatted_item_links"] = "";
|
||||
|
||||
for (auto matchingItemId : matchingItemIds)
|
||||
{
|
||||
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(matchingItemId);
|
||||
placeholders["%formatted_item_links"] += GET_PLAYERBOT_AI(bot)->GetChatHelper()->FormatItem(proto, GET_PLAYERBOT_AI(bot)->GetInventoryItemsCountWithId(matchingItemId));
|
||||
placeholders["%formatted_item_links"] += " ";
|
||||
}
|
||||
|
||||
switch (chatChannelSource)
|
||||
{
|
||||
case ChatChannelSource::SRC_WORLD:
|
||||
{
|
||||
//may reply to the same channel or whisper
|
||||
if (urand(0, 1))
|
||||
{
|
||||
std::string responseMessage = BOT_TEXT2("response_wtb_items_channel", placeholders);
|
||||
GET_PLAYERBOT_AI(bot)->SayToWorld(responseMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string responseMessage = BOT_TEXT2("response_wtb_items_whisper", placeholders);
|
||||
GET_PLAYERBOT_AI(bot)->Whisper(responseMessage, name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ChatChannelSource::SRC_GENERAL:
|
||||
{
|
||||
//may reply to the same channel or whisper
|
||||
if (urand(0, 1))
|
||||
{
|
||||
std::string responseMessage = BOT_TEXT2("response_wtb_items_channel", placeholders);
|
||||
GET_PLAYERBOT_AI(bot)->SayToChannel(responseMessage, ChatChannelId::GENERAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string responseMessage = BOT_TEXT2("response_wtb_items_whisper", placeholders);
|
||||
GET_PLAYERBOT_AI(bot)->Whisper(responseMessage, name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ChatChannelSource::SRC_TRADE:
|
||||
{
|
||||
//may reply to the same channel or whisper
|
||||
if (urand(0, 1))
|
||||
{
|
||||
std::string responseMessage = BOT_TEXT2("response_wtb_items_channel", placeholders);
|
||||
GET_PLAYERBOT_AI(bot)->SayToChannel(responseMessage, ChatChannelId::TRADE);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string responseMessage = BOT_TEXT2("response_wtb_items_whisper", placeholders);
|
||||
GET_PLAYERBOT_AI(bot)->Whisper(responseMessage, name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<time_t>("last said", "chat")->Set(time(0) + urand(5, 60));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool ChatReplyAction::HandleLFGQuestsReply(Player* bot, ChatChannelSource chatChannelSource, std::string msg, std::string name)
|
||||
bool ChatReplyAction::HandleLFGQuestsReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name)
|
||||
{
|
||||
auto messageQuestIds = GET_PLAYERBOT_AI(bot)->GetChatHelper()->ExtractAllQuestIds(msg);
|
||||
|
||||
@@ -303,7 +451,7 @@ bool ChatReplyAction::HandleLFGQuestsReply(Player* bot, ChatChannelSource chatCh
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatReplyAction::SendGeneralResponse(Player* bot, ChatChannelSource chatChannelSource, std::string responseMessage, std::string name)
|
||||
bool ChatReplyAction::SendGeneralResponse(Player* bot, ChatChannelSource chatChannelSource, std::string& responseMessage, std::string& name)
|
||||
{
|
||||
// send responds
|
||||
switch (chatChannelSource)
|
||||
@@ -341,13 +489,11 @@ bool ChatReplyAction::SendGeneralResponse(Player* bot, ChatChannelSource chatCha
|
||||
case ChatChannelSource::SRC_LOOKING_FOR_GROUP:
|
||||
{
|
||||
//do not reply to the chat
|
||||
//may whisper
|
||||
break;
|
||||
}
|
||||
case ChatChannelSource::SRC_GUILD_RECRUITMENT:
|
||||
{
|
||||
//do not reply to the chat
|
||||
//may whisper
|
||||
break;
|
||||
}
|
||||
case ChatChannelSource::SRC_WHISPER:
|
||||
@@ -378,7 +524,7 @@ bool ChatReplyAction::SendGeneralResponse(Player* bot, ChatChannelSource chatCha
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ChatReplyAction::GenerateReplyMessage(Player* bot, std::string incomingMessage, uint32 guid1, std::string name)
|
||||
std::string ChatReplyAction::GenerateReplyMessage(Player* bot, std::string& incomingMessage, uint32& guid1, std::string& name)
|
||||
{
|
||||
ChatReplyType replyType = REPLY_NOT_UNDERSTAND; // default not understand
|
||||
|
||||
|
||||
@@ -32,12 +32,12 @@ public:
|
||||
virtual bool Execute(Event event) { return true; }
|
||||
bool isUseful() { return true; }
|
||||
|
||||
static void ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32 guid2, std::string msg, std::string chanName, std::string name);
|
||||
static bool HandleThunderfuryReply(Player* bot, ChatChannelSource chatChannelSource, std::string msg, std::string name);
|
||||
static bool HandleToxicLinksReply(Player* bot, ChatChannelSource chatChannelSource, std::string msg, std::string name);
|
||||
static bool HandleWTBItemsReply(Player* bot, ChatChannelSource chatChannelSource, std::string msg, std::string name);
|
||||
static bool HandleLFGQuestsReply(Player* bot, ChatChannelSource chatChannelSource, std::string msg, std::string name);
|
||||
static bool SendGeneralResponse(Player* bot, ChatChannelSource chatChannelSource, std::string responseMessage, std::string name);
|
||||
static std::string GenerateReplyMessage(Player* bot, std::string incomingMessage, uint32 guid1, std::string name);
|
||||
static void ChatReplyDo(Player* bot, uint32& type, uint32& guid1, uint32& guid2, std::string& msg, std::string& chanName, std::string& name);
|
||||
static bool HandleThunderfuryReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name);
|
||||
static bool HandleToxicLinksReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name);
|
||||
static bool HandleWTBItemsReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name);
|
||||
static bool HandleLFGQuestsReply(Player* bot, ChatChannelSource chatChannelSource, std::string& msg, std::string& name);
|
||||
static bool SendGeneralResponse(Player* bot, ChatChannelSource chatChannelSource, std::string& responseMessage, std::string& name);
|
||||
static std::string GenerateReplyMessage(Player* bot, std::string& incomingMessage, uint32& guid1, std::string& name);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include "ChatHelper.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "Config.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
@@ -36,6 +36,8 @@ SuggestWhatToDoAction::SuggestWhatToDoAction(PlayerbotAI* botAI, std::string con
|
||||
suggestions.push_back(std::bind(&SuggestWhatToDoAction::grindReputation, this));
|
||||
suggestions.push_back(std::bind(&SuggestWhatToDoAction::something, this));
|
||||
suggestions.push_back(std::bind(&SuggestWhatToDoAction::grindMaterials, this));
|
||||
suggestions.push_back(std::bind(&SuggestWhatToDoAction::somethingToxic, this));
|
||||
suggestions.push_back(std::bind(&SuggestWhatToDoAction::toxicLinks, this));
|
||||
}
|
||||
|
||||
bool SuggestWhatToDoAction::isUseful()
|
||||
@@ -85,15 +87,7 @@ void SuggestWhatToDoAction::specificQuest()
|
||||
if (quests.empty())
|
||||
return;
|
||||
|
||||
uint32 index = rand() % quests.size();
|
||||
|
||||
Quest const* quest = sObjectMgr->GetQuestTemplate(quests[index]);
|
||||
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%role"] = chat->FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
||||
placeholders["%quest"] = chat->FormatQuest(quest);
|
||||
|
||||
spam(BOT_TEXT2("suggest_quest", placeholders), urand(0, 1) ? eTalkType::General : 0, !urand(0, 2), !urand(0, 3));
|
||||
BroadcastHelper::BroadcastSuggestQuest(botAI, quests, bot);
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::grindMaterials()
|
||||
@@ -187,123 +181,34 @@ void SuggestWhatToDoAction::grindReputation()
|
||||
levels.push_back("exalted");
|
||||
|
||||
std::vector<std::string> allowedFactions;
|
||||
for (const auto& i : factions)
|
||||
for (auto it : factions)
|
||||
{
|
||||
if (bot->GetLevel() >= i.second)
|
||||
allowedFactions.push_back(i.first);
|
||||
if ((int)bot->GetLevel() >= it.second) allowedFactions.push_back(it.first);
|
||||
}
|
||||
if (allowedFactions.empty())
|
||||
return;
|
||||
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%role"] = chat->FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
||||
placeholders["%level"] = levels[urand(0, 2)];
|
||||
if (allowedFactions.empty()) return;
|
||||
|
||||
std::ostringstream rnd;
|
||||
rnd << urand(1, 5) << "K";
|
||||
placeholders["%rndK"] = rnd.str();
|
||||
|
||||
std::ostringstream itemout;
|
||||
// itemout << "|c004040b0" << allowedFactions[urand(0, allowedFactions.size() - 1)] << "|r";
|
||||
itemout << allowedFactions[urand(0, allowedFactions.size() - 1)];
|
||||
placeholders["%faction"] = itemout.str();
|
||||
|
||||
spam(BOT_TEXT2("suggest_faction", placeholders), eTalkType::General, true);
|
||||
BroadcastHelper::BroadcastSuggestGrindReputation(botAI, levels, allowedFactions, bot);
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::something()
|
||||
{
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%role"] = chat->FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
||||
|
||||
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(bot->GetMap()->GetZoneId(bot->GetPhaseMask(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ()));
|
||||
if (!zone) return;
|
||||
|
||||
std::ostringstream out;
|
||||
// out << "|cffb04040" << entry->area_name[0] << "|r";
|
||||
out << zone->area_name[_dbc_locale];
|
||||
placeholders["%zone"] = out.str();
|
||||
|
||||
spam(BOT_TEXT2("suggest_something", placeholders), urand(0, 1) ? eTalkType::General : 0, !urand(0, 2), !urand(0, 3));
|
||||
BroadcastHelper::BroadcastSuggestSomething(botAI, bot);
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::spam(std::string msg, uint8 flags, bool worldChat, bool guild)
|
||||
void SuggestWhatToDoAction::somethingToxic()
|
||||
{
|
||||
if (msg.empty())
|
||||
return;
|
||||
BroadcastHelper::BroadcastSuggestSomethingToxic(botAI, bot);
|
||||
}
|
||||
|
||||
std::vector<std::string> channelNames;
|
||||
ChannelMgr* cMgr = ChannelMgr::forTeam(bot->GetTeamId());
|
||||
if (!cMgr)
|
||||
return;
|
||||
void SuggestWhatToDoAction::toxicLinks()
|
||||
{
|
||||
BroadcastHelper::BroadcastSuggestToxicLinks(botAI, bot);
|
||||
}
|
||||
|
||||
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(bot->GetMap()->GetZoneId(bot->GetPhaseMask(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ()));
|
||||
if (!zone) return;
|
||||
/*AreaTableEntry const* area = sAreaTableStore.LookupEntry(bot->GetMap()->GetAreaId(bot->GetPhaseMask(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ()));
|
||||
if (!area) return;*/
|
||||
|
||||
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
||||
{
|
||||
ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i);
|
||||
if (!channel) continue;
|
||||
|
||||
// combine full channel name
|
||||
char channelName[100];
|
||||
Channel* chn = nullptr;
|
||||
if (channel->ChannelID == 24 || (channel->flags & CHANNEL_DBC_FLAG_LFG) != 0)
|
||||
{
|
||||
std::string chanName = channel->pattern[_dbc_locale];
|
||||
chn = cMgr->GetChannel(chanName, bot);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(channelName, 100, channel->pattern[_dbc_locale], zone->area_name[_dbc_locale]);
|
||||
chn = cMgr->GetChannel(channelName, bot);
|
||||
}
|
||||
if (!chn)
|
||||
continue;
|
||||
|
||||
// skip world chat here
|
||||
if (chn->GetName() == "World")
|
||||
continue;
|
||||
|
||||
if (flags != 0 && chn->GetFlags() != flags)
|
||||
continue;
|
||||
|
||||
// skip local defense and universal defense
|
||||
if (chn->GetChannelId() == 22 || chn->GetChannelId() == 23)
|
||||
continue;
|
||||
|
||||
// no filter, pick several options
|
||||
if (flags == CHANNEL_FLAG_NONE)
|
||||
{
|
||||
channelNames.push_back(chn->GetName());
|
||||
}
|
||||
else
|
||||
{
|
||||
chn->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
||||
}
|
||||
|
||||
if (!channelNames.empty())
|
||||
{
|
||||
std::string randomName = channelNames[urand(0, channelNames.size() - 1)];
|
||||
if (Channel* chn = cMgr->GetChannel(randomName, bot))
|
||||
{
|
||||
chn->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (worldChat)
|
||||
{
|
||||
if (Channel* worldChannel = cMgr->GetChannel("World", bot))
|
||||
worldChannel->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (sPlayerbotAIConfig->randomBotGuildTalk)
|
||||
{
|
||||
botAI->SayToGuild(msg);
|
||||
}
|
||||
void SuggestWhatToDoAction::thunderfury()
|
||||
{
|
||||
BroadcastHelper::BroadcastSuggestThunderfury(botAI, bot);
|
||||
}
|
||||
|
||||
class FindTradeItemsVisitor : public IterateItemsVisitor
|
||||
@@ -394,22 +299,14 @@ bool SuggestDungeonAction::Execute(Event event)
|
||||
}
|
||||
|
||||
std::vector<std::string> allowedInstances;
|
||||
for (const auto& instance : instances)
|
||||
for (auto it : instances)
|
||||
{
|
||||
if (bot->GetLevel() >= instance.second)
|
||||
allowedInstances.push_back(instance.first);
|
||||
if (bot->GetLevel() >= it.second) allowedInstances.push_back(it.first);
|
||||
}
|
||||
|
||||
if (allowedInstances.empty()) return false;
|
||||
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%role"] = ChatHelper::FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
||||
|
||||
std::ostringstream itemout;
|
||||
//itemout << "|c00b000b0" << allowedInstances[urand(0, allowedInstances.size() - 1)] << "|r";
|
||||
itemout << allowedInstances[urand(0, allowedInstances.size() - 1)];
|
||||
placeholders["%instance"] = itemout.str();
|
||||
|
||||
spam(BOT_TEXT2("suggest_instance", placeholders), urand(0, 1) ? eTalkType::LookingForGroup : 0, !urand(0, 2), !urand(0, 3));
|
||||
BroadcastHelper::BroadcastSuggestInstance(botAI, allowedInstances, bot);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -469,11 +366,6 @@ bool SuggestTradeAction::Execute(Event event)
|
||||
if (!price)
|
||||
return false;
|
||||
|
||||
std::map<std::string, std::string> placeholders;
|
||||
placeholders["%item"] = chat->FormatItem(proto, count);
|
||||
placeholders["%gold"] = chat->formatMoney(price);
|
||||
|
||||
|
||||
spam(BOT_TEXT2("suggest_sell", placeholders), urand(0, 1) ? eTalkType::Trade : 0, !urand(0, 2), urand(0, 5));
|
||||
BroadcastHelper::BroadcastSuggestSell(botAI, proto, count, price, bot);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,10 @@ class SuggestWhatToDoAction : public InventoryAction
|
||||
void grindReputation();
|
||||
void grindMaterials();
|
||||
void something();
|
||||
void spam(std::string msg, uint8 flags = 0, bool worldChat = false, bool guild = false);
|
||||
|
||||
void toxicLinks();
|
||||
void somethingToxic();
|
||||
void thunderfury();
|
||||
|
||||
std::vector<uint32> GetIncompletedQuests();
|
||||
|
||||
private:
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "Playerbots.h"
|
||||
#include "QuestDef.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
bool TalkToQuestGiverAction::ProcessQuest(Quest const* quest, Object* questGiver)
|
||||
{
|
||||
@@ -96,14 +97,19 @@ bool TalkToQuestGiverAction::TurnInQuest(Quest const* quest, Object* questGiver,
|
||||
|
||||
void TalkToQuestGiverAction::RewardNoItem(Quest const* quest, Object* questGiver, std::ostringstream& out)
|
||||
{
|
||||
std::map<std::string, std::string> args;
|
||||
args["%quest"] = chat->FormatQuest(quest);
|
||||
|
||||
if (bot->CanRewardQuest(quest, false))
|
||||
{
|
||||
out << BOT_TEXT2("quest_status_completed", args);
|
||||
BroadcastHelper::BroadcastQuestTurnedIn(botAI, bot, quest);
|
||||
|
||||
bot->RewardQuest(quest, 0, questGiver, false);
|
||||
out << "Completed";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "|cffff0000Unable to turn in|r";
|
||||
out << BOT_TEXT2("quest_status_unable_to_complete", args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,15 +117,19 @@ void TalkToQuestGiverAction::RewardSingleItem(Quest const* quest, Object* questG
|
||||
{
|
||||
int index = 0;
|
||||
ItemTemplate const* item = sObjectMgr->GetItemTemplate(quest->RewardChoiceItemId[index]);
|
||||
std::map<std::string, std::string> args;
|
||||
args["%quest"] = chat->FormatQuest(quest);
|
||||
args["%item"] = chat->FormatItem(item);
|
||||
|
||||
if (bot->CanRewardQuest(quest, index, false))
|
||||
{
|
||||
out << BOT_TEXT2("quest_status_complete_single_reward", args);
|
||||
BroadcastHelper::BroadcastQuestTurnedIn(botAI, bot, quest);
|
||||
bot->RewardQuest(quest, index, questGiver, true);
|
||||
|
||||
out << "Rewarded " << chat->FormatItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "|cffff0000Unable to turn in:|r, reward: " << chat->FormatItem(item);
|
||||
out << BOT_TEXT2("quest_status_unable_to_complete", args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "Event.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "BroadcastHelper.h"
|
||||
|
||||
bool XpGainAction::Execute(Event event)
|
||||
{
|
||||
@@ -33,19 +33,10 @@ bool XpGainAction::Execute(Event event)
|
||||
p >> groupBonus; // 8 group bonus
|
||||
}
|
||||
|
||||
if (sPlayerbotAIConfig->randomBotGuildTalk && bot->GetGuildId() && urand(0, 10))
|
||||
Creature* creature = botAI->GetCreature(guid);
|
||||
if (creature && !creature->GetMap()->IsDungeon())
|
||||
{
|
||||
Creature* creature = botAI->GetCreature(guid);
|
||||
if (creature && (creature->isElite() || creature->isWorldBoss() || creature->GetLevel() > 61 || creature->GetLevel() > bot->GetLevel() + 4))
|
||||
{
|
||||
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
|
||||
if (guild)
|
||||
{
|
||||
std::map<std::string, std::string> args;
|
||||
args["%victim_name"] = creature->GetName();
|
||||
botAI->SayToGuild(BOT_TEXT2("broadcast_killed_rare", args));
|
||||
}
|
||||
}
|
||||
BroadcastHelper::BroadcastKill(botAI, bot, creature);
|
||||
}
|
||||
|
||||
Unit* victim = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user