mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-01-17 02:40:28 +00:00
Rewrite bot texts
This commit is contained in:
@@ -53,7 +53,6 @@
|
||||
#include "SayAction.h"
|
||||
#include "StayActions.h"
|
||||
#include "SuggestWhatToDoAction.h"
|
||||
#include "SuggestDungeonAction.h"
|
||||
#include "TravelAction.h"
|
||||
#include "XpGainAction.h"
|
||||
#include "VehicleActions.h"
|
||||
@@ -76,7 +75,6 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
creators["choose travel target"] = &ActionContext::choose_travel_target;
|
||||
creators["move to travel target"] = &ActionContext::move_to_travel_target;
|
||||
creators["move out of collision"] = &ActionContext::move_out_of_collision;
|
||||
creators["move out of collision"] = &ActionContext::move_out_of_collision;
|
||||
creators["move random"] = &ActionContext::move_random;
|
||||
creators["attack"] = &ActionContext::melee;
|
||||
creators["melee"] = &ActionContext::melee;
|
||||
@@ -118,7 +116,6 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
creators["emote"] = &ActionContext::emote;
|
||||
creators["talk"] = &ActionContext::talk;
|
||||
creators["suggest what to do"] = &ActionContext::suggest_what_to_do;
|
||||
creators["suggest dungeon"] = &ActionContext::suggest_dungeon;
|
||||
creators["suggest trade"] = &ActionContext::suggest_trade;
|
||||
creators["return"] = &ActionContext::_return;
|
||||
creators["move to loot"] = &ActionContext::move_to_loot;
|
||||
@@ -138,12 +135,12 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
creators["greet"] = &ActionContext::greet;
|
||||
creators["check values"] = &ActionContext::check_values;
|
||||
creators["ra"] = &ActionContext::ra;
|
||||
creators["give food"] = &ActionContext::give_food;
|
||||
creators["give water"] = &ActionContext::give_water;
|
||||
creators["apply poison"] = &ActionContext::apply_poison;
|
||||
creators["apply stone"] = &ActionContext::apply_stone;
|
||||
creators["apply oil"] = &ActionContext::apply_oil;
|
||||
creators["try emergency"] = &ActionContext::try_emergency;
|
||||
creators["give food"] = &ActionContext::give_food;
|
||||
creators["give water"] = &ActionContext::give_water;
|
||||
creators["mount"] = &ActionContext::mount;
|
||||
creators["war stomp"] = &ActionContext::war_stomp;
|
||||
creators["auto talents"] = &ActionContext::auto_talents;
|
||||
@@ -266,7 +263,6 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
static Action* emote(PlayerbotAI* botAI) { return new EmoteAction(botAI); }
|
||||
static Action* talk(PlayerbotAI* botAI) { return new TalkAction(botAI); }
|
||||
static Action* suggest_what_to_do(PlayerbotAI* botAI) { return new SuggestWhatToDoAction(botAI); }
|
||||
static Action* suggest_dungeon(PlayerbotAI* botAI) { return new SuggestDungeonAction(botAI); }
|
||||
static Action* suggest_trade(PlayerbotAI* botAI) { return new SuggestTradeAction(botAI); }
|
||||
static Action* attack_anything(PlayerbotAI* botAI) { return new AttackAnythingAction(botAI); }
|
||||
static Action* attack_least_hp_target(PlayerbotAI* botAI) { return new AttackLeastHpTargetAction(botAI); }
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Event.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
|
||||
std::map<std::string, uint32> EmoteActionBase::emotes;
|
||||
std::map<std::string, uint32> EmoteActionBase::textEmotes;
|
||||
@@ -778,7 +779,7 @@ bool EmoteAction::isUseful()
|
||||
return false;
|
||||
|
||||
time_t lastEmote = AI_VALUE2(time_t, "last emote", qualifier);
|
||||
return (time(nullptr) - lastEmote) >= sPlayerbotAIConfig->repeatDelay / 1000;
|
||||
return time(nullptr) >= lastEmote;
|
||||
}
|
||||
|
||||
bool TalkAction::Execute(Event event)
|
||||
|
||||
@@ -5,125 +5,26 @@
|
||||
#include "SayAction.h"
|
||||
#include "Event.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
std::map<std::string, std::vector<std::string>> SayAction::stringTable;
|
||||
std::map<std::string, uint32> SayAction::probabilityTable;
|
||||
#include "PlayerbotTextMgr.h"
|
||||
#include "ChannelMgr.h"
|
||||
#include "GuildMgr.h"
|
||||
#include <regex>
|
||||
|
||||
SayAction::SayAction(PlayerbotAI* botAI) : Action(botAI, "say"), Qualified()
|
||||
{
|
||||
}
|
||||
|
||||
void replaceAll(std::string& str, std::string const from, std::string const 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'
|
||||
}
|
||||
}
|
||||
|
||||
bool SayAction::Execute(Event event)
|
||||
{
|
||||
if (stringTable.empty())
|
||||
{
|
||||
if (PreparedQueryResult result = PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_SPEECH)))
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
std::string const name = fields[0].Get<std::string>();
|
||||
std::string text = fields[1].Get<std::string>();
|
||||
std::string const type = fields[2].Get<std::string>();
|
||||
|
||||
if (type == "yell")
|
||||
text = "/y " + text;
|
||||
|
||||
if (!text.empty() && text != "")
|
||||
stringTable[name].push_back(std::move(text));
|
||||
}
|
||||
while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
if (probabilityTable.empty())
|
||||
{
|
||||
if (PreparedQueryResult result = PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_SPEECH_PROBABILITY)))
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
std::string const name = fields[0].Get<std::string>();
|
||||
uint32 probability = fields[1].Get<uint32>();
|
||||
|
||||
probabilityTable[name] = probability;
|
||||
}
|
||||
while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string>& strings = stringTable[qualifier];
|
||||
if (strings.empty())
|
||||
return false;
|
||||
|
||||
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
||||
uint32 nextTime = time(nullptr) + urand(1, 30);
|
||||
botAI->GetAiObjectContext()->GetValue<time_t>("last said", qualifier)->Set(nextTime);
|
||||
|
||||
if (Group* group = bot->GetGroup())
|
||||
{
|
||||
std::vector<Player*> members;
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||
{
|
||||
Player* member = ref->GetSource();
|
||||
if (PlayerbotAI* memberAi = GET_PLAYERBOT_AI(member))
|
||||
members.push_back(member);
|
||||
}
|
||||
|
||||
uint32 count = members.size();
|
||||
if (count > 1)
|
||||
{
|
||||
for (uint32 i = 0; i < count * 5; i++)
|
||||
{
|
||||
uint32 i1 = urand(0, count - 1);
|
||||
uint32 i2 = urand(0, count - 1);
|
||||
|
||||
Player* item = members[i1];
|
||||
members[i1] = members[i2];
|
||||
members[i2] = item;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 index = 0;
|
||||
for (Player* player : members)
|
||||
{
|
||||
PlayerbotAI* memberAi = GET_PLAYERBOT_AI(player);
|
||||
memberAi->GetAiObjectContext()->GetValue<time_t>("last said", qualifier)->Set(nextTime + (20 * ++index) + urand(1, 15));
|
||||
}
|
||||
}
|
||||
|
||||
uint32 probability = probabilityTable[qualifier];
|
||||
if (!probability)
|
||||
probability = 100;
|
||||
|
||||
if (urand(0, 100) >= probability)
|
||||
return false;
|
||||
|
||||
uint32 idx = urand(0, strings.size() - 1);
|
||||
std::string text = strings[idx];
|
||||
|
||||
std::string text = "";
|
||||
std::map<std::string, std::string> placeholders;
|
||||
Unit* target = AI_VALUE(Unit*, "tank target");
|
||||
if (!target)
|
||||
target = AI_VALUE(Unit*, "current target");
|
||||
|
||||
if (target)
|
||||
replaceAll(text, "<target>", target->GetName());
|
||||
|
||||
replaceAll(text, "<randomfaction>", IsAlliance(bot->getRace()) ? "Alliance" : "Horde");
|
||||
|
||||
// set replace strings
|
||||
if (target) placeholders["<target>"] = target->GetName();
|
||||
placeholders["<randomfaction>"] = IsAlliance(bot->getRace()) ? "Alliance" : "Horde";
|
||||
if (qualifier == "low ammo" || qualifier == "no ammo")
|
||||
{
|
||||
if (Item* const pItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
|
||||
@@ -131,11 +32,11 @@ bool SayAction::Execute(Event event)
|
||||
switch (pItem->GetTemplate()->SubClass)
|
||||
{
|
||||
case ITEM_SUBCLASS_WEAPON_GUN:
|
||||
replaceAll(text, "<ammo>", "bullets");
|
||||
placeholders["<ammo>"] = "bullets";
|
||||
break;
|
||||
case ITEM_SUBCLASS_WEAPON_BOW:
|
||||
case ITEM_SUBCLASS_WEAPON_CROSSBOW:
|
||||
replaceAll(text, "<ammo>", "arrows");
|
||||
placeholders["<ammo>"] = "arrows";
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -144,9 +45,53 @@ bool SayAction::Execute(Event event)
|
||||
if (bot->GetMap())
|
||||
{
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(bot->GetAreaId()))
|
||||
replaceAll(text, "<subzone>", area->area_name[0]);
|
||||
placeholders["<subzone>"] = area->area_name[0];
|
||||
}
|
||||
|
||||
|
||||
// set delay before next say
|
||||
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
||||
uint32 nextTime = time(nullptr) + urand(1, 30);
|
||||
botAI->GetAiObjectContext()->GetValue<time_t>("last said", qualifier)->Set(nextTime);
|
||||
|
||||
Group* group = bot->GetGroup();
|
||||
if (group)
|
||||
{
|
||||
std::vector<Player*> members;
|
||||
for (GroupReference* ref = group->GetFirstMember(); ref; ref = ref->next())
|
||||
{
|
||||
Player* member = ref->GetSource();
|
||||
PlayerbotAI* memberAi = GET_PLAYERBOT_AI(member);
|
||||
if (memberAi) members.push_back(member);
|
||||
}
|
||||
|
||||
uint32 count = members.size();
|
||||
if (count > 1)
|
||||
{
|
||||
for (uint32 i = 0; i < count * 5; i++)
|
||||
{
|
||||
int i1 = urand(0, count - 1);
|
||||
int i2 = urand(0, count - 1);
|
||||
|
||||
Player* item = members[i1];
|
||||
members[i1] = members[i2];
|
||||
members[i2] = item;
|
||||
}
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (auto & member : members)
|
||||
{
|
||||
PlayerbotAI* memberAi = GET_PLAYERBOT_AI(member);
|
||||
if (memberAi)
|
||||
memberAi->GetAiObjectContext()->GetValue<time_t>("last said", qualifier)->Set(nextTime + (20 * ++index) + urand(1, 15));
|
||||
}
|
||||
}
|
||||
|
||||
// load text based on chance
|
||||
if (!sPlayerbotTextMgr->GetBotText(qualifier, text, placeholders))
|
||||
return false;
|
||||
|
||||
if (text.find("/y ") == 0)
|
||||
bot->Yell(text.substr(3), (bot->GetTeamId() == TEAM_ALLIANCE ? LANG_COMMON : LANG_ORCISH));
|
||||
else
|
||||
@@ -163,3 +108,540 @@ bool SayAction::isUseful()
|
||||
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
||||
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)
|
||||
{
|
||||
ChatReplyType replyType = REPLY_NOT_UNDERSTAND; // default not understand
|
||||
std::string respondsText = "";
|
||||
|
||||
// Chat Logic
|
||||
int32 verb_pos = -1;
|
||||
int32 verb_type = -1;
|
||||
int32 is_quest = 0;
|
||||
bool found = false;
|
||||
std::stringstream text(msg);
|
||||
std::string segment;
|
||||
std::vector<std::string> word;
|
||||
while (std::getline(text, segment, ' '))
|
||||
{
|
||||
word.push_back(segment);
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < 15; i++)
|
||||
{
|
||||
if (word.size() < i)
|
||||
word.push_back("");
|
||||
}
|
||||
|
||||
if (msg.find("?") != std::string::npos)
|
||||
is_quest = 1;
|
||||
if (word[0].find("what") != std::string::npos)
|
||||
is_quest = 2;
|
||||
else if (word[0].find("who") != std::string::npos)
|
||||
is_quest = 3;
|
||||
else if (word[0] == "when")
|
||||
is_quest = 4;
|
||||
else if (word[0] == "where")
|
||||
is_quest = 5;
|
||||
else if (word[0] == "why")
|
||||
is_quest = 6;
|
||||
|
||||
// Responds
|
||||
for (uint32 i = 0; i < 8; i++)
|
||||
{
|
||||
// // blame gm with chat tag
|
||||
// if (Player* plr = sObjectMgr->GetPlayer(ObjectGuid(HIGHGUID_PLAYER, guid1)))
|
||||
// {
|
||||
// if (plr->isGMChat())
|
||||
// {
|
||||
// replyType = REPLY_ADMIN_ABUSE;
|
||||
// found = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
if (word[i] == "hi" || word[i] == "hey" || word[i] == "hello" || word[i] == "wazzup")
|
||||
{
|
||||
replyType = REPLY_HELLO;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (verb_type < 4)
|
||||
{
|
||||
if (word[i] == "am" || word[i] == "are" || word[i] == "is")
|
||||
{
|
||||
verb_pos = i;
|
||||
verb_type = 2; // present
|
||||
}
|
||||
else if (word[i] == "will")
|
||||
{
|
||||
verb_pos = i;
|
||||
verb_type = 3; // future
|
||||
}
|
||||
else if (word[i] == "was" || word[i] == "were")
|
||||
{
|
||||
verb_pos = i;
|
||||
verb_type = 1; // past
|
||||
}
|
||||
else if (word[i] == "shut" || word[i] == "noob")
|
||||
{
|
||||
if (msg.find(bot->GetName()) == std::string::npos)
|
||||
{
|
||||
continue; // not react
|
||||
uint32 rnd = urand(0, 2);
|
||||
std::string msg = "";
|
||||
if (rnd == 0)
|
||||
msg = "sorry %s, ill shut up now";
|
||||
if (rnd == 1)
|
||||
msg = "ok ok %s";
|
||||
if (rnd == 2)
|
||||
msg = "fine, i wont talk to you anymore %s";
|
||||
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
replyType = REPLY_GRUDGE;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (verb_type < 4 && is_quest && !found)
|
||||
{
|
||||
switch (is_quest)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
uint32 rnd = urand(0, 3);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "i dont know what";
|
||||
break;
|
||||
case 1:
|
||||
msg = "i dont know %s";
|
||||
break;
|
||||
case 2:
|
||||
msg = "who cares";
|
||||
break;
|
||||
case 3:
|
||||
msg = "afraid that was before i was around or paying attention";
|
||||
break;
|
||||
}
|
||||
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
uint32 rnd = urand(0, 4);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "nobody";
|
||||
break;
|
||||
case 1:
|
||||
msg = "we all do";
|
||||
break;
|
||||
case 2:
|
||||
msg = "perhaps its you, %s";
|
||||
break;
|
||||
case 3:
|
||||
msg = "dunno %s";
|
||||
break;
|
||||
case 4:
|
||||
msg = "is it me?";
|
||||
break;
|
||||
}
|
||||
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
uint32 rnd = urand(0, 6);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "soon perhaps %s";
|
||||
break;
|
||||
case 1:
|
||||
msg = "probably later";
|
||||
break;
|
||||
case 2:
|
||||
msg = "never";
|
||||
break;
|
||||
case 3:
|
||||
msg = "what do i look like, a psychic?";
|
||||
break;
|
||||
case 4:
|
||||
msg = "a few minutes, maybe an hour ... years?";
|
||||
break;
|
||||
case 5:
|
||||
msg = "when? good question %s";
|
||||
break;
|
||||
case 6:
|
||||
msg = "dunno %s";
|
||||
break;
|
||||
}
|
||||
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
uint32 rnd = urand(0, 6);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "really want me to answer that?";
|
||||
break;
|
||||
case 1:
|
||||
msg = "on the map?";
|
||||
break;
|
||||
case 2:
|
||||
msg = "who cares";
|
||||
break;
|
||||
case 3:
|
||||
msg = "afk?";
|
||||
break;
|
||||
case 4:
|
||||
msg = "none of your buisiness where";
|
||||
break;
|
||||
case 5:
|
||||
msg = "yeah, where?";
|
||||
break;
|
||||
case 6:
|
||||
msg = "dunno %s";
|
||||
break;
|
||||
}
|
||||
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
uint32 rnd = urand(0, 6);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "dunno %s";
|
||||
break;
|
||||
case 1:
|
||||
msg = "why? just because %s";
|
||||
break;
|
||||
case 2:
|
||||
msg = "why is the sky blue?";
|
||||
break;
|
||||
case 3:
|
||||
msg = "dont ask me %s, im just a bot";
|
||||
break;
|
||||
case 4:
|
||||
msg = "your asking the wrong person";
|
||||
break;
|
||||
case 5:
|
||||
msg = "who knows?";
|
||||
break;
|
||||
case 6:
|
||||
msg = "dunno %s";
|
||||
break;
|
||||
}
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
switch (verb_type)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
uint32 rnd = urand(0, 3);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "its true, " + word[verb_pos + 1] + " " + word[verb_pos] + " " + word[verb_pos + 2] + " " + word[verb_pos + 3] + " " + word[verb_pos + 4] + " " + word[verb_pos + 4];
|
||||
break;
|
||||
case 1:
|
||||
msg = "ya %s but thats in the past";
|
||||
break;
|
||||
case 2:
|
||||
msg = "nah, but " + word[verb_pos + 1] + " will " + word[verb_pos + 3] + " again though %s";
|
||||
break;
|
||||
case 3:
|
||||
msg = "afraid that was before i was around or paying attention";
|
||||
break;
|
||||
}
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
uint32 rnd = urand(0, 6);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "its true, " + word[verb_pos + 1] + " " + word[verb_pos] + " " + word[verb_pos + 2] + " " + word[verb_pos + 3] + " " + word[verb_pos + 4] + " " + word[verb_pos + 5];
|
||||
break;
|
||||
case 1:
|
||||
msg = "ya %s thats true";
|
||||
break;
|
||||
case 2:
|
||||
msg = "maybe " + word[verb_pos + 1] + " " + word[verb_pos] + " " + word[verb_pos + 2] + " " + word[verb_pos + 3] + " " + word[verb_pos + 4] + " " + word[verb_pos + 5];
|
||||
break;
|
||||
case 3:
|
||||
msg = "dunno %s";
|
||||
break;
|
||||
case 4:
|
||||
msg = "i dont think so %s";
|
||||
break;
|
||||
case 5:
|
||||
msg = "yes";
|
||||
break;
|
||||
case 6:
|
||||
msg = "no";
|
||||
break;
|
||||
}
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
uint32 rnd = urand(0, 8);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "dunno %s";
|
||||
break;
|
||||
case 1:
|
||||
msg = "beats me %s";
|
||||
break;
|
||||
case 2:
|
||||
msg = "how should i know %s";
|
||||
break;
|
||||
case 3:
|
||||
msg = "dont ask me %s, im just a bot";
|
||||
break;
|
||||
case 4:
|
||||
msg = "your asking the wrong person";
|
||||
break;
|
||||
case 5:
|
||||
msg = "what do i look like, a psychic?";
|
||||
break;
|
||||
case 6:
|
||||
msg = "sure %s";
|
||||
break;
|
||||
case 7:
|
||||
msg = "i dont think so %s";
|
||||
break;
|
||||
case 8:
|
||||
msg = "maybe";
|
||||
break;
|
||||
}
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!found)
|
||||
{
|
||||
switch (verb_type)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
uint32 rnd = urand(0, 2);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "yeah %s, the key word being " + word[verb_pos] + " " + word[verb_pos + 1];
|
||||
break;
|
||||
case 1:
|
||||
msg = "ya %s but thats in the past";
|
||||
break;
|
||||
case 2:
|
||||
msg = word[verb_pos - 1] + " will " + word[verb_pos + 1] + " again though %s";
|
||||
break;
|
||||
}
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
uint32 rnd = urand(0, 2);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "%s, what do you mean " + word[verb_pos + 1] + "?";
|
||||
break;
|
||||
case 1:
|
||||
msg = "%s, what is a " + word[verb_pos + 1] + "?";
|
||||
break;
|
||||
case 2:
|
||||
msg = "yeah i know " + word[verb_pos - 1] + " is a " + word[verb_pos + 1];
|
||||
break;
|
||||
}
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
uint32 rnd = urand(0, 1);
|
||||
std::string msg = "";
|
||||
|
||||
switch (rnd)
|
||||
{
|
||||
case 0:
|
||||
msg = "are you sure thats going to happen %s?";
|
||||
break;
|
||||
case 1:
|
||||
msg = "%s, what will happen %s?";
|
||||
break;
|
||||
case 2:
|
||||
msg = "are you saying " + word[verb_pos - 1] + " will " + word[verb_pos + 1] + " " + word[verb_pos + 2] + " %s?";
|
||||
break;
|
||||
}
|
||||
msg = std::regex_replace(msg, std::regex("%s"), name);
|
||||
respondsText = msg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
// Name Responds
|
||||
if (msg.find(bot->GetName()) != std::string::npos)
|
||||
{
|
||||
replyType = REPLY_NAME;
|
||||
found = true;
|
||||
}
|
||||
else // Does not understand
|
||||
{
|
||||
replyType = REPLY_NOT_UNDERSTAND;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// send responds
|
||||
//
|
||||
if (found)
|
||||
{
|
||||
// load text if needed
|
||||
if (respondsText.empty())
|
||||
{
|
||||
respondsText = BOT_TEXT2(replyType, name);
|
||||
}
|
||||
const char* c = respondsText.c_str();
|
||||
if (strlen(c) > 255)
|
||||
return;
|
||||
|
||||
if (chanName == "World")
|
||||
{
|
||||
if (ChannelMgr* cMgr = ChannelMgr::forTeam(bot->GetTeamId()))
|
||||
{
|
||||
std::string worldChan = "World";
|
||||
if (Channel* chn = cMgr->GetJoinChannel(worldChan.c_str(), 0))
|
||||
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
||||
chn->Say(bot->GetGUID(), c, LANG_COMMON);
|
||||
else
|
||||
chn->Say(bot->GetGUID(), c, LANG_ORCISH);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == CHAT_MSG_WHISPER)
|
||||
{
|
||||
ObjectGuid receiver = sCharacterCache->GetCharacterGuidByName(name);
|
||||
if (!receiver.IsPlayer())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
||||
{
|
||||
bot->Whisper(c, LANG_COMMON, ObjectAccessor::FindPlayer(receiver));
|
||||
}
|
||||
else
|
||||
{
|
||||
bot->Whisper(c, LANG_ORCISH, ObjectAccessor::FindPlayer(receiver));
|
||||
}
|
||||
}
|
||||
|
||||
if (type == CHAT_MSG_SAY)
|
||||
{
|
||||
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
||||
bot->Say(respondsText, LANG_COMMON);
|
||||
else
|
||||
bot->Say(respondsText, LANG_ORCISH);
|
||||
}
|
||||
|
||||
if (type == CHAT_MSG_YELL)
|
||||
{
|
||||
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
||||
bot->Yell(respondsText, LANG_COMMON);
|
||||
else
|
||||
bot->Yell(respondsText, LANG_ORCISH);
|
||||
}
|
||||
|
||||
if (type == CHAT_MSG_GUILD)
|
||||
{
|
||||
if (!bot->GetGuildId())
|
||||
return;
|
||||
|
||||
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
|
||||
if (!guild)
|
||||
return;
|
||||
|
||||
guild->BroadcastToGuild(bot->GetSession(), false, respondsText, LANG_UNIVERSAL);
|
||||
}
|
||||
}
|
||||
GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<time_t>("last said", "chat")->Set(time(nullptr) + urand(5, 25));
|
||||
}
|
||||
}
|
||||
@@ -24,4 +24,13 @@ class SayAction : public Action, public Qualified
|
||||
static std::map<std::string, uint32> probabilityTable;
|
||||
};
|
||||
|
||||
|
||||
class ChatReplyAction : public Action
|
||||
{
|
||||
public:
|
||||
ChatReplyAction(PlayerbotAI* ai) : Action(ai, "chat message") {}
|
||||
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);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, 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 "SuggestDungeonAction.h"
|
||||
#include "AiFactory.h"
|
||||
#include "Player.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
#include "PlayerbotDungeonSuggestionMgr.h"
|
||||
|
||||
DungeonSuggestions SuggestDungeonAction::m_dungeonSuggestions;
|
||||
|
||||
SuggestDungeonAction::SuggestDungeonAction(PlayerbotAI* botAI) :
|
||||
SuggestWhatToDoAction(botAI, "suggest instance")
|
||||
{
|
||||
if (m_dungeonSuggestions.empty())
|
||||
{
|
||||
m_dungeonSuggestions = sPlayerbotDungeonSuggestionMgr->GetDungeonSuggestions();
|
||||
}
|
||||
}
|
||||
|
||||
bool SuggestDungeonAction::Execute(Event event)
|
||||
{
|
||||
bool const isRealPlayer = !sRandomPlayerbotMgr->IsRandomBot(bot);
|
||||
bool const isInGroup = bot->GetGroup();
|
||||
bool const isInInstance = bot->GetInstanceId();
|
||||
if (isRealPlayer || isInGroup || isInInstance)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DungeonSuggestions const dungeonSuggestions = GetDungeonSuggestionsEligibleFor(bot);
|
||||
if (dungeonSuggestions.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 const randomDungeonIndex = urand(0, dungeonSuggestions.size() - 1);
|
||||
DungeonSuggestion const* dungeonSuggestion = &dungeonSuggestions[randomDungeonIndex];
|
||||
PlaceholderMap const placeholders = MapPlaceholders(bot, dungeonSuggestion);
|
||||
std::string playerbotsTextKey = PlayerbotsTextKeyByMapKey(placeholders);
|
||||
std::string message = sPlayerbotTextMgr->Format(playerbotsTextKey, placeholders);
|
||||
bool isRandomlyLowerCase = sPlayerbotAIConfig->suggestDungeonsInLowerCaseRandomly
|
||||
? urand(0, 1)
|
||||
: false;
|
||||
spam(message, 1, isRandomlyLowerCase);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DungeonSuggestions const SuggestDungeonAction::GetDungeonSuggestionsEligibleFor(Player* bot)
|
||||
{
|
||||
DungeonSuggestions dungeonSuggestionsEligibleFor;
|
||||
for (DungeonSuggestions::const_iterator i = m_dungeonSuggestions.begin();
|
||||
i != m_dungeonSuggestions.end(); ++i)
|
||||
{
|
||||
uint8 const level = bot->getLevel();
|
||||
bool const isEligible = level >= i->min_level && level <= i->max_level;
|
||||
if (isEligible)
|
||||
{
|
||||
dungeonSuggestionsEligibleFor.push_back(*i);
|
||||
}
|
||||
}
|
||||
|
||||
return dungeonSuggestionsEligibleFor;
|
||||
}
|
||||
|
||||
PlaceholderMap SuggestDungeonAction::MapPlaceholders(
|
||||
Player* bot,
|
||||
DungeonSuggestion const* dungeonSuggestion
|
||||
)
|
||||
{
|
||||
PlaceholderMap placeholders;
|
||||
bool const isRandomlyMappingRole = urand(0, 1);
|
||||
if (isRandomlyMappingRole)
|
||||
{
|
||||
PlaceholderHelper::MapRole(placeholders, bot);
|
||||
}
|
||||
PlaceholderHelper::MapDungeon(placeholders, dungeonSuggestion, bot);
|
||||
|
||||
return placeholders;
|
||||
}
|
||||
|
||||
std::string SuggestDungeonAction::PlayerbotsTextKeyByMapKey(PlaceholderMap const& placeholders)
|
||||
{
|
||||
bool const isRoleMapped = placeholders.find("%role") != placeholders.end();
|
||||
std::string playerbotsTextKey = "suggest_dungeon";
|
||||
if (isRoleMapped)
|
||||
{
|
||||
playerbotsTextKey = "suggest_dungeon_role";
|
||||
}
|
||||
|
||||
return playerbotsTextKey;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, 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.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_SUGGESTINSTANCEACTION_H
|
||||
#define _PLAYERBOT_SUGGESTINSTANCEACTION_H
|
||||
|
||||
#include "SuggestWhatToDoAction.h"
|
||||
#include "PlayerbotDungeonSuggestionMgr.h"
|
||||
#include "PlaceholderHelper.h"
|
||||
|
||||
typedef std::vector<DungeonSuggestion> DungeonSuggestions;
|
||||
|
||||
class SuggestDungeonAction : public SuggestWhatToDoAction
|
||||
{
|
||||
public:
|
||||
SuggestDungeonAction(PlayerbotAI* botAI);
|
||||
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override { return true; }
|
||||
|
||||
private:
|
||||
static DungeonSuggestions m_dungeonSuggestions;
|
||||
|
||||
DungeonSuggestions const GetDungeonSuggestionsEligibleFor(Player* bot);
|
||||
PlaceholderMap MapPlaceholders(
|
||||
Player* bot,
|
||||
DungeonSuggestion const* dungeonSuggestion
|
||||
);
|
||||
std::string PlayerbotsTextKeyByMapKey(PlaceholderMap const& placeholders);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -10,7 +10,9 @@
|
||||
#include "ChatHelper.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
#include "GuildMgr.h"
|
||||
|
||||
std::map<std::string, uint8> SuggestWhatToDoAction::instances;
|
||||
std::map<std::string, uint8> SuggestWhatToDoAction::factions;
|
||||
|
||||
SuggestWhatToDoAction::SuggestWhatToDoAction(PlayerbotAI* botAI, std::string const name) : InventoryAction(botAI, name)
|
||||
@@ -35,6 +37,73 @@ bool SuggestWhatToDoAction::Execute(Event event)
|
||||
return true;
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::instance()
|
||||
{
|
||||
if (instances.empty())
|
||||
{
|
||||
instances["Ragefire Chasm"] = 15;
|
||||
instances["Deadmines"] = 18;
|
||||
instances["Wailing Caverns"] = 18;
|
||||
instances["Shadowfang Keep"] = 25;
|
||||
instances["Blackfathom Deeps"] = 20;
|
||||
instances["Stockade"] = 20;
|
||||
instances["Gnomeregan"] = 35;
|
||||
instances["Razorfen Kraul"] = 35;
|
||||
instances["Maraudon"] = 50;
|
||||
instances["Scarlet Monestery"] = 40;
|
||||
instances["Uldaman"] = 45;
|
||||
instances["Dire Maul"] = 58;
|
||||
instances["Scholomance"] = 59;
|
||||
instances["Razorfen Downs"] = 40;
|
||||
instances["Strathholme"] = 59;
|
||||
instances["Zul'Farrak"] = 45;
|
||||
instances["Blackrock Depths"] = 55;
|
||||
instances["Temple of Atal'Hakkar"] = 55;
|
||||
instances["Lower Blackrock Spire"] = 57;
|
||||
|
||||
instances["Hellfire Citidel"] = 65;
|
||||
instances["Coilfang Reservoir"] = 65;
|
||||
instances["Auchindoun"] = 65;
|
||||
instances["Cavens of Time"] = 68;
|
||||
instances["Tempest Keep"] = 69;
|
||||
instances["Magister's Terrace"] = 70;
|
||||
|
||||
instances["Utgarde Keep"] = 75;
|
||||
instances["The Nexus"] = 75;
|
||||
instances["Ahn'kahet: The Old Kingdom"] = 75;
|
||||
instances["Azjol-Nerub"] = 75;
|
||||
instances["Drak'Tharon Keep"] = 75;
|
||||
instances["Violet Hold"] = 80;
|
||||
instances["Gundrak"] = 77;
|
||||
instances["Halls of Stone"] = 77;
|
||||
instances["Halls of Lightning"] = 77;
|
||||
instances["Oculus"] = 77;
|
||||
instances["Utgarde Pinnacle"] = 77;
|
||||
instances["Trial of the Champion"] = 80;
|
||||
instances["Forge of Souls"] = 80;
|
||||
instances["Pit of Saron"] = 80;
|
||||
instances["Halls of Reflection"] = 80;
|
||||
}
|
||||
|
||||
std::vector<std::string> allowedInstances;
|
||||
for (auto & instance : instances)
|
||||
{
|
||||
if (bot->getLevel() >= instance.second) allowedInstances.push_back(instance.first);
|
||||
}
|
||||
|
||||
if (allowedInstances.empty()) return;
|
||||
|
||||
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) ? 0x50 : 0, urand(0, 2), urand(0, 2));
|
||||
}
|
||||
|
||||
std::vector<uint32> SuggestWhatToDoAction::GetIncompletedQuests()
|
||||
{
|
||||
std::vector<uint32> result;
|
||||
@@ -67,7 +136,7 @@ void SuggestWhatToDoAction::specificQuest()
|
||||
placeholders["%role"] = chat->FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
||||
placeholders["%quest"] = chat->FormatQuest(quest);
|
||||
|
||||
spam(sPlayerbotTextMgr->Format("suggest_quest", placeholders));
|
||||
spam(BOT_TEXT2("suggest_quest", placeholders), urand(0, 1) ? 0x18 : 0, urand(0, 2), urand(0, 2));
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::grindReputation()
|
||||
@@ -134,10 +203,11 @@ void SuggestWhatToDoAction::grindReputation()
|
||||
placeholders["%rndK"] = rnd.str();
|
||||
|
||||
std::ostringstream itemout;
|
||||
itemout << "|c004040b0" << allowedFactions[urand(0, allowedFactions.size() - 1)] << "|r";
|
||||
// itemout << "|c004040b0" << allowedFactions[urand(0, allowedFactions.size() - 1)] << "|r";
|
||||
itemout << allowedFactions[urand(0, allowedFactions.size() - 1)];
|
||||
placeholders["%faction"] = itemout.str();
|
||||
|
||||
spam(sPlayerbotTextMgr->Format("suggest_faction", placeholders));
|
||||
spam(BOT_TEXT2("suggest_faction", placeholders), 0x18, true);
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::something()
|
||||
@@ -150,48 +220,88 @@ void SuggestWhatToDoAction::something()
|
||||
return;
|
||||
|
||||
std::ostringstream out;
|
||||
out << "|cffb04040" << entry->area_name[0] << "|r";
|
||||
// out << "|cffb04040" << entry->area_name[0] << "|r";
|
||||
out << entry->area_name[0];
|
||||
placeholders["%zone"] = out.str();
|
||||
|
||||
spam(sPlayerbotTextMgr->Format("suggest_something", placeholders));
|
||||
spam(BOT_TEXT2("suggest_something", placeholders), urand(0, 1) ? 0x18 : 0, urand(0, 2), urand(0, 2));
|
||||
}
|
||||
|
||||
void SuggestWhatToDoAction::spam(
|
||||
std::string msg,
|
||||
uint32 channelId,
|
||||
bool const isLowerCase
|
||||
)
|
||||
void SuggestWhatToDoAction::spam(std::string msg, uint8 flags, bool worldChat, bool guild)
|
||||
{
|
||||
std::set<std::string> said;
|
||||
if (msg.empty())
|
||||
return;
|
||||
|
||||
std::vector<std::string> channelNames;
|
||||
ChannelMgr* cMgr = ChannelMgr::forTeam(bot->GetTeamId());
|
||||
if (!cMgr)
|
||||
return;
|
||||
|
||||
|
||||
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
||||
{
|
||||
ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i);
|
||||
if (!channel || channel->ChannelID != channelId) continue;
|
||||
if (!channel) continue;
|
||||
|
||||
for (AreaTableEntry const* area : sAreaTableStore)
|
||||
for (AreaTableEntry const* current_zone : sAreaTableStore)
|
||||
{
|
||||
char channelName[255];
|
||||
snprintf(channelName, 255, channel->pattern[0], area->area_name[0]);
|
||||
if (said.find(channelName) != said.end())
|
||||
if (!current_zone)
|
||||
continue;
|
||||
|
||||
|
||||
// combine full channel name
|
||||
char channelName[100];
|
||||
Channel* chn = nullptr;
|
||||
if ((channel->flags & CHANNEL_DBC_FLAG_LFG) != 0)
|
||||
{
|
||||
std::string chanName = channel->pattern[0];
|
||||
chn = cMgr->GetChannel(chanName, bot);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(channelName, 100, channel->pattern[0], current_zone->area_name[0]);
|
||||
chn = cMgr->GetChannel(channelName, bot);
|
||||
}
|
||||
if (!chn)
|
||||
continue;
|
||||
// skip world chat here
|
||||
if (chn->GetName() == "World")
|
||||
continue;
|
||||
|
||||
said.insert(channelName);
|
||||
if (flags != 0 && chn->GetFlags() != flags)
|
||||
continue;
|
||||
|
||||
if (ChannelMgr* cMgr = ChannelMgr::forTeam(bot->GetTeamId()))
|
||||
// skip local defense
|
||||
//if (chn->GetFlags() == 0x18)
|
||||
// continue;
|
||||
|
||||
// no filter, pick several options
|
||||
if (flags == CHANNEL_FLAG_NONE)
|
||||
{
|
||||
if (Channel* chn = cMgr->GetJoinChannel(channelName, channel->ChannelID))
|
||||
{
|
||||
chn->JoinChannel(bot, "");
|
||||
if (isLowerCase)
|
||||
{
|
||||
strToLower(msg);
|
||||
}
|
||||
if (chn->GetName().length() > 0)
|
||||
{
|
||||
chn->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
||||
}
|
||||
}
|
||||
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 (guild && bot->GetGuildId())
|
||||
{
|
||||
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
|
||||
if (guild)
|
||||
guild->BroadcastToGuild(bot->GetSession(), false, msg.c_str(), LANG_UNIVERSAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,7 +400,7 @@ bool SuggestTradeAction::Execute(Event event)
|
||||
placeholders["%item"] = chat->FormatItem(proto, count);
|
||||
placeholders["%gold"] = chat->formatMoney(price);
|
||||
|
||||
spam(sPlayerbotTextMgr->Format("suggest_sell", placeholders));
|
||||
spam(BOT_TEXT2("suggest_sell", placeholders), urand(0, 1) ? 0x3C : 0, urand(0, 1), urand(0, 5));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,14 +20,11 @@ class SuggestWhatToDoAction : public InventoryAction
|
||||
protected:
|
||||
typedef void (SuggestWhatToDoAction::*Suggestion)();
|
||||
std::vector<Suggestion> suggestions;
|
||||
void instance();
|
||||
void specificQuest();
|
||||
void grindReputation();
|
||||
void something();
|
||||
void spam(
|
||||
std::string msg,
|
||||
uint32 channelId = 1,
|
||||
bool const isLowerCase = false
|
||||
);
|
||||
void spam(std::string msg, uint8 flags = 0, bool worldChat = false, bool guild = false);
|
||||
|
||||
std::vector<uint32> GetIncompletedQuests();
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
void EmoteStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("emote", 1.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("suggest what to do", 1.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("suggest trade", 1.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("suggest what to do", 1.0f), nullptr)));
|
||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("suggest trade", 1.0f), nullptr)));
|
||||
|
||||
if (sPlayerbotAIConfig->randomBotSuggestDungeons)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user