mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Merge pull request #386 from atidot3/locale_fix
Playerbot functionnality to use (channels / emote / say / yell / guild) chat
This commit is contained in:
@@ -1238,6 +1238,19 @@ AiPlayerbot.CommandPrefix = ""
|
|||||||
# Separator for bot chat commands
|
# Separator for bot chat commands
|
||||||
AiPlayerbot.CommandSeparator = "\\\\"
|
AiPlayerbot.CommandSeparator = "\\\\"
|
||||||
|
|
||||||
|
# Enable playerbot talk (say / yell / general chatting / lfg)
|
||||||
|
AiPlayerbot.RandomBotTalk = 0
|
||||||
|
|
||||||
|
# Enable playerbot emote
|
||||||
|
AiPlayerbot.RandomBotEmote = 0
|
||||||
|
|
||||||
|
# Enable dungeon suggestions for random bots
|
||||||
|
AiPlayerbot.RandomBotSuggestDungeons = 1
|
||||||
|
|
||||||
|
# Bots greet to the players
|
||||||
|
AiPlayerbot.EnableGreet = 0
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
@@ -1276,9 +1289,6 @@ AiPlayerbot.RandomBotLoginAtStartup = 1
|
|||||||
# Guild Task system
|
# Guild Task system
|
||||||
AiPlayerbot.EnableGuildTasks = 0
|
AiPlayerbot.EnableGuildTasks = 0
|
||||||
|
|
||||||
# Enable dungeon suggestions for random bots
|
|
||||||
AiPlayerbot.RandomBotSuggestDungeons = 1
|
|
||||||
|
|
||||||
# Enable dungeon suggestions in lower case randomly
|
# Enable dungeon suggestions in lower case randomly
|
||||||
AiPlayerbot.SuggestDungeonsInLowerCaseRandomly = 0
|
AiPlayerbot.SuggestDungeonsInLowerCaseRandomly = 0
|
||||||
|
|
||||||
@@ -1297,9 +1307,6 @@ AiPlayerbot.RandombotsWalkingRPG = 0
|
|||||||
# Set randombots movement speed to walking only inside buildings
|
# Set randombots movement speed to walking only inside buildings
|
||||||
AiPlayerbot.RandombotsWalkingRPG.InDoors = 0
|
AiPlayerbot.RandombotsWalkingRPG.InDoors = 0
|
||||||
|
|
||||||
# Bots greet to the players
|
|
||||||
AiPlayerbot.EnableGreet = 0
|
|
||||||
|
|
||||||
# Specify percent of active bots
|
# Specify percent of active bots
|
||||||
# The default is 10. With 10% of all bots going active or inactive each minute.
|
# The default is 10. With 10% of all bots going active or inactive each minute.
|
||||||
AiPlayerbot.BotActiveAlone = 100
|
AiPlayerbot.BotActiveAlone = 100
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
|||||||
|
|
||||||
if (!player->InBattleground())
|
if (!player->InBattleground())
|
||||||
{
|
{
|
||||||
engine->addStrategies("racials", "chat", "default", "cast time", "duel", "boost", nullptr);
|
engine->addStrategies("racials", "chat", "default", "cast time", "duel", "boost", "emote", nullptr);
|
||||||
}
|
}
|
||||||
if (sPlayerbotAIConfig->autoSaveMana)
|
if (sPlayerbotAIConfig->autoSaveMana)
|
||||||
{
|
{
|
||||||
@@ -548,7 +548,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
|||||||
if (!player->InBattleground())
|
if (!player->InBattleground())
|
||||||
{
|
{
|
||||||
nonCombatEngine->addStrategies("nc", "food", "chat", "follow",
|
nonCombatEngine->addStrategies("nc", "food", "chat", "follow",
|
||||||
"default", "quest", "loot", "gather", "duel", "buff", "mount", nullptr);
|
"default", "quest", "loot", "gather", "duel", "buff", "mount", "emote", nullptr);
|
||||||
}
|
}
|
||||||
if (sPlayerbotAIConfig->autoSaveMana) {
|
if (sPlayerbotAIConfig->autoSaveMana) {
|
||||||
nonCombatEngine->addStrategy("auto save mana");
|
nonCombatEngine->addStrategy("auto save mana");
|
||||||
@@ -636,7 +636,7 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
|||||||
// Battleground switch
|
// Battleground switch
|
||||||
if (player->InBattleground() && player->GetBattleground())
|
if (player->InBattleground() && player->GetBattleground())
|
||||||
{
|
{
|
||||||
nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "dps assist", "attack tagged", nullptr);
|
nonCombatEngine->addStrategies("nc", "chat", "default", "buff", "food", "mount", "pvp", "dps assist", "attack tagged", "emote", nullptr);
|
||||||
nonCombatEngine->removeStrategy("custom::say");
|
nonCombatEngine->removeStrategy("custom::say");
|
||||||
nonCombatEngine->removeStrategy("travel");
|
nonCombatEngine->removeStrategy("travel");
|
||||||
nonCombatEngine->removeStrategy("rpg");
|
nonCombatEngine->removeStrategy("rpg");
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ std::string const ChatHelper::FormatQuest(Quest const* quest)
|
|||||||
std::string const ChatHelper::FormatGameobject(GameObject* go)
|
std::string const ChatHelper::FormatGameobject(GameObject* go)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "|cFFFFFF00|Hfound:" << go->GetGUID().GetRawValue() << ":" << go->GetEntry() << ":" << "|h[" << go->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale()) << "]|h|r";
|
out << "|cFFFFFF00|Hfound:" << go->GetGUID().GetRawValue() << ":" << go->GetEntry() << ":" << "|h[" << go->GetNameForLocaleIdx(LOCALE_enUS) << "]|h|r";
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +296,7 @@ std::string const ChatHelper::FormatWorldobject(WorldObject* wo)
|
|||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "|cFFFFFF00|Hfound:" << wo->GetGUID().GetRawValue() << ":" << wo->GetEntry() << ":" << "|h[";
|
out << "|cFFFFFF00|Hfound:" << wo->GetGUID().GetRawValue() << ":" << wo->GetEntry() << ":" << "|h[";
|
||||||
out << (wo->ToGameObject() ? ((GameObject*)wo)->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale()) : wo->GetNameForLocaleIdx(sWorld->GetDefaultDbcLocale())) << "]|h|r";
|
out << (wo->ToGameObject() ? ((GameObject*)wo)->GetNameForLocaleIdx(LOCALE_enUS) : wo->GetNameForLocaleIdx(LOCALE_enUS)) << "]|h|r";
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@ std::string const ChatHelper::FormatWorldEntry(int32 entry)
|
|||||||
std::string const ChatHelper::FormatSpell(SpellInfo const* spellInfo)
|
std::string const ChatHelper::FormatSpell(SpellInfo const* spellInfo)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "|cffffffff|Hspell:" << spellInfo->Id << "|h[" << spellInfo->SpellName[sWorld->GetDefaultDbcLocale()] << "]|h|r";
|
out << "|cffffffff|Hspell:" << spellInfo->Id << "|h[" << spellInfo->SpellName[LOCALE_enUS] << "]|h|r";
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ std::string const ChatHelper::FormatItem(ItemTemplate const* proto, uint32 count
|
|||||||
char color[32];
|
char color[32];
|
||||||
sprintf(color, "%x", ItemQualityColors[proto->Quality]);
|
sprintf(color, "%x", ItemQualityColors[proto->Quality]);
|
||||||
|
|
||||||
// const std::string &name = sObjectMgr->GetItemLocale(proto->ItemId)->Name[sWorld->GetDefaultDbcLocale()];
|
// const std::string &name = sObjectMgr->GetItemLocale(proto->ItemId)->Name[LOCALE_enUS];
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
out << "|c" << color << "|Hitem:" << proto->ItemId
|
out << "|c" << color << "|Hitem:" << proto->ItemId
|
||||||
|
|||||||
@@ -140,6 +140,8 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
minRandomBotsPriceChangeInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotsPriceChangeInterval", 2 * HOUR);
|
minRandomBotsPriceChangeInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotsPriceChangeInterval", 2 * HOUR);
|
||||||
maxRandomBotsPriceChangeInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR);
|
maxRandomBotsPriceChangeInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR);
|
||||||
randomBotJoinLfg = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinLfg", true);
|
randomBotJoinLfg = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinLfg", true);
|
||||||
|
randomBotTalk = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotTalk", false);
|
||||||
|
randomBotEmote = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotEmote", false);
|
||||||
randomBotSuggestDungeons = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotSuggestDungeons", true);
|
randomBotSuggestDungeons = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotSuggestDungeons", true);
|
||||||
suggestDungeonsInLowerCaseRandomly = sConfigMgr->GetOption<bool>("AiPlayerbot.SuggestDungeonsInLowerCaseRandomly", false);
|
suggestDungeonsInLowerCaseRandomly = sConfigMgr->GetOption<bool>("AiPlayerbot.SuggestDungeonsInLowerCaseRandomly", false);
|
||||||
randomBotJoinBG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinBG", true);
|
randomBotJoinBG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinBG", true);
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ class PlayerbotAIConfig
|
|||||||
uint32 randomBotsPerInterval;
|
uint32 randomBotsPerInterval;
|
||||||
uint32 minRandomBotsPriceChangeInterval, maxRandomBotsPriceChangeInterval;
|
uint32 minRandomBotsPriceChangeInterval, maxRandomBotsPriceChangeInterval;
|
||||||
bool randomBotJoinLfg;
|
bool randomBotJoinLfg;
|
||||||
|
bool randomBotTalk;
|
||||||
|
bool randomBotEmote;
|
||||||
bool randomBotSuggestDungeons;
|
bool randomBotSuggestDungeons;
|
||||||
bool suggestDungeonsInLowerCaseRandomly;
|
bool suggestDungeonsInLowerCaseRandomly;
|
||||||
bool randomBotJoinBG;
|
bool randomBotJoinBG;
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
|
|||||||
|
|
||||||
uint32 botAccountId = holder.GetAccountId();
|
uint32 botAccountId = holder.GetAccountId();
|
||||||
|
|
||||||
WorldSession* botSession = new WorldSession(botAccountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING, time_t(0), LOCALE_enUS, 0, false, false, 0, true);
|
// At login DBC locale should be what the server is set to use by default (as spells etc are hardcoded to ENUS this allows channels to work as intended)
|
||||||
|
WorldSession* botSession = new WorldSession(botAccountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING, time_t(0), sWorld->GetDefaultDbcLocale(), 0, false, false, 0, true);
|
||||||
|
|
||||||
botSession->HandlePlayerLoginFromDB(holder); // will delete lqh
|
botSession->HandlePlayerLoginFromDB(holder); // will delete lqh
|
||||||
|
|
||||||
@@ -544,13 +545,13 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
|||||||
Channel* new_channel = nullptr;
|
Channel* new_channel = nullptr;
|
||||||
if (isLfg)
|
if (isLfg)
|
||||||
{
|
{
|
||||||
std::string lfgChannelName = channel->pattern[0];
|
std::string lfgChannelName = channel->pattern[sWorld->GetDefaultDbcLocale()];
|
||||||
new_channel = cMgr->GetJoinChannel("LookingForGroup", channel->ChannelID);
|
new_channel = cMgr->GetJoinChannel("LookingForGroup", channel->ChannelID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char new_channel_name_buf[100];
|
char new_channel_name_buf[100];
|
||||||
snprintf(new_channel_name_buf, 100, channel->pattern[0], current_zone_name.c_str());
|
snprintf(new_channel_name_buf, 100, channel->pattern[sWorld->GetDefaultDbcLocale()], current_zone_name.c_str());
|
||||||
new_channel = cMgr->GetJoinChannel(new_channel_name_buf, channel->ChannelID);
|
new_channel = cMgr->GetJoinChannel(new_channel_name_buf, channel->ChannelID);
|
||||||
}
|
}
|
||||||
if (new_channel && new_channel->GetName().length() > 0)
|
if (new_channel && new_channel->GetName().length() > 0)
|
||||||
|
|||||||
@@ -28,12 +28,13 @@ void PlayerbotTextMgr::LoadBotTexts()
|
|||||||
Field* fields = result->Fetch();
|
Field* fields = result->Fetch();
|
||||||
std::string name = fields[0].Get<std::string>();
|
std::string name = fields[0].Get<std::string>();
|
||||||
text[0] = fields[1].Get<std::string>();
|
text[0] = fields[1].Get<std::string>();
|
||||||
uint32 sayType = fields[2].Get<uint32>();
|
uint8 sayType = fields[2].Get<uint8>();
|
||||||
uint32 replyType = fields[3].Get<uint32>();
|
uint8 replyType = fields[3].Get<uint8>();
|
||||||
for (uint8 i = 1; i < MAX_LOCALES; ++i)
|
for (uint8 i = 1; i < MAX_LOCALES; ++i)
|
||||||
{
|
{
|
||||||
text[i] = fields[i + 3].Get<std::string>();
|
text[i] = fields[i + 3].Get<std::string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
botTexts[name].push_back(BotTextEntry(name, text, sayType, replyType));
|
botTexts[name].push_back(BotTextEntry(name, text, sayType, replyType));
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
@@ -191,6 +192,7 @@ uint32 PlayerbotTextMgr::GetLocalePriority()
|
|||||||
if (botTextLocalePriority[i] > topLocale)
|
if (botTextLocalePriority[i] > topLocale)
|
||||||
topLocale = i;
|
topLocale = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return topLocale;
|
return topLocale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1228,8 +1228,8 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
|||||||
if (bot->GetLevel() <= 18 && (loc.GetMapId() != pInfo->mapId || dis > 10000.0f)) {
|
if (bot->GetLevel() <= 18 && (loc.GetMapId() != pInfo->mapId || dis > 10000.0f)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LocaleConstant locale = sWorld->GetDefaultDbcLocale();
|
|
||||||
|
const LocaleConstant& locale = sWorld->GetDefaultDbcLocale();
|
||||||
LOG_INFO("playerbots", "Random teleporting bot {} (level {}) to Map: {} ({}) Zone: {} ({}) Area: {} ({}) {},{},{} ({}/{} locations)",
|
LOG_INFO("playerbots", "Random teleporting bot {} (level {}) to Map: {} ({}) Zone: {} ({}) Area: {} ({}) {},{},{} ({}/{} locations)",
|
||||||
bot->GetName().c_str(), bot->GetLevel(),
|
bot->GetName().c_str(), bot->GetLevel(),
|
||||||
map->GetId(), map->GetMapName(),
|
map->GetId(), map->GetMapName(),
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
|
|||||||
|
|
||||||
if (!action)
|
if (!action)
|
||||||
{
|
{
|
||||||
|
//LOG_ERROR("playerbots", "Action: {} - is UNKNOWN - c:{} l:{}", actionNode->getName().c_str(), botAI->GetBot()->getClass(), botAI->GetBot()->GetLevel());
|
||||||
LogAction("A:%s - UNKNOWN", actionNode->getName().c_str());
|
LogAction("A:%s - UNKNOWN", actionNode->getName().c_str());
|
||||||
}
|
}
|
||||||
else if (action->isUseful())
|
else if (action->isUseful())
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ class ActionContext : public NamedObjectContext<Action>
|
|||||||
creators["talk"] = &ActionContext::talk;
|
creators["talk"] = &ActionContext::talk;
|
||||||
creators["suggest what to do"] = &ActionContext::suggest_what_to_do;
|
creators["suggest what to do"] = &ActionContext::suggest_what_to_do;
|
||||||
creators["suggest trade"] = &ActionContext::suggest_trade;
|
creators["suggest trade"] = &ActionContext::suggest_trade;
|
||||||
|
creators["suggest dungeon"] = &ActionContext::suggest_dungeon;
|
||||||
creators["return"] = &ActionContext::_return;
|
creators["return"] = &ActionContext::_return;
|
||||||
creators["move to loot"] = &ActionContext::move_to_loot;
|
creators["move to loot"] = &ActionContext::move_to_loot;
|
||||||
creators["open loot"] = &ActionContext::open_loot;
|
creators["open loot"] = &ActionContext::open_loot;
|
||||||
@@ -280,6 +281,7 @@ class ActionContext : public NamedObjectContext<Action>
|
|||||||
static Action* talk(PlayerbotAI* botAI) { return new TalkAction(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_what_to_do(PlayerbotAI* botAI) { return new SuggestWhatToDoAction(botAI); }
|
||||||
static Action* suggest_trade(PlayerbotAI* botAI) { return new SuggestTradeAction(botAI); }
|
static Action* suggest_trade(PlayerbotAI* botAI) { return new SuggestTradeAction(botAI); }
|
||||||
|
static Action* suggest_dungeon(PlayerbotAI* botAI) { return new SuggestDungeonAction(botAI); }
|
||||||
static Action* attack_anything(PlayerbotAI* botAI) { return new AttackAnythingAction(botAI); }
|
static Action* attack_anything(PlayerbotAI* botAI) { return new AttackAnythingAction(botAI); }
|
||||||
static Action* attack_least_hp_target(PlayerbotAI* botAI) { return new AttackLeastHpTargetAction(botAI); }
|
static Action* attack_least_hp_target(PlayerbotAI* botAI) { return new AttackLeastHpTargetAction(botAI); }
|
||||||
static Action* attack_enemy_player(PlayerbotAI* botAI) { return new AttackEnemyPlayerAction(botAI); }
|
static Action* attack_enemy_player(PlayerbotAI* botAI) { return new AttackEnemyPlayerAction(botAI); }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "PlayerbotFactory.h"
|
#include "PlayerbotFactory.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
#include "GuildMgr.h"
|
||||||
|
|
||||||
bool AutoLearnSpellAction::Execute(Event event)
|
bool AutoLearnSpellAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
@@ -27,7 +28,6 @@ bool AutoLearnSpellAction::Execute(Event event)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AutoLearnSpellAction::LearnSpells(std::ostringstream* out)
|
void AutoLearnSpellAction::LearnSpells(std::ostringstream* out)
|
||||||
{
|
{
|
||||||
if (sPlayerbotAIConfig->autoLearnTrainerSpells && sRandomPlayerbotMgr->IsRandomBot(bot))// || (!botAI->GetMaster() && sRandomPlayerbotMgr->IsRandomBot(bot)))
|
if (sPlayerbotAIConfig->autoLearnTrainerSpells && sRandomPlayerbotMgr->IsRandomBot(bot))// || (!botAI->GetMaster() && sRandomPlayerbotMgr->IsRandomBot(bot)))
|
||||||
@@ -35,6 +35,21 @@ void AutoLearnSpellAction::LearnSpells(std::ostringstream* out)
|
|||||||
|
|
||||||
if (sPlayerbotAIConfig->autoLearnQuestSpells && sRandomPlayerbotMgr->IsRandomBot(bot))// || (!botAI->GetMaster() && sRandomPlayerbotMgr->IsRandomBot(bot)))
|
if (sPlayerbotAIConfig->autoLearnQuestSpells && sRandomPlayerbotMgr->IsRandomBot(bot))// || (!botAI->GetMaster() && sRandomPlayerbotMgr->IsRandomBot(bot)))
|
||||||
LearnQuestSpells(out);
|
LearnQuestSpells(out);
|
||||||
|
|
||||||
|
if (sPlayerbotAIConfig->randomBotTalk)
|
||||||
|
{
|
||||||
|
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
|
||||||
|
if (guild)
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string> placeholders;
|
||||||
|
placeholders["%level"] = std::to_string(bot->GetLevel());
|
||||||
|
|
||||||
|
if (urand(0, 3))
|
||||||
|
guild->BroadcastToGuild(bot->GetSession(), false, BOT_TEXT2("Ding!", placeholders), LANG_UNIVERSAL);
|
||||||
|
else
|
||||||
|
guild->BroadcastToGuild(bot->GetSession(), false, BOT_TEXT2("Yay level %level!", placeholders), LANG_UNIVERSAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoLearnSpellAction::LearnTrainerSpells(std::ostringstream* out)
|
void AutoLearnSpellAction::LearnTrainerSpells(std::ostringstream* out)
|
||||||
|
|||||||
@@ -671,9 +671,9 @@ bool EmoteAction::Execute(Event event)
|
|||||||
if (pSource && (pSource->GetGUID() != bot->GetGUID()) && ((urand(0, 1) && bot->HasInArc(static_cast<float>(M_PI), pSource, 10.0f)) ||
|
if (pSource && (pSource->GetGUID() != bot->GetGUID()) && ((urand(0, 1) && bot->HasInArc(static_cast<float>(M_PI), pSource, 10.0f)) ||
|
||||||
(namlen > 1 && strstri(bot->GetName().c_str(), nam.c_str()))))
|
(namlen > 1 && strstri(bot->GetName().c_str(), nam.c_str()))))
|
||||||
{
|
{
|
||||||
LOG_INFO("playerbots", "Bot {} {}:{} <{}> received SMSG_TEXT_EMOTE {} from player {} <{}>",
|
/*LOG_INFO("playerbots", "Bot {} {}:{} <{}> received SMSG_TEXT_EMOTE {} from player {} <{}>",
|
||||||
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(),
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(),
|
||||||
bot->GetName(), text_emote, pSource->GetGUID().ToString().c_str(), pSource->GetName());
|
bot->GetName(), text_emote, pSource->GetGUID().ToString().c_str(), pSource->GetName());*/
|
||||||
|
|
||||||
emote = text_emote;
|
emote = text_emote;
|
||||||
}
|
}
|
||||||
@@ -693,9 +693,9 @@ bool EmoteAction::Execute(Event event)
|
|||||||
if ((pSource->GetGUID() != bot->GetGUID()) && (pSource->GetTarget() == bot->GetGUID() ||
|
if ((pSource->GetGUID() != bot->GetGUID()) && (pSource->GetTarget() == bot->GetGUID() ||
|
||||||
(urand(0, 1) && bot->HasInArc(static_cast<float>(M_PI), pSource, 10.0f))))
|
(urand(0, 1) && bot->HasInArc(static_cast<float>(M_PI), pSource, 10.0f))))
|
||||||
{
|
{
|
||||||
LOG_INFO("playerbots", "Bot {} {}:{} <{}> received SMSG_EMOTE {} from player {} <{}>",
|
/*LOG_INFO("playerbots", "Bot {} {}:{} <{}> received SMSG_EMOTE {} from player {} <{}>",
|
||||||
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName(),
|
bot->GetGUID().ToString().c_str(), bot->GetTeamId() == TEAM_ALLIANCE ? "A" : "H", bot->GetLevel(), bot->GetName(),
|
||||||
emoteId, pSource->GetGUID().ToString().c_str(), pSource->GetName());
|
emoteId, pSource->GetGUID().ToString().c_str(), pSource->GetName());*/
|
||||||
|
|
||||||
std::vector<uint32> types;
|
std::vector<uint32> types;
|
||||||
for (int32 i = sEmotesTextStore.GetNumRows(); i >= 0; --i)
|
for (int32 i = sEmotesTextStore.GetNumRows(); i >= 0; --i)
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ bool LfgJoinAction::JoinLFG()
|
|||||||
|
|
||||||
const auto& botLevel = bot->GetLevel();
|
const auto& botLevel = bot->GetLevel();
|
||||||
|
|
||||||
/*LFG_TYPE_RANDOM on classic is 15-58 so bot over level 25 will never queue*/
|
/*LFG_TYPE_RANDOM on classic is 15-58 so bot over level 25 will never queue*/
|
||||||
if (dungeon->MinLevel && (botLevel < dungeon->MinLevel || botLevel > dungeon->MaxLevel)
|
if (dungeon->MinLevel && (botLevel < dungeon->MinLevel || botLevel > dungeon->MaxLevel)
|
||||||
||
|
||
|
||||||
(botLevel > dungeon->MinLevel + 10 && dungeon->TypeID == LFG_TYPE_DUNGEON)
|
(botLevel > dungeon->MinLevel + 10 && dungeon->TypeID == LFG_TYPE_DUNGEON)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "PlayerbotAIConfig.h"
|
#include "PlayerbotAIConfig.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "ServerFacade.h"
|
#include "ServerFacade.h"
|
||||||
|
#include "GuildMgr.h"
|
||||||
|
|
||||||
bool LootAction::Execute(Event event)
|
bool LootAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
@@ -416,6 +417,22 @@ bool StoreLootAction::Execute(Event event)
|
|||||||
if (proto->Quality >= ITEM_QUALITY_RARE && !urand(0, 1) && botAI->HasStrategy("emote", BOT_STATE_NON_COMBAT))
|
if (proto->Quality >= ITEM_QUALITY_RARE && !urand(0, 1) && botAI->HasStrategy("emote", BOT_STATE_NON_COMBAT))
|
||||||
botAI->PlayEmote(TEXT_EMOTE_CHEER);
|
botAI->PlayEmote(TEXT_EMOTE_CHEER);
|
||||||
|
|
||||||
|
if (sPlayerbotAIConfig->randomBotTalk && bot->GetGuildId() && urand(0, 10) && proto->Quality >= ITEM_QUALITY_RARE)
|
||||||
|
{
|
||||||
|
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
|
||||||
|
|
||||||
|
if (guild)
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string> placeholders;
|
||||||
|
placeholders["%name"] = chat->FormatItem(proto);
|
||||||
|
|
||||||
|
if (urand(0, 3))
|
||||||
|
guild->BroadcastToGuild(bot->GetSession(), false, BOT_TEXT2("Yay I looted %name!", placeholders), LANG_UNIVERSAL);
|
||||||
|
else
|
||||||
|
guild->BroadcastToGuild(bot->GetSession(), false, BOT_TEXT2("Guess who got a %name? Me!", placeholders), LANG_UNIVERSAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// std::ostringstream out;
|
// std::ostringstream out;
|
||||||
// out << "Looting " << chat->FormatItem(proto);
|
// out << "Looting " << chat->FormatItem(proto);
|
||||||
// botAI->TellMasterNoFacing(out.str());
|
// botAI->TellMasterNoFacing(out.str());
|
||||||
|
|||||||
@@ -1570,7 +1570,7 @@ bool AvoidAoeAction::AvoidAuraWithDynamicObj()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << spellInfo->SpellName[sWorld->GetDefaultDbcLocale()]; // << "] (aura)";
|
name << spellInfo->SpellName[LOCALE_enUS]; // << "] (aura)";
|
||||||
if (FleePosition(dynOwner->GetPosition(), radius)) {
|
if (FleePosition(dynOwner->GetPosition(), radius)) {
|
||||||
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
||||||
lastTellTimer = time(NULL);
|
lastTellTimer = time(NULL);
|
||||||
@@ -1628,7 +1628,7 @@ bool AvoidAoeAction::AvoidGameObjectWithDamage()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << spellInfo->SpellName[sWorld->GetDefaultDbcLocale()]; // << "] (object)";
|
name << spellInfo->SpellName[LOCALE_enUS]; // << "] (object)";
|
||||||
if (FleePosition(go->GetPosition(), radius)) {
|
if (FleePosition(go->GetPosition(), radius)) {
|
||||||
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
||||||
lastTellTimer = time(NULL);
|
lastTellTimer = time(NULL);
|
||||||
@@ -1677,7 +1677,7 @@ bool AvoidAoeAction::AvoidUnitWithDamageAura()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::ostringstream name;
|
std::ostringstream name;
|
||||||
name << triggerSpellInfo->SpellName[sWorld->GetDefaultDbcLocale()]; //<< "] (unit)";
|
name << triggerSpellInfo->SpellName[LOCALE_enUS]; //<< "] (unit)";
|
||||||
if (FleePosition(unit->GetPosition(), radius)) {
|
if (FleePosition(unit->GetPosition(), radius)) {
|
||||||
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
if (sPlayerbotAIConfig->tellWhenAvoidAoe && lastTellTimer < time(NULL) - 10) {
|
||||||
lastTellTimer = time(NULL);
|
lastTellTimer = time(NULL);
|
||||||
|
|||||||
@@ -10,6 +10,16 @@
|
|||||||
#include "GuildMgr.h"
|
#include "GuildMgr.h"
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
static const std::unordered_set<std::string> noReplyMsgs = {
|
||||||
|
"join", "leave", "follow", "attack", "pull", "flee", "reset", "reset ai",
|
||||||
|
"all ?", "talents", "talents list", "talents auto", "talk", "stay", "stats",
|
||||||
|
"who", "items", "leave", "join", "repair", "summon", "nc ?", "co ?", "de ?",
|
||||||
|
"dead ?", "follow", "los", "guard", "do accept invitation", "stats", "react ?",
|
||||||
|
"reset strats", "home",
|
||||||
|
};
|
||||||
|
static const std::unordered_set<std::string> noReplyMsgParts = { "+", "-","@" , "follow target", "focus heal", "cast ", "accept [", "e [", "destroy [", "go zone" };
|
||||||
|
static const std::unordered_set<std::string> noReplyMsgStarts = { "e ", "accept ", "cast ", "destroy " };
|
||||||
|
|
||||||
SayAction::SayAction(PlayerbotAI* botAI) : Action(botAI, "say"), Qualified()
|
SayAction::SayAction(PlayerbotAI* botAI) : Action(botAI, "say"), Qualified()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -105,6 +115,9 @@ bool SayAction::isUseful()
|
|||||||
if (!botAI->AllowActivity())
|
if (!botAI->AllowActivity())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (botAI->HasStrategy("silent", BotState::BOT_STATE_NON_COMBAT))
|
||||||
|
return false;
|
||||||
|
|
||||||
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
||||||
return (time(nullptr) - lastSaid) > 30;
|
return (time(nullptr) - lastSaid) > 30;
|
||||||
}
|
}
|
||||||
@@ -114,6 +127,35 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
|||||||
ChatReplyType replyType = REPLY_NOT_UNDERSTAND; // default not understand
|
ChatReplyType replyType = REPLY_NOT_UNDERSTAND; // default not understand
|
||||||
std::string respondsText = "";
|
std::string respondsText = "";
|
||||||
|
|
||||||
|
// if we're just commanding bots around, don't respond...
|
||||||
|
// first one is for exact word matches
|
||||||
|
if (noReplyMsgs.find(msg) != noReplyMsgs.end()) {
|
||||||
|
/*std::ostringstream out;
|
||||||
|
out << "DEBUG ChatReplyDo decided to ignore exact blocklist match" << msg;
|
||||||
|
bot->Say(out.str(), LANG_UNIVERSAL);*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// second one is for partial matches like + or - where we change strats
|
||||||
|
if (std::any_of(noReplyMsgParts.begin(), noReplyMsgParts.end(), [&msg](const std::string& part) { return msg.find(part) != std::string::npos; })) {
|
||||||
|
/*std::ostringstream out;
|
||||||
|
out << "DEBUG ChatReplyDo decided to ignore partial blocklist match" << msg;
|
||||||
|
bot->Say(out.str(), LANG_UNIVERSAL);*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::any_of(noReplyMsgStarts.begin(), noReplyMsgStarts.end(), [&msg](const std::string& start) {
|
||||||
|
return msg.find(start) == 0; // Check if the start matches the beginning of msg
|
||||||
|
})) {
|
||||||
|
/*std::ostringstream out;
|
||||||
|
out << "DEBUG ChatReplyDo decided to ignore start blocklist match" << msg;
|
||||||
|
bot->Say(out.str(), LANG_UNIVERSAL);*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectGuid receiver = sCharacterCache->GetCharacterGuidByName(name);
|
||||||
|
Player* plr = ObjectAccessor::FindPlayer(receiver);
|
||||||
|
|
||||||
// Chat Logic
|
// Chat Logic
|
||||||
int32 verb_pos = -1;
|
int32 verb_pos = -1;
|
||||||
int32 verb_type = -1;
|
int32 verb_type = -1;
|
||||||
@@ -149,18 +191,16 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
|||||||
// Responds
|
// Responds
|
||||||
for (uint32 i = 0; i < 8; i++)
|
for (uint32 i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
// // blame gm with chat tag
|
// blame gm with chat tag
|
||||||
// if (Player* plr = sObjectMgr->GetPlayer(ObjectGuid(HIGHGUID_PLAYER, guid1)))
|
if (plr && plr->isGMChat())
|
||||||
// {
|
{
|
||||||
// if (plr->isGMChat())
|
replyType = REPLY_ADMIN_ABUSE;
|
||||||
// {
|
found = true;
|
||||||
// replyType = REPLY_ADMIN_ABUSE;
|
break;
|
||||||
// found = true;
|
}
|
||||||
// break;
|
|
||||||
// }
|
if (word[i] == "hi" || word[i] == "hey" || word[i] == "hello" || word[i] == "wazzup"
|
||||||
// }
|
|| word[i] == "salut" || word[i] == "plop" || word[i] == "yo")
|
||||||
//
|
|
||||||
if (word[i] == "hi" || word[i] == "hey" || word[i] == "hello" || word[i] == "wazzup")
|
|
||||||
{
|
{
|
||||||
replyType = REPLY_HELLO;
|
replyType = REPLY_HELLO;
|
||||||
found = true;
|
found = true;
|
||||||
@@ -169,22 +209,25 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
|||||||
|
|
||||||
if (verb_type < 4)
|
if (verb_type < 4)
|
||||||
{
|
{
|
||||||
if (word[i] == "am" || word[i] == "are" || word[i] == "is")
|
if (word[i] == "am" || word[i] == "are" || word[i] == "is" || word[i] == "suis" || word[i] == "as" || word[i] == "est"
|
||||||
|
|| word[i] == "dois" || word[i] == "doit")
|
||||||
{
|
{
|
||||||
verb_pos = i;
|
verb_pos = i;
|
||||||
verb_type = 2; // present
|
verb_type = 2; // present
|
||||||
|
if (verb_pos == 0)
|
||||||
|
is_quest = 1;
|
||||||
}
|
}
|
||||||
else if (word[i] == "will")
|
else if (word[i] == "will" || word[i] == "vais" || word[i] == "sera")
|
||||||
{
|
{
|
||||||
verb_pos = i;
|
verb_pos = i;
|
||||||
verb_type = 3; // future
|
verb_type = 3; // future
|
||||||
}
|
}
|
||||||
else if (word[i] == "was" || word[i] == "were")
|
else if (word[i] == "was" || word[i] == "were" || word[i] == "été" || word[i] == "ai" || word[i] == "eu" || word[i] == "étions" || word[i] == "etion" )
|
||||||
{
|
{
|
||||||
verb_pos = i;
|
verb_pos = i;
|
||||||
verb_type = 1; // past
|
verb_type = 1; // past
|
||||||
}
|
}
|
||||||
else if (word[i] == "shut" || word[i] == "noob")
|
else if (word[i] == "shut" || word[i] == "noob" || word[i] == "tg")
|
||||||
{
|
{
|
||||||
if (msg.find(bot->GetName()) == std::string::npos)
|
if (msg.find(bot->GetName()) == std::string::npos)
|
||||||
{
|
{
|
||||||
@@ -600,22 +643,20 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
|||||||
{
|
{
|
||||||
if (type == CHAT_MSG_WHISPER)
|
if (type == CHAT_MSG_WHISPER)
|
||||||
{
|
{
|
||||||
ObjectGuid receiver = sCharacterCache->GetCharacterGuidByName(name);
|
if (plr)
|
||||||
if (!receiver || !receiver.IsPlayer() || !ObjectAccessor::FindPlayer(receiver))
|
|
||||||
{
|
{
|
||||||
return;
|
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
||||||
}
|
{
|
||||||
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
bot->Whisper(c, LANG_COMMON, plr);
|
||||||
{
|
}
|
||||||
bot->Whisper(c, LANG_COMMON, ObjectAccessor::FindPlayer(receiver));
|
else
|
||||||
}
|
{
|
||||||
else
|
bot->Whisper(c, LANG_ORCISH, plr);
|
||||||
{
|
}
|
||||||
bot->Whisper(c, LANG_ORCISH, ObjectAccessor::FindPlayer(receiver));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == CHAT_MSG_SAY)
|
else if (type == CHAT_MSG_SAY)
|
||||||
{
|
{
|
||||||
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
||||||
bot->Say(respondsText, LANG_COMMON);
|
bot->Say(respondsText, LANG_COMMON);
|
||||||
@@ -623,7 +664,7 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
|||||||
bot->Say(respondsText, LANG_ORCISH);
|
bot->Say(respondsText, LANG_ORCISH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == CHAT_MSG_YELL)
|
else if (type == CHAT_MSG_YELL)
|
||||||
{
|
{
|
||||||
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
if (bot->GetTeamId() == TEAM_ALLIANCE)
|
||||||
bot->Yell(respondsText, LANG_COMMON);
|
bot->Yell(respondsText, LANG_COMMON);
|
||||||
@@ -631,7 +672,7 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
|||||||
bot->Yell(respondsText, LANG_ORCISH);
|
bot->Yell(respondsText, LANG_ORCISH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == CHAT_MSG_GUILD)
|
else if (type == CHAT_MSG_GUILD)
|
||||||
{
|
{
|
||||||
if (!bot->GetGuildId())
|
if (!bot->GetGuildId())
|
||||||
return;
|
return;
|
||||||
@@ -645,4 +686,4 @@ void ChatReplyAction::ChatReplyDo(Player* bot, uint32 type, uint32 guid1, uint32
|
|||||||
}
|
}
|
||||||
GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<time_t>("last said", "chat")->Set(time(nullptr) + urand(5, 25));
|
GET_PLAYERBOT_AI(bot)->GetAiObjectContext()->GetValue<time_t>("last said", "chat")->Set(time(nullptr) + urand(5, 25));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SuggestWhatToDoAction.h"
|
#include "SuggestWhatToDoAction.h"
|
||||||
|
#include "ServerFacade.h"
|
||||||
#include "ChannelMgr.h"
|
#include "ChannelMgr.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "ItemVisitors.h"
|
#include "ItemVisitors.h"
|
||||||
@@ -11,24 +12,47 @@
|
|||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
#include "PlayerbotTextMgr.h"
|
#include "PlayerbotTextMgr.h"
|
||||||
#include "GuildMgr.h"
|
#include "GuildMgr.h"
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
std::map<std::string, uint8> SuggestWhatToDoAction::instances;
|
#include <functional>
|
||||||
|
|
||||||
|
enum eTalkType
|
||||||
|
{
|
||||||
|
General = ChannelFlags::CHANNEL_FLAG_GENERAL | ChannelFlags::CHANNEL_FLAG_NOT_LFG,
|
||||||
|
Trade = ChannelFlags::CHANNEL_FLAG_CITY | ChannelFlags::CHANNEL_FLAG_GENERAL | ChannelFlags::CHANNEL_FLAG_NOT_LFG | ChannelFlags::CHANNEL_FLAG_TRADE,
|
||||||
|
LocalDefence = ChannelFlags::CHANNEL_FLAG_GENERAL | ChannelFlags::CHANNEL_FLAG_NOT_LFG,
|
||||||
|
GuildRecruitment = ChannelFlags::CHANNEL_FLAG_CITY | ChannelFlags::CHANNEL_FLAG_GENERAL | ChannelFlags::CHANNEL_FLAG_NOT_LFG,
|
||||||
|
LookingForGroup = ChannelFlags::CHANNEL_FLAG_LFG | ChannelFlags::CHANNEL_FLAG_GENERAL
|
||||||
|
};
|
||||||
|
|
||||||
|
std::map<std::string, uint8> SuggestDungeonAction::instances;
|
||||||
std::map<std::string, uint8> SuggestWhatToDoAction::factions;
|
std::map<std::string, uint8> SuggestWhatToDoAction::factions;
|
||||||
|
|
||||||
SuggestWhatToDoAction::SuggestWhatToDoAction(PlayerbotAI* botAI, std::string const name) : InventoryAction(botAI, name)
|
SuggestWhatToDoAction::SuggestWhatToDoAction(PlayerbotAI* botAI, std::string const name)
|
||||||
|
: InventoryAction{ botAI, name }
|
||||||
|
, _dbc_locale{ sWorld->GetDefaultDbcLocale() }
|
||||||
{
|
{
|
||||||
suggestions.push_back(&SuggestWhatToDoAction::specificQuest);
|
suggestions.push_back(std::bind(&SuggestWhatToDoAction::specificQuest, this));
|
||||||
suggestions.push_back(&SuggestWhatToDoAction::grindReputation);
|
suggestions.push_back(std::bind(&SuggestWhatToDoAction::grindReputation, this));
|
||||||
suggestions.push_back(&SuggestWhatToDoAction::something);
|
suggestions.push_back(std::bind(&SuggestWhatToDoAction::something, this));
|
||||||
|
suggestions.push_back(std::bind(&SuggestWhatToDoAction::grindMaterials, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SuggestWhatToDoAction::Execute(Event event)
|
bool SuggestWhatToDoAction::isUseful()
|
||||||
{
|
{
|
||||||
if (!sRandomPlayerbotMgr->IsRandomBot(bot) || bot->GetGroup() || bot->GetInstanceId())
|
if (!sRandomPlayerbotMgr->IsRandomBot(bot) || bot->GetGroup() || bot->GetInstanceId())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
std::string qualifier = "suggest what to do";
|
||||||
|
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
||||||
|
return (time(0) - lastSaid) > 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SuggestWhatToDoAction::Execute(Event event)
|
||||||
|
{
|
||||||
uint32 index = rand() % suggestions.size();
|
uint32 index = rand() % suggestions.size();
|
||||||
(this->*suggestions[index])();
|
auto fnct_ptr = suggestions[index];
|
||||||
|
fnct_ptr();
|
||||||
|
|
||||||
std::string const qualifier = "suggest what to do";
|
std::string const qualifier = "suggest what to do";
|
||||||
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
||||||
@@ -37,73 +61,6 @@ bool SuggestWhatToDoAction::Execute(Event event)
|
|||||||
return true;
|
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> SuggestWhatToDoAction::GetIncompletedQuests()
|
||||||
{
|
{
|
||||||
std::vector<uint32> result;
|
std::vector<uint32> result;
|
||||||
@@ -136,7 +93,52 @@ void SuggestWhatToDoAction::specificQuest()
|
|||||||
placeholders["%role"] = chat->FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
placeholders["%role"] = chat->FormatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
||||||
placeholders["%quest"] = chat->FormatQuest(quest);
|
placeholders["%quest"] = chat->FormatQuest(quest);
|
||||||
|
|
||||||
spam(BOT_TEXT2("suggest_quest", placeholders), urand(0, 1) ? 0x18 : 0, urand(0, 2), urand(0, 2));
|
spam(BOT_TEXT2("suggest_quest", placeholders), urand(0, 1) ? eTalkType::General : 0, urand(0, 2), urand(0, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuggestWhatToDoAction::grindMaterials()
|
||||||
|
{
|
||||||
|
/*if (bot->GetLevel() <= 5)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto result = CharacterDatabase.Query("SELECT distinct category, multiplier FROM ahbot_category where category not in ('other', 'quest', 'trade', 'reagent') and multiplier > 3 order by multiplier desc limit 10");
|
||||||
|
if (!result)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::map<std::string, double> categories;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Field* fields = result->Fetch();
|
||||||
|
categories[fields[0].Get<std::string>()] = fields[1].Get<float>();
|
||||||
|
} while (result->NextRow());
|
||||||
|
|
||||||
|
for (std::map<std::string, double>::iterator i = categories.begin(); i != categories.end(); ++i)
|
||||||
|
{
|
||||||
|
if (urand(0, 10) < 3) {
|
||||||
|
std::string name = i->first;
|
||||||
|
double multiplier = i->second;
|
||||||
|
|
||||||
|
for (int j = 0; j < ahbot::CategoryList::instance.size(); j++)
|
||||||
|
{
|
||||||
|
ahbot::Category* category = ahbot::CategoryList::instance[j];
|
||||||
|
if (name == category->GetName())
|
||||||
|
{
|
||||||
|
std::string item = category->GetLabel();
|
||||||
|
transform(item.begin(), item.end(), item.begin(), ::tolower);
|
||||||
|
std::ostringstream itemout;
|
||||||
|
itemout << "|c0000b000" << item << "|r";
|
||||||
|
item = itemout.str();
|
||||||
|
|
||||||
|
std::map<std::string, std::string> placeholders;
|
||||||
|
placeholders["%role"] = chat->formatClass(bot, AiFactory::GetPlayerSpecTab(bot));
|
||||||
|
placeholders["%category"] = item;
|
||||||
|
|
||||||
|
spam(BOT_TEXT2("suggest_trade", placeholders), urand(0, 1) ? 0x3C : 0x18, !urand(0, 2), !urand(0, 3));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuggestWhatToDoAction::grindReputation()
|
void SuggestWhatToDoAction::grindReputation()
|
||||||
@@ -185,12 +187,11 @@ void SuggestWhatToDoAction::grindReputation()
|
|||||||
levels.push_back("exalted");
|
levels.push_back("exalted");
|
||||||
|
|
||||||
std::vector<std::string> allowedFactions;
|
std::vector<std::string> allowedFactions;
|
||||||
for (std::map<std::string, uint8>::iterator i = factions.begin(); i != factions.end(); ++i)
|
for (const auto& i : factions)
|
||||||
{
|
{
|
||||||
if (bot->GetLevel() >= i->second)
|
if (bot->GetLevel() >= i.second)
|
||||||
allowedFactions.push_back(i->first);
|
allowedFactions.push_back(i.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowedFactions.empty())
|
if (allowedFactions.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -207,7 +208,7 @@ void SuggestWhatToDoAction::grindReputation()
|
|||||||
itemout << allowedFactions[urand(0, allowedFactions.size() - 1)];
|
itemout << allowedFactions[urand(0, allowedFactions.size() - 1)];
|
||||||
placeholders["%faction"] = itemout.str();
|
placeholders["%faction"] = itemout.str();
|
||||||
|
|
||||||
spam(BOT_TEXT2("suggest_faction", placeholders), 0x18, true);
|
spam(BOT_TEXT2("suggest_faction", placeholders), eTalkType::General, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuggestWhatToDoAction::something()
|
void SuggestWhatToDoAction::something()
|
||||||
@@ -221,10 +222,10 @@ void SuggestWhatToDoAction::something()
|
|||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
// out << "|cffb04040" << entry->area_name[0] << "|r";
|
// out << "|cffb04040" << entry->area_name[0] << "|r";
|
||||||
out << entry->area_name[0];
|
out << entry->area_name[_dbc_locale];
|
||||||
placeholders["%zone"] = out.str();
|
placeholders["%zone"] = out.str();
|
||||||
|
|
||||||
spam(BOT_TEXT2("suggest_something", placeholders), urand(0, 1) ? 0x18 : 0, urand(0, 2), urand(0, 2));
|
spam(BOT_TEXT2("suggest_something", placeholders), urand(0, 1) ? eTalkType::General : 0, urand(0, 2), urand(0, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuggestWhatToDoAction::spam(std::string msg, uint8 flags, bool worldChat, bool guild)
|
void SuggestWhatToDoAction::spam(std::string msg, uint8 flags, bool worldChat, bool guild)
|
||||||
@@ -237,58 +238,63 @@ void SuggestWhatToDoAction::spam(std::string msg, uint8 flags, bool worldChat, b
|
|||||||
if (!cMgr)
|
if (!cMgr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
|
||||||
{
|
{
|
||||||
ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i);
|
ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i);
|
||||||
if (!channel) continue;
|
if (!channel) continue;
|
||||||
|
|
||||||
for (AreaTableEntry const* current_zone : sAreaTableStore)
|
AreaTableEntry const* current_zone = GetAreaEntryByAreaID(bot->GetAreaId());
|
||||||
|
if (!current_zone)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// combine full channel name
|
||||||
|
char channelName[100];
|
||||||
|
Channel* chn = nullptr;
|
||||||
|
if ((channel->flags & CHANNEL_DBC_FLAG_LFG) != 0)
|
||||||
{
|
{
|
||||||
if (!current_zone)
|
std::string chanName = channel->pattern[_dbc_locale];
|
||||||
continue;
|
chn = cMgr->GetChannel(chanName, bot);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
snprintf(channelName, 100, channel->pattern[_dbc_locale], current_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;
|
||||||
|
|
||||||
// combine full channel name
|
// skip local defense
|
||||||
char channelName[100];
|
if (chn->GetChannelId() == 22)
|
||||||
Channel* chn = nullptr;
|
continue;
|
||||||
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;
|
|
||||||
|
|
||||||
if (flags != 0 && chn->GetFlags() != flags)
|
// no filter, pick several options
|
||||||
continue;
|
if (flags == CHANNEL_FLAG_NONE)
|
||||||
|
{
|
||||||
// skip local defense
|
channelNames.push_back(chn->GetName());
|
||||||
//if (chn->GetFlags() == 0x18)
|
}
|
||||||
// continue;
|
else
|
||||||
|
{
|
||||||
// no filter, pick several options
|
if (!bot->IsInChannel(chn))
|
||||||
if (flags == CHANNEL_FLAG_NONE)
|
chn->JoinChannel(bot, "");
|
||||||
{
|
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())
|
if (!channelNames.empty())
|
||||||
{
|
{
|
||||||
std::string randomName = channelNames[urand(0, channelNames.size() - 1)];
|
std::string randomName = channelNames[urand(0, channelNames.size() - 1)];
|
||||||
if (Channel* chn = cMgr->GetChannel(randomName, bot))
|
if (Channel* chn = cMgr->GetChannel(randomName, bot))
|
||||||
|
{
|
||||||
|
if (!bot->IsInChannel(chn))
|
||||||
|
chn->JoinChannel(bot, "");
|
||||||
|
|
||||||
chn->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
chn->Say(bot->GetGUID(), msg.c_str(), LANG_UNIVERSAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (worldChat)
|
if (worldChat)
|
||||||
@@ -337,6 +343,80 @@ class FindTradeItemsVisitor : public IterateItemsVisitor
|
|||||||
uint32 quality;
|
uint32 quality;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
SuggestDungeonAction::SuggestDungeonAction(PlayerbotAI* botAI) : SuggestWhatToDoAction(botAI, "suggest dungeon")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SuggestDungeonAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
// TODO: use sPlayerbotDungeonSuggestionMgr
|
||||||
|
|
||||||
|
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 (const auto& instance : instances)
|
||||||
|
{
|
||||||
|
if (bot->GetLevel() >= instance.second)
|
||||||
|
allowedInstances.push_back(instance.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, 2));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
SuggestTradeAction::SuggestTradeAction(PlayerbotAI* botAI) : SuggestWhatToDoAction(botAI, "suggest trade")
|
SuggestTradeAction::SuggestTradeAction(PlayerbotAI* botAI) : SuggestWhatToDoAction(botAI, "suggest trade")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -400,13 +480,6 @@ bool SuggestTradeAction::Execute(Event event)
|
|||||||
placeholders["%item"] = chat->FormatItem(proto, count);
|
placeholders["%item"] = chat->FormatItem(proto, count);
|
||||||
placeholders["%gold"] = chat->formatMoney(price);
|
placeholders["%gold"] = chat->formatMoney(price);
|
||||||
|
|
||||||
spam(BOT_TEXT2("suggest_sell", placeholders), urand(0, 1) ? 0x3C : 0, urand(0, 1), urand(0, 5));
|
spam(BOT_TEXT2("suggest_sell", placeholders), urand(0, 1) ? eTalkType::Trade : 0, urand(0, 1), urand(0, 5));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SuggestWhatToDoAction::isUseful()
|
|
||||||
{
|
|
||||||
std::string const qualifier = "suggest what to do";
|
|
||||||
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
|
|
||||||
return (time(nullptr) - lastSaid) > 30;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -18,19 +18,19 @@ class SuggestWhatToDoAction : public InventoryAction
|
|||||||
bool isUseful() override;
|
bool isUseful() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef void (SuggestWhatToDoAction::*Suggestion)();
|
using Suggestion = std::function<void()>;
|
||||||
std::vector<Suggestion> suggestions;
|
std::vector<Suggestion> suggestions;
|
||||||
void instance();
|
|
||||||
void specificQuest();
|
void specificQuest();
|
||||||
void grindReputation();
|
void grindReputation();
|
||||||
|
void grindMaterials();
|
||||||
void something();
|
void something();
|
||||||
void spam(std::string msg, uint8 flags = 0, bool worldChat = false, bool guild = false);
|
void spam(std::string msg, uint8 flags = 0, bool worldChat = false, bool guild = false);
|
||||||
|
|
||||||
std::vector<uint32> GetIncompletedQuests();
|
std::vector<uint32> GetIncompletedQuests();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::map<std::string, uint8> instances;
|
|
||||||
static std::map<std::string, uint8> factions;
|
static std::map<std::string, uint8> factions;
|
||||||
|
const int32_t _dbc_locale;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SuggestTradeAction : public SuggestWhatToDoAction
|
class SuggestTradeAction : public SuggestWhatToDoAction
|
||||||
@@ -42,4 +42,15 @@ class SuggestTradeAction : public SuggestWhatToDoAction
|
|||||||
bool isUseful() override { return true; }
|
bool isUseful() override { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SuggestDungeonAction : public SuggestWhatToDoAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SuggestDungeonAction(PlayerbotAI* botAI);
|
||||||
|
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
bool isUseful() override { return true; }
|
||||||
|
private:
|
||||||
|
static std::map<std::string, uint8> instances;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -138,4 +138,4 @@ bool TellExpectedDpsAction::Execute(Event event)
|
|||||||
float dps = AI_VALUE(float, "expected group dps");
|
float dps = AI_VALUE(float, "expected group dps");
|
||||||
botAI->TellMaster("Expected Group DPS: " + std::to_string(dps));
|
botAI->TellMaster("Expected Group DPS: " + std::to_string(dps));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "PlayerbotAIConfig.h"
|
#include "PlayerbotAIConfig.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
#include "GuildMgr.h"
|
||||||
|
|
||||||
bool XpGainAction::Execute(Event event)
|
bool XpGainAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
@@ -32,6 +33,25 @@ bool XpGainAction::Execute(Event event)
|
|||||||
p >> groupBonus; // 8 group bonus
|
p >> groupBonus; // 8 group bonus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sPlayerbotAIConfig->randomBotTalk && bot->GetGuildId() && urand(0, 10))
|
||||||
|
{
|
||||||
|
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> placeholders;
|
||||||
|
placeholders["%name"] = creature->GetName();
|
||||||
|
|
||||||
|
if (urand(0, 3))
|
||||||
|
guild->BroadcastToGuild(bot->GetSession(), false, BOT_TEXT2("Wow I just killed %name!", placeholders), LANG_UNIVERSAL);
|
||||||
|
else
|
||||||
|
guild->BroadcastToGuild(bot->GetSession(), false, BOT_TEXT2("Awesome that %name went down quickly!", placeholders), LANG_UNIVERSAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Unit* victim = nullptr;
|
Unit* victim = nullptr;
|
||||||
if (guid)
|
if (guid)
|
||||||
victim = botAI->GetUnit(guid);
|
victim = botAI->GetUnit(guid);
|
||||||
|
|||||||
@@ -7,22 +7,25 @@
|
|||||||
|
|
||||||
void EmoteStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
void EmoteStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||||
{
|
{
|
||||||
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("emote", 1.0f), nullptr)));
|
if (sPlayerbotAIConfig->randomBotEmote)
|
||||||
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)));
|
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("emote", 1.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("receive text emote", NextAction::array(0, new NextAction("emote", 10.0f), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("receive emote", NextAction::array(0, new NextAction("emote", 10.0f), nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sPlayerbotAIConfig->randomBotTalk)
|
||||||
|
{
|
||||||
|
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)));
|
||||||
|
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("talk", 1.0f), nullptr)));
|
||||||
|
}
|
||||||
|
|
||||||
if (sPlayerbotAIConfig->randomBotSuggestDungeons)
|
if (sPlayerbotAIConfig->randomBotSuggestDungeons)
|
||||||
{
|
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("suggest dungeon", 1.0f), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("random", NextAction::array(0, new NextAction("suggest dungeon", 1.0f), nullptr)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sPlayerbotAIConfig->enableGreet)
|
if (sPlayerbotAIConfig->enableGreet)
|
||||||
{
|
|
||||||
triggers.push_back(new TriggerNode("new player nearby", NextAction::array(0, new NextAction("greet", 1.0f), nullptr)));
|
triggers.push_back(new TriggerNode("new player nearby", NextAction::array(0, new NextAction("greet", 1.0f), nullptr)));
|
||||||
}
|
|
||||||
|
|
||||||
triggers.push_back(new TriggerNode("seldom", NextAction::array(0, new NextAction("talk", 1.0f), nullptr)));
|
|
||||||
triggers.push_back(new TriggerNode("receive text emote", NextAction::array(0, new NextAction("emote", 10.0f), nullptr)));
|
|
||||||
triggers.push_back(new TriggerNode("receive emote", NextAction::array(0, new NextAction("emote", 10.0f), nullptr)));
|
|
||||||
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("rpg mount anim", 1.0f), nullptr)));
|
triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("rpg mount anim", 1.0f), nullptr)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ uint32 VehicleSpellIdValue::Calculate()
|
|||||||
char firstSymbol = tolower(namepart[0]);
|
char firstSymbol = tolower(namepart[0]);
|
||||||
int spellLength = wnamepart.length();
|
int spellLength = wnamepart.length();
|
||||||
|
|
||||||
int loc = bot->GetSession()->GetSessionDbcLocale();
|
const int loc = LocaleConstant::LOCALE_enUS;
|
||||||
|
|
||||||
Creature* creature = vehicleBase->ToCreature();
|
Creature* creature = vehicleBase->ToCreature();
|
||||||
for (uint32 x = 0; x < MAX_CREATURE_SPELLS; ++x)
|
for (uint32 x = 0; x < MAX_CREATURE_SPELLS; ++x)
|
||||||
|
|||||||
Reference in New Issue
Block a user