Run clang-format

This commit is contained in:
Yunfan Li 2024-08-04 10:23:36 +08:00
parent 44da167492
commit 53611c9040
835 changed files with 35085 additions and 31861 deletions

View File

@ -1,28 +1,30 @@
/* /*
* 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. * 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 "AiFactory.h" #include "AiFactory.h"
#include "BattlegroundMgr.h" #include "BattlegroundMgr.h"
#include "DKAiObjectContext.h"
#include "DruidAiObjectContext.h"
#include "Engine.h"
#include "Group.h"
#include "HunterAiObjectContext.h"
#include "Item.h" #include "Item.h"
#include "MageAiObjectContext.h"
#include "PaladinAiObjectContext.h"
#include "PlayerbotAI.h" #include "PlayerbotAI.h"
#include "PlayerbotAIConfig.h" #include "PlayerbotAIConfig.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Engine.h"
#include "Group.h"
#include "DKAiObjectContext.h"
#include "PriestAiObjectContext.h" #include "PriestAiObjectContext.h"
#include "MageAiObjectContext.h" #include "RogueAiObjectContext.h"
#include "ShamanAiObjectContext.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "SpellInfo.h" #include "SpellInfo.h"
#include "SpellMgr.h" #include "SpellMgr.h"
#include "WarlockAiObjectContext.h" #include "WarlockAiObjectContext.h"
#include "WarriorAiObjectContext.h" #include "WarriorAiObjectContext.h"
#include "ShamanAiObjectContext.h"
#include "PaladinAiObjectContext.h"
#include "DruidAiObjectContext.h"
#include "HunterAiObjectContext.h"
#include "RogueAiObjectContext.h"
AiObjectContext* AiFactory::createAiObjectContext(Player* player, PlayerbotAI* botAI) AiObjectContext* AiFactory::createAiObjectContext(Player* player, PlayerbotAI* botAI)
{ {
@ -100,7 +102,8 @@ std::map<uint8, uint32> AiFactory::GetPlayerSpecTabs(Player* bot)
for (PlayerTalentMap::const_iterator i = talentMap.begin(); i != talentMap.end(); ++i) for (PlayerTalentMap::const_iterator i = talentMap.begin(); i != talentMap.end(); ++i)
{ {
uint32 spellId = i->first; uint32 spellId = i->first;
if ((bot->GetActiveSpecMask() & i->second->specMask) == 0) { if ((bot->GetActiveSpecMask() & i->second->specMask) == 0)
{
continue; continue;
} }
TalentSpellPos const* talentPos = GetTalentSpellPos(spellId); TalentSpellPos const* talentPos = GetTalentSpellPos(spellId);
@ -186,7 +189,8 @@ std::string AiFactory::GetPlayerSpecName(Player* player)
specName = "holy"; specName = "holy";
else else
specName = "disc"; specName = "disc";
; break; ;
break;
case CLASS_SHAMAN: case CLASS_SHAMAN:
if (tab == 2) if (tab == 2)
specName = "resto"; specName = "resto";
@ -286,11 +290,16 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
switch (player->getClass()) switch (player->getClass())
{ {
case CLASS_PRIEST: case CLASS_PRIEST:
if (tab == 2) { if (tab == 2)
{
engine->addStrategies("dps", "shadow debuff", "shadow aoe", nullptr); engine->addStrategies("dps", "shadow debuff", "shadow aoe", nullptr);
} else if (tab == PRIEST_TAB_DISIPLINE) { }
else if (tab == PRIEST_TAB_DISIPLINE)
{
engine->addStrategies("heal", nullptr); engine->addStrategies("heal", nullptr);
} else { }
else
{
engine->addStrategies("holy heal", nullptr); engine->addStrategies("holy heal", nullptr);
} }
@ -343,9 +352,12 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
engine->addStrategies("heal", "cure", "dps assist", nullptr); engine->addStrategies("heal", "cure", "dps assist", nullptr);
else else
{ {
if (player->GetLevel() >= 20 && !player->HasAura(16931)/*thick hide*/) { if (player->GetLevel() >= 20 && !player->HasAura(16931) /*thick hide*/)
{
engine->addStrategies("cat", "dps assist", nullptr); engine->addStrategies("cat", "dps assist", nullptr);
} else { }
else
{
engine->addStrategies("bear", "tank assist", nullptr); engine->addStrategies("bear", "tank assist", nullptr);
} }
} }
@ -355,9 +367,12 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
engine->addStrategy("dps debuff"); engine->addStrategy("dps debuff");
break; break;
case CLASS_ROGUE: case CLASS_ROGUE:
if (tab == ROGUE_TAB_ASSASSINATION) { if (tab == ROGUE_TAB_ASSASSINATION)
{
engine->addStrategies("melee", "dps assist", "aoe", /*"behind",*/ nullptr); engine->addStrategies("melee", "dps assist", "aoe", /*"behind",*/ nullptr);
} else { }
else
{
engine->addStrategies("dps", "dps assist", "aoe", /*"behind",*/ nullptr); engine->addStrategies("dps", "dps assist", "aoe", /*"behind",*/ nullptr);
} }
break; break;
@ -384,28 +399,37 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
engine->addStrategy("dps assist"); engine->addStrategy("dps assist");
engine->removeStrategy("threat"); engine->removeStrategy("threat");
// engine- // engine-
switch (player->getClass()) { switch (player->getClass())
case CLASS_PRIEST: { {
if (tab != PRIEST_TAB_SHADOW) { case CLASS_PRIEST:
{
if (tab != PRIEST_TAB_SHADOW)
{
engine->addStrategies("holy dps", "shadow debuff", "shadow aoe", nullptr); engine->addStrategies("holy dps", "shadow debuff", "shadow aoe", nullptr);
} }
break; break;
} }
case CLASS_DRUID: { case CLASS_DRUID:
if (tab == DRUID_TAB_RESTORATION) { {
if (tab == DRUID_TAB_RESTORATION)
{
engine->addStrategies("caster", "caster aoe", nullptr); engine->addStrategies("caster", "caster aoe", nullptr);
engine->addStrategy("caster debuff"); engine->addStrategy("caster debuff");
} }
break; break;
} }
case CLASS_SHAMAN: { case CLASS_SHAMAN:
if (tab == SHAMAN_TAB_RESTORATION) { {
if (tab == SHAMAN_TAB_RESTORATION)
{
engine->addStrategies("caster", "caster aoe", "bmana", nullptr); engine->addStrategies("caster", "caster aoe", "bmana", nullptr);
} }
break; break;
} }
case CLASS_PALADIN: { case CLASS_PALADIN:
if (tab == PALADIN_TAB_HOLY) { {
if (tab == PALADIN_TAB_HOLY)
{
engine->addStrategies("dps", "dps assist", "baoe", nullptr); engine->addStrategies("dps", "dps assist", "baoe", nullptr);
} }
break; break;
@ -447,7 +471,8 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
engine->addStrategy("arena"); engine->addStrategy("arena");
} }
engine->addStrategies("boost", "racials", "chat", "default", "aoe", "potions", "cast time", "dps assist", nullptr); engine->addStrategies("boost", "racials", "chat", "default", "aoe", "potions", "cast time", "dps assist",
nullptr);
engine->removeStrategy("custom::say"); engine->removeStrategy("custom::say");
engine->removeStrategy("flee"); engine->removeStrategy("flee");
engine->removeStrategy("threat"); engine->removeStrategy("threat");
@ -481,11 +506,15 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
nonCombatEngine->addStrategies("dps assist", "cure", nullptr); nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
break; break;
case CLASS_PALADIN: case CLASS_PALADIN:
if (tab == 1) { if (tab == 1)
{
nonCombatEngine->addStrategies("bthreat", "tank assist", "barmor", nullptr); nonCombatEngine->addStrategies("bthreat", "tank assist", "barmor", nullptr);
if (player->GetLevel() >= 20) { if (player->GetLevel() >= 20)
{
nonCombatEngine->addStrategy("bstats"); nonCombatEngine->addStrategy("bstats");
} else { }
else
{
nonCombatEngine->addStrategy("bdps"); nonCombatEngine->addStrategy("bdps");
} }
} }
@ -516,10 +545,14 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
nonCombatEngine->addStrategies("dps assist", "cure", nullptr); nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
break; break;
case CLASS_DRUID: case CLASS_DRUID:
if (tab == 1) { if (tab == 1)
if (player->GetLevel() >= 20 && !player->HasAura(16931)/*thick hide*/) { {
if (player->GetLevel() >= 20 && !player->HasAura(16931) /*thick hide*/)
{
nonCombatEngine->addStrategy("dps assist"); nonCombatEngine->addStrategy("dps assist");
} else { }
else
{
nonCombatEngine->addStrategy("tank assist"); nonCombatEngine->addStrategy("tank assist");
} }
} }
@ -533,11 +566,16 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
nonCombatEngine->addStrategy("dps assist"); nonCombatEngine->addStrategy("dps assist");
break; break;
case CLASS_WARLOCK: case CLASS_WARLOCK:
if (tab == WARLOCK_TAB_AFFLICATION) { if (tab == WARLOCK_TAB_AFFLICATION)
{
nonCombatEngine->addStrategies("bmana", nullptr); nonCombatEngine->addStrategies("bmana", nullptr);
} else if (tab == WARLOCK_TAB_DEMONOLOGY) { }
else if (tab == WARLOCK_TAB_DEMONOLOGY)
{
nonCombatEngine->addStrategies("bdps", nullptr); nonCombatEngine->addStrategies("bdps", nullptr);
} else if (tab == WARLOCK_TAB_DESTRUCTION) { }
else if (tab == WARLOCK_TAB_DESTRUCTION)
{
nonCombatEngine->addStrategies("bhealth", nullptr); nonCombatEngine->addStrategies("bhealth", nullptr);
} }
nonCombatEngine->addStrategies("dps assist", nullptr); nonCombatEngine->addStrategies("dps assist", nullptr);
@ -555,10 +593,11 @@ 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",
"default", "quest", "loot", "gather", "duel", "buff", "mount", "emote", nullptr); "buff", "mount", "emote", nullptr);
} }
if (sPlayerbotAIConfig->autoSaveMana) { if (sPlayerbotAIConfig->autoSaveMana)
{
nonCombatEngine->addStrategy("auto save mana"); nonCombatEngine->addStrategy("auto save mana");
} }
if ((sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground()) if ((sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground())
@ -588,7 +627,9 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
{ {
// nonCombatEngine->addStrategy("travel"); // nonCombatEngine->addStrategy("travel");
nonCombatEngine->addStrategy("rpg"); nonCombatEngine->addStrategy("rpg");
} else { }
else
{
nonCombatEngine->addStrategy("move random"); nonCombatEngine->addStrategy("move random");
} }
@ -627,7 +668,8 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->randomBotNonCombatStrategies); nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->randomBotNonCombatStrategies);
} }
else { else
{
nonCombatEngine->addStrategy("pvp"); nonCombatEngine->addStrategy("pvp");
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies); nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
} }
@ -644,7 +686,8 @@ 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", "emote", 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");
@ -654,7 +697,8 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
if (bgType == BATTLEGROUND_RB) if (bgType == BATTLEGROUND_RB)
bgType = player->GetBattleground()->GetBgTypeID(true); bgType = player->GetBattleground()->GetBgTypeID(true);
if ((bgType <= BATTLEGROUND_EY || bgType == BATTLEGROUND_IC) && !player->InArena()) // do not add for not supported bg or arena if ((bgType <= BATTLEGROUND_EY || bgType == BATTLEGROUND_IC) &&
!player->InArena()) // do not add for not supported bg or arena
nonCombatEngine->addStrategy("battleground"); nonCombatEngine->addStrategy("battleground");
if (bgType == BATTLEGROUND_WS) if (bgType == BATTLEGROUND_WS)

View File

@ -1,14 +1,15 @@
/* /*
* 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. * 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_AIFACTORY_H #ifndef _PLAYERBOT_AIFACTORY_H
#define _PLAYERBOT_AIFACTORY_H #define _PLAYERBOT_AIFACTORY_H
#include "Common.h"
#include <map> #include <map>
#include "Common.h"
class AiObjectContext; class AiObjectContext;
class Engine; class Engine;
class Player; class Player;

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "ChatFilter.h" #include "ChatFilter.h"
#include "Group.h" #include "Group.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "RtiTargetValue.h" #include "RtiTargetValue.h"
@ -295,4 +297,3 @@ std::string const CompositeChatFilter::Filter(std::string& message)
return message; return message;
} }

View File

@ -1,15 +1,16 @@
/* /*
* 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. * 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_CHATFILTER_H #ifndef _PLAYERBOT_CHATFILTER_H
#define _PLAYERBOT_CHATFILTER_H #define _PLAYERBOT_CHATFILTER_H
#include <vector>
#include "Common.h" #include "Common.h"
#include "PlayerbotAIAware.h" #include "PlayerbotAIAware.h"
#include <vector>
class PlayerbotAI; class PlayerbotAI;
class ChatFilter : public PlayerbotAIAware class ChatFilter : public PlayerbotAIAware

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "ChatHelper.h" #include "ChatHelper.h"
#include "AiFactory.h" #include "AiFactory.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "SpellInfo.h" #include "SpellInfo.h"
@ -281,22 +283,27 @@ ItemIds ChatHelper::parseItems(std::string const text)
std::string const ChatHelper::FormatQuest(Quest const* quest) std::string const ChatHelper::FormatQuest(Quest const* quest)
{ {
std::ostringstream out; std::ostringstream out;
out << "|cFFFFFF00|Hquest:" << quest->GetQuestId() << ':' << quest->GetQuestLevel() << "|h[" << quest->GetTitle() << "]|h|r"; out << "|cFFFFFF00|Hquest:" << quest->GetQuestId() << ':' << quest->GetQuestLevel() << "|h[" << quest->GetTitle()
<< "]|h|r";
return out.str(); return out.str();
} }
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(LOCALE_enUS) << "]|h|r"; out << "|cFFFFFF00|Hfound:" << go->GetGUID().GetRawValue() << ":" << go->GetEntry() << ":"
<< "|h[" << go->GetNameForLocaleIdx(LOCALE_enUS) << "]|h|r";
return out.str(); return out.str();
} }
std::string const ChatHelper::FormatWorldobject(WorldObject* wo) 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() << ":"
out << (wo->ToGameObject() ? ((GameObject*)wo)->GetNameForLocaleIdx(LOCALE_enUS) : wo->GetNameForLocaleIdx(LOCALE_enUS)) << "]|h|r"; << "|h[";
out << (wo->ToGameObject() ? ((GameObject*)wo)->GetNameForLocaleIdx(LOCALE_enUS)
: wo->GetNameForLocaleIdx(LOCALE_enUS))
<< "]|h|r";
return out.str(); return out.str();
} }
@ -311,7 +318,8 @@ std::string const ChatHelper::FormatWorldEntry(int32 entry)
gInfo = sObjectMgr->GetGameObjectTemplate(entry * -1); gInfo = sObjectMgr->GetGameObjectTemplate(entry * -1);
std::ostringstream out; std::ostringstream out;
out << "|cFFFFFF00|Hentry:" << abs(entry) << ":" << "|h["; out << "|cFFFFFF00|Hentry:" << abs(entry) << ":"
<< "|h[";
if (entry < 0 && gInfo) if (entry < 0 && gInfo)
out << gInfo->name; out << gInfo->name;
@ -339,9 +347,8 @@ std::string const ChatHelper::FormatItem(ItemTemplate const* proto, uint32 count
// const std::string &name = sObjectMgr->GetItemLocale(proto->ItemId)->Name[LOCALE_enUS]; // 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 << ":0:0:0:0:0:0:0"
<< ":0:0:0:0:0:0:0" << "|h[" << proto->Name1 << "|h[" << proto->Name1 << "]|h|r";
<< "]|h|r";
if (count > 1) if (count > 1)
out << "x" << count; out << "x" << count;
@ -392,7 +399,6 @@ std::string const ChatHelper::FormatChat(ChatMsg chat)
return "unknown"; return "unknown";
} }
uint32 ChatHelper::parseSpell(std::string const text) uint32 ChatHelper::parseSpell(std::string const text)
{ {
PlayerbotChatHandler handler(botAI->GetBot()); PlayerbotChatHandler handler(botAI->GetBot());
@ -444,8 +450,8 @@ GuidVector ChatHelper::parseGameobjects(std::string const text)
std::string const ChatHelper::FormatQuestObjective(std::string const name, uint32 available, uint32 required) std::string const ChatHelper::FormatQuestObjective(std::string const name, uint32 available, uint32 required)
{ {
std::ostringstream out; std::ostringstream out;
out << "|cFFFFFFFF" << name << (available >= required ? "|c0000FF00: " : "|c00FF0000: ") out << "|cFFFFFFFF" << name << (available >= required ? "|c0000FF00: " : "|c00FF0000: ") << available << "/"
<< available << "/" << required << "|r"; << required << "|r";
return out.str(); return out.str();
} }
@ -501,9 +507,11 @@ uint32 ChatHelper::parseSlot(std::string const text)
bool ChatHelper::parseable(std::string const text) bool ChatHelper::parseable(std::string const text)
{ {
return text.find("|H") != std::string::npos || text == "questitem" || text == "ammo" || substrContainsInMap<uint32>(text, consumableSubClasses) || return text.find("|H") != std::string::npos || text == "questitem" || text == "ammo" ||
substrContainsInMap<uint32>(text, tradeSubClasses) || substrContainsInMap<uint32>(text, itemQualities) || substrContainsInMap<uint32>(text, slots) || substrContainsInMap<uint32>(text, consumableSubClasses) ||
substrContainsInMap<ChatMsg>(text, chats) || substrContainsInMap<uint32>(text, skills) || parseMoney(text) > 0; substrContainsInMap<uint32>(text, tradeSubClasses) || substrContainsInMap<uint32>(text, itemQualities) ||
substrContainsInMap<uint32>(text, slots) || substrContainsInMap<ChatMsg>(text, chats) ||
substrContainsInMap<uint32>(text, skills) || parseMoney(text) > 0;
} }
std::string const ChatHelper::FormatClass(Player* player, int8 spec) std::string const ChatHelper::FormatClass(Player* player, int8 spec)
@ -526,15 +534,9 @@ std::string const ChatHelper::FormatClass(Player* player, int8 spec)
return out.str(); return out.str();
} }
std::string const ChatHelper::FormatClass(uint8 cls) std::string const ChatHelper::FormatClass(uint8 cls) { return classes[cls]; }
{
return classes[cls];
}
std::string const ChatHelper::FormatRace(uint8 race) std::string const ChatHelper::FormatRace(uint8 race) { return races[race]; }
{
return races[race];
}
uint32 ChatHelper::parseSkill(std::string const text) uint32 ChatHelper::parseSkill(std::string const text)
{ {
@ -555,10 +557,7 @@ std::string const ChatHelper::FormatSkill(uint32 skill)
return ""; return "";
} }
std::string const ChatHelper::FormatBoolean(bool flag) std::string const ChatHelper::FormatBoolean(bool flag) { return flag ? "|cff00ff00ON|r" : "|cffffff00OFF|r"; }
{
return flag ? "|cff00ff00ON|r" : "|cffffff00OFF|r";
}
void ChatHelper::eraseAllSubStr(std::string& mainStr, std::string const toErase) void ChatHelper::eraseAllSubStr(std::string& mainStr, std::string const toErase)
{ {

View File

@ -1,17 +1,18 @@
/* /*
* 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. * 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_CHATHELPER_H #ifndef _PLAYERBOT_CHATHELPER_H
#define _PLAYERBOT_CHATHELPER_H #define _PLAYERBOT_CHATHELPER_H
#include <map>
#include "Common.h" #include "Common.h"
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "PlayerbotAIAware.h" #include "PlayerbotAIAware.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include <map>
class GameObject; class GameObject;
class Quest; class Quest;
class Player; class Player;

View File

@ -1,13 +1,20 @@
/* /*
* 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. * 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 "FleeManager.h" #include "FleeManager.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "ServerFacade.h" #include "ServerFacade.h"
FleeManager::FleeManager(Player* bot, float maxAllowedDistance, float followAngle, bool forceMaxDistance, WorldPosition startPosition) : FleeManager::FleeManager(Player* bot, float maxAllowedDistance, float followAngle, bool forceMaxDistance,
bot(bot), maxAllowedDistance(maxAllowedDistance), followAngle(followAngle), forceMaxDistance(forceMaxDistance), startPosition(startPosition ? startPosition : WorldPosition(bot)) WorldPosition startPosition)
: bot(bot),
maxAllowedDistance(maxAllowedDistance),
followAngle(followAngle),
forceMaxDistance(forceMaxDistance),
startPosition(startPosition ? startPosition : WorldPosition(bot))
{ {
} }
@ -16,7 +23,8 @@ void FleeManager::calculateDistanceToCreatures(FleePoint *point)
point->minDistance = -1.0f; point->minDistance = -1.0f;
point->sumDistance = 0.0f; point->sumDistance = 0.0f;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return; return;
} }
GuidVector units = *botAI->GetAiObjectContext()->GetValue<GuidVector>("possible targets no los"); GuidVector units = *botAI->GetAiObjectContext()->GetValue<GuidVector>("possible targets no los");
@ -48,7 +56,8 @@ bool intersectsOri(float angle, std::vector<float>& angles, float angleIncrement
void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*>& points) void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*>& points)
{ {
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return; return;
} }
Unit* target = *botAI->GetAiObjectContext()->GetValue<Unit*>("current target"); Unit* target = *botAI->GetAiObjectContext()->GetValue<Unit*>("current target");
@ -72,19 +81,24 @@ void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*> &points)
enemyOri.push_back(ori); enemyOri.push_back(ori);
} }
float distIncrement = std::max(sPlayerbotAIConfig->followDistance, (maxAllowedDistance - sPlayerbotAIConfig->tooCloseDistance) / 10.0f); float distIncrement = std::max(sPlayerbotAIConfig->followDistance,
(maxAllowedDistance - sPlayerbotAIConfig->tooCloseDistance) / 10.0f);
for (float dist = maxAllowedDistance; dist >= sPlayerbotAIConfig->tooCloseDistance; dist -= distIncrement) for (float dist = maxAllowedDistance; dist >= sPlayerbotAIConfig->tooCloseDistance; dist -= distIncrement)
{ {
float angleIncrement = std::max(M_PI / 20, M_PI / 4 / (1.0 + dist - sPlayerbotAIConfig->tooCloseDistance)); float angleIncrement = std::max(M_PI / 20, M_PI / 4 / (1.0 + dist - sPlayerbotAIConfig->tooCloseDistance));
for (float add = 0.0f; add < M_PI / 4 + angleIncrement; add += angleIncrement) for (float add = 0.0f; add < M_PI / 4 + angleIncrement; add += angleIncrement)
{ {
for (float angle = add; angle < add + 2 * static_cast<float>(M_PI) + angleIncrement; angle += static_cast<float>(M_PI) / 4) for (float angle = add; angle < add + 2 * static_cast<float>(M_PI) + angleIncrement;
angle += static_cast<float>(M_PI) / 4)
{ {
if (intersectsOri(angle, enemyOri, angleIncrement)) if (intersectsOri(angle, enemyOri, angleIncrement))
continue; continue;
float x = botPosX + cos(angle) * maxAllowedDistance, y = botPosY + sin(angle) * maxAllowedDistance, z = botPosZ + CONTACT_DISTANCE; float x = botPosX + cos(angle) * maxAllowedDistance, y = botPosY + sin(angle) * maxAllowedDistance,
if (forceMaxDistance && sServerFacade->IsDistanceLessThan(sServerFacade->GetDistance2d(bot, x, y), maxAllowedDistance - sPlayerbotAIConfig->tooCloseDistance)) z = botPosZ + CONTACT_DISTANCE;
if (forceMaxDistance &&
sServerFacade->IsDistanceLessThan(sServerFacade->GetDistance2d(bot, x, y),
maxAllowedDistance - sPlayerbotAIConfig->tooCloseDistance))
continue; continue;
bot->UpdateAllowedPositionZ(x, y, z); bot->UpdateAllowedPositionZ(x, y, z);
@ -99,7 +113,8 @@ void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*> &points)
FleePoint* point = new FleePoint(botAI, x, y, z); FleePoint* point = new FleePoint(botAI, x, y, z);
calculateDistanceToCreatures(point); calculateDistanceToCreatures(point);
if (sServerFacade->IsDistanceGreaterOrEqualThan(point->minDistance - start.minDistance, sPlayerbotAIConfig->followDistance)) if (sServerFacade->IsDistanceGreaterOrEqualThan(point->minDistance - start.minDistance,
sPlayerbotAIConfig->followDistance))
points.push_back(point); points.push_back(point);
else else
delete point; delete point;
@ -159,7 +174,8 @@ bool FleeManager::CalculateDestination(float* rx, float* ry, float* rz)
bool FleeManager::isUseful() bool FleeManager::isUseful()
{ {
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return false; return false;
} }
GuidVector units = *botAI->GetAiObjectContext()->GetValue<GuidVector>("possible targets no los"); GuidVector units = *botAI->GetAiObjectContext()->GetValue<GuidVector>("possible targets no los");
@ -169,7 +185,8 @@ bool FleeManager::isUseful()
if (!creature) if (!creature)
continue; continue;
if (startPosition.sqDistance(WorldPosition(creature)) < creature->GetAttackDistance(bot) * creature->GetAttackDistance(bot)) if (startPosition.sqDistance(WorldPosition(creature)) <
creature->GetAttackDistance(bot) * creature->GetAttackDistance(bot))
return true; return true;
// float d = sServerFacade->GetDistance2d(unit, bot); // float d = sServerFacade->GetDistance2d(unit, bot);

View File

@ -1,22 +1,26 @@
/* /*
* 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. * 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_FLEEMANAGER_H #ifndef _PLAYERBOT_FLEEMANAGER_H
#define _PLAYERBOT_FLEEMANAGER_H #define _PLAYERBOT_FLEEMANAGER_H
#include <vector>
#include "Common.h" #include "Common.h"
#include "TravelMgr.h" #include "TravelMgr.h"
#include <vector>
class Player; class Player;
class PlayerbotAI; class PlayerbotAI;
class FleePoint class FleePoint
{ {
public: public:
FleePoint(PlayerbotAI* botAI, float x, float y, float z) : botAI(botAI), sumDistance(0.0f), minDistance(0.0f), x(x), y(y), z(z) { } FleePoint(PlayerbotAI* botAI, float x, float y, float z)
: botAI(botAI), sumDistance(0.0f), minDistance(0.0f), x(x), y(y), z(z)
{
}
float x; float x;
float y; float y;
@ -32,7 +36,8 @@ class FleePoint
class FleeManager class FleeManager
{ {
public: public:
FleeManager(Player* bot, float maxAllowedDistance, float followAngle, bool forceMaxDistance = false, WorldPosition startPosition = WorldPosition()); FleeManager(Player* bot, float maxAllowedDistance, float followAngle, bool forceMaxDistance = false,
WorldPosition startPosition = WorldPosition());
bool CalculateDestination(float* rx, float* ry, float* rz); bool CalculateDestination(float* rx, float* ry, float* rz);
bool isUseful(); bool isUseful();

View File

@ -1,15 +1,17 @@
/* /*
* 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. * 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 "GuildTaskMgr.h" #include "GuildTaskMgr.h"
#include "ChatHelper.h" #include "ChatHelper.h"
#include "GuildMgr.h"
#include "Group.h" #include "Group.h"
#include "GuildMgr.h"
#include "Mail.h" #include "Mail.h"
#include "MapMgr.h" #include "MapMgr.h"
#include "Playerbots.h"
#include "PlayerbotFactory.h" #include "PlayerbotFactory.h"
#include "Playerbots.h"
#include "RandomItemMgr.h" #include "RandomItemMgr.h"
#include "ServerFacade.h" #include "ServerFacade.h"
@ -46,9 +48,11 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
DenyReason reason = PLAYERBOT_DENY_NONE; DenyReason reason = PLAYERBOT_DENY_NONE;
PlayerbotSecurityLevel secLevel = masterBotAI->GetSecurity()->LevelFor(player, &reason); PlayerbotSecurityLevel secLevel = masterBotAI->GetSecurity()->LevelFor(player, &reason);
if (secLevel == PLAYERBOT_SECURITY_DENY_ALL || (secLevel == PLAYERBOT_SECURITY_TALK && reason != PLAYERBOT_DENY_FAR)) if (secLevel == PLAYERBOT_SECURITY_DENY_ALL ||
(secLevel == PLAYERBOT_SECURITY_TALK && reason != PLAYERBOT_DENY_FAR))
{ {
LOG_DEBUG("playerbots", "{} / {}: skipping guild task update - not enough security level, reason = {}", guild->GetName().c_str(), player->GetName().c_str(), reason); LOG_DEBUG("playerbots", "{} / {}: skipping guild task update - not enough security level, reason = {}",
guild->GetName().c_str(), player->GetName().c_str(), reason);
return; return;
} }
@ -72,14 +76,18 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
if (task == GUILD_TASK_TYPE_NONE) if (task == GUILD_TASK_TYPE_NONE)
{ {
LOG_ERROR("playerbots", "{} / {}: error creating guild task", guild->GetName().c_str(), player->GetName().c_str()); LOG_ERROR("playerbots", "{} / {}: error creating guild task", guild->GetName().c_str(),
player->GetName().c_str());
} }
uint32 time = urand(sPlayerbotAIConfig->minGuildTaskChangeTime, sPlayerbotAIConfig->maxGuildTaskChangeTime); uint32 time = urand(sPlayerbotAIConfig->minGuildTaskChangeTime, sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "activeTask", task, time); SetTaskValue(owner, guildId, "activeTask", task, time);
SetTaskValue(owner, guildId, "advertisement", 1, urand(sPlayerbotAIConfig->minGuildTaskAdvertisementTime, sPlayerbotAIConfig->maxGuildTaskAdvertisementTime)); SetTaskValue(owner, guildId, "advertisement", 1,
urand(sPlayerbotAIConfig->minGuildTaskAdvertisementTime,
sPlayerbotAIConfig->maxGuildTaskAdvertisementTime));
LOG_DEBUG("playerbots", "{} / {}: guild task {} is set for {} secs", guild->GetName().c_str(), player->GetName().c_str(), task, time); LOG_DEBUG("playerbots", "{} / {}: guild task {} is set for {} secs", guild->GetName().c_str(),
player->GetName().c_str(), task, time);
return; return;
} }
@ -92,11 +100,14 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
if (SendAdvertisement(trans, owner, guildId)) if (SendAdvertisement(trans, owner, guildId))
{ {
SetTaskValue(owner, guildId, "advertisement", 1, urand(sPlayerbotAIConfig->minGuildTaskAdvertisementTime, sPlayerbotAIConfig->maxGuildTaskAdvertisementTime)); SetTaskValue(owner, guildId, "advertisement", 1,
urand(sPlayerbotAIConfig->minGuildTaskAdvertisementTime,
sPlayerbotAIConfig->maxGuildTaskAdvertisementTime));
} }
else else
{ {
LOG_DEBUG("playerbots", "{} / {}: error sending advertisement", guild->GetName().c_str(), player->GetName().c_str()); LOG_DEBUG("playerbots", "{} / {}: error sending advertisement", guild->GetName().c_str(),
player->GetName().c_str());
} }
} }
@ -112,7 +123,8 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
} }
else else
{ {
LOG_DEBUG("playerbots", "{} / {}: error sending thanks", guild->GetName().c_str(), player->GetName().c_str()); LOG_DEBUG("playerbots", "{} / {}: error sending thanks", guild->GetName().c_str(),
player->GetName().c_str());
} }
} }
@ -128,7 +140,8 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
} }
else else
{ {
LOG_DEBUG("playerbots", "{} / {}: error sending reward", guild->GetName().c_str(), player->GetName().c_str()); LOG_DEBUG("playerbots", "{} / {}: error sending reward", guild->GetName().c_str(),
player->GetName().c_str());
} }
} }
@ -180,16 +193,20 @@ bool GuildTaskMgr::CreateItemTask(Player* player, uint32 guildId)
uint32 itemId = sRandomItemMgr->GetRandomItem(player->GetLevel() - 5, RANDOM_ITEM_GUILD_TASK, &predicate); uint32 itemId = sRandomItemMgr->GetRandomItem(player->GetLevel() - 5, RANDOM_ITEM_GUILD_TASK, &predicate);
if (!itemId) if (!itemId)
{ {
LOG_ERROR("playerbots", "{} / {}: no items avaible for item task", sGuildMgr->GetGuildById(guildId)->GetName().c_str(), player->GetName().c_str()); LOG_ERROR("playerbots", "{} / {}: no items avaible for item task",
sGuildMgr->GetGuildById(guildId)->GetName().c_str(), player->GetName().c_str());
return false; return false;
} }
uint32 count = GetMaxItemTaskCount(itemId); uint32 count = GetMaxItemTaskCount(itemId);
LOG_DEBUG("playerbots", "{} / {}: item task {} (x{})", sGuildMgr->GetGuildById(guildId)->GetName().c_str(), player->GetName().c_str(), itemId, count); LOG_DEBUG("playerbots", "{} / {}: item task {} (x{})", sGuildMgr->GetGuildById(guildId)->GetName().c_str(),
player->GetName().c_str(), itemId, count);
SetTaskValue(player->GetGUID().GetCounter(), guildId, "itemCount", count, sPlayerbotAIConfig->maxGuildTaskChangeTime); SetTaskValue(player->GetGUID().GetCounter(), guildId, "itemCount", count,
SetTaskValue(player->GetGUID().GetCounter(), guildId, "itemTask", itemId, sPlayerbotAIConfig->maxGuildTaskChangeTime); sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(player->GetGUID().GetCounter(), guildId, "itemTask", itemId,
sPlayerbotAIConfig->maxGuildTaskChangeTime);
return true; return true;
} }
@ -204,8 +221,10 @@ bool GuildTaskMgr::CreateKillTask(Player* player, uint32 guildId)
std::vector<uint32> ids; std::vector<uint32> ids;
uint32 level = player->GetLevel(); uint32 level = player->GetLevel();
QueryResult results = WorldDatabase.Query("SELECT ct.Entry, c.map, c.position_x, c.position_y, ct.Name FROM creature_template ct " QueryResult results = WorldDatabase.Query(
"JOIN creature c ON ct.Entry = c.id1 WHERE ct.MaxLevel < {} AND ct.MinLevel > {} AND ct.Rank = {} ", level + 4, level - 3, rank); "SELECT ct.Entry, c.map, c.position_x, c.position_y, ct.Name FROM creature_template ct "
"JOIN creature c ON ct.Entry = c.id1 WHERE ct.MaxLevel < {} AND ct.MinLevel > {} AND ct.Rank = {} ",
level + 4, level - 3, rank);
if (results) if (results)
{ {
do do
@ -231,16 +250,19 @@ bool GuildTaskMgr::CreateKillTask(Player* player, uint32 guildId)
if (ids.empty()) if (ids.empty())
{ {
LOG_ERROR("playerbots", "{} / {}: no rare creatures available for kill task", sGuildMgr->GetGuildById(guildId)->GetName().c_str(), player->GetName().c_str()); LOG_ERROR("playerbots", "{} / {}: no rare creatures available for kill task",
sGuildMgr->GetGuildById(guildId)->GetName().c_str(), player->GetName().c_str());
return false; return false;
} }
uint32 index = urand(0, ids.size() - 1); uint32 index = urand(0, ids.size() - 1);
uint32 creatureId = ids[index]; uint32 creatureId = ids[index];
LOG_DEBUG("playerbots", "{} / {}: kill task {}", sGuildMgr->GetGuildById(guildId)->GetName().c_str(), player->GetName().c_str(), creatureId); LOG_DEBUG("playerbots", "{} / {}: kill task {}", sGuildMgr->GetGuildById(guildId)->GetName().c_str(),
player->GetName().c_str(), creatureId);
SetTaskValue(player->GetGUID().GetCounter(), guildId, "killTask", creatureId, sPlayerbotAIConfig->maxGuildTaskChangeTime); SetTaskValue(player->GetGUID().GetCounter(), guildId, "killTask", creatureId,
sPlayerbotAIConfig->maxGuildTaskChangeTime);
return true; return true;
} }
@ -283,7 +305,8 @@ std::string const formatTime(uint32 secs)
else if (secs < 3600 * 24) else if (secs < 3600 * 24)
{ {
out << secs / 3600 << " hr"; out << secs / 3600 << " hr";
} else }
else
{ {
out << secs / 3600 / 24 << " days"; out << secs / 3600 / 24 << " days";
} }
@ -318,7 +341,8 @@ std::string const GetHelloText(uint32 owner)
return body.str(); return body.str();
} }
bool GuildTaskMgr::SendItemAdvertisement(CharacterDatabaseTransaction& trans, uint32 itemId, uint32 owner, uint32 guildId, uint32 validIn) bool GuildTaskMgr::SendItemAdvertisement(CharacterDatabaseTransaction& trans, uint32 itemId, uint32 owner,
uint32 guildId, uint32 validIn)
{ {
Guild* guild = sGuildMgr->GetGuildById(guildId); Guild* guild = sGuildMgr->GetGuildById(guildId);
Player* leader = ObjectAccessor::FindPlayer(guild->GetLeaderGUID()); Player* leader = ObjectAccessor::FindPlayer(guild->GetLeaderGUID());
@ -352,7 +376,8 @@ bool GuildTaskMgr::SendItemAdvertisement(CharacterDatabaseTransaction& trans, ui
return true; return true;
} }
bool GuildTaskMgr::SendKillAdvertisement(CharacterDatabaseTransaction& trans, uint32 creatureId, uint32 owner, uint32 guildId, uint32 validIn) bool GuildTaskMgr::SendKillAdvertisement(CharacterDatabaseTransaction& trans, uint32 creatureId, uint32 owner,
uint32 guildId, uint32 validIn)
{ {
Guild* guild = sGuildMgr->GetGuildById(guildId); Guild* guild = sGuildMgr->GetGuildById(guildId);
Player* leader = ObjectAccessor::FindPlayer(guild->GetLeaderGUID()); Player* leader = ObjectAccessor::FindPlayer(guild->GetLeaderGUID());
@ -361,7 +386,8 @@ bool GuildTaskMgr::SendKillAdvertisement(CharacterDatabaseTransaction& trans, ui
if (!proto) if (!proto)
return false; return false;
QueryResult result = WorldDatabase.Query("SELECT map, position_x, position_y, position_z FROM creature WHERE id1 = {}", creatureId); QueryResult result =
WorldDatabase.Query("SELECT map, position_x, position_y, position_z FROM creature WHERE id1 = {}", creatureId);
if (!result) if (!result)
return false; return false;
@ -387,7 +413,8 @@ bool GuildTaskMgr::SendKillAdvertisement(CharacterDatabaseTransaction& trans, ui
std::ostringstream body; std::ostringstream body;
body << GetHelloText(owner); body << GetHelloText(owner);
body << "As you probably know " << proto->Name << " is wanted dead for the crimes it did against our guild. If you should kill it "; body << "As you probably know " << proto->Name
<< " is wanted dead for the crimes it did against our guild. If you should kill it ";
body << "we'd really appreciate that.\n\n"; body << "we'd really appreciate that.\n\n";
if (!location.empty()) if (!location.empty())
body << proto->Name << "'s the last known location was " << location << ".\n"; body << proto->Name << "'s the last known location was " << location << ".\n";
@ -399,7 +426,8 @@ bool GuildTaskMgr::SendKillAdvertisement(CharacterDatabaseTransaction& trans, ui
std::ostringstream subject; std::ostringstream subject;
subject << "Guild Task: "; subject << "Guild Task: ";
if (proto->rank == CREATURE_ELITE_ELITE || proto->rank == CREATURE_ELITE_RAREELITE || proto->rank == CREATURE_ELITE_WORLDBOSS) if (proto->rank == CREATURE_ELITE_ELITE || proto->rank == CREATURE_ELITE_RAREELITE ||
proto->rank == CREATURE_ELITE_WORLDBOSS)
subject << "(Elite) "; subject << "(Elite) ";
subject << proto->Name; subject << proto->Name;
if (!location.empty()) if (!location.empty())
@ -441,9 +469,7 @@ bool GuildTaskMgr::SendThanks(CharacterDatabaseTransaction& trans, uint32 owner,
body << guild->GetName() << "\n"; body << guild->GetName() << "\n";
body << leader->GetName() << "\n"; body << leader->GetName() << "\n";
MailDraft("Thank You", body.str()). MailDraft("Thank You", body.str()).AddMoney(payment).SendMailTo(trans, MailReceiver(owner), MailSender(leader));
AddMoney(payment).
SendMailTo(trans, MailReceiver(owner), MailSender(leader));
Player* player = ObjectAccessor::FindPlayer(ObjectGuid::Create<HighGuid::Player>(owner)); Player* player = ObjectAccessor::FindPlayer(ObjectGuid::Create<HighGuid::Player>(owner));
if (player) if (player)
@ -501,7 +527,8 @@ bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
{ {
uint32 value = 0; uint32 value = 0;
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_VALUE); PlayerbotsDatabasePreparedStatement* stmt =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_VALUE);
stmt->SetData(0, itemId); stmt->SetData(0, itemId);
stmt->SetData(1, guildId); stmt->SetData(1, guildId);
stmt->SetData(2, "itemTask"); stmt->SetData(2, "itemTask");
@ -518,11 +545,13 @@ bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
return value; return value;
} }
std::map<uint32, uint32> GuildTaskMgr::GetTaskValues(uint32 owner, std::string const type, uint32* validIn /* = nullptr */) std::map<uint32, uint32> GuildTaskMgr::GetTaskValues(uint32 owner, std::string const type,
uint32* validIn /* = nullptr */)
{ {
std::map<uint32, uint32> results; std::map<uint32, uint32> results;
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_OWNER); PlayerbotsDatabasePreparedStatement* stmt =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_OWNER);
stmt->SetData(0, owner); stmt->SetData(0, owner);
stmt->SetData(1, type); stmt->SetData(1, type);
if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt)) if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt))
@ -549,7 +578,8 @@ uint32 GuildTaskMgr::GetTaskValue(uint32 owner, uint32 guildId, std::string cons
{ {
uint32 value = 0; uint32 value = 0;
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_OWNER_AND_TYPE); PlayerbotsDatabasePreparedStatement* stmt =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_OWNER_AND_TYPE);
stmt->SetData(0, owner); stmt->SetData(0, owner);
stmt->SetData(1, guildId); stmt->SetData(1, guildId);
stmt->SetData(2, type); stmt->SetData(2, type);
@ -633,7 +663,8 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* handler, char const* args)
uint32 owner = guid.GetCounter(); uint32 owner = guid.GetCounter();
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_OWNER_ORDERED); PlayerbotsDatabasePreparedStatement* stmt =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_OWNER_ORDERED);
stmt->SetData(0, owner); stmt->SetData(0, owner);
stmt->SetData(1, "activeTask"); stmt->SetData(1, "activeTask");
if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt)) if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt))
@ -731,11 +762,10 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* handler, char const* args)
if (payment && paymentValidIn < validIn) if (payment && paymentValidIn < validIn)
name << " payment " << ChatHelper::formatMoney(payment) << " in " << formatTime(paymentValidIn); name << " payment " << ChatHelper::formatMoney(payment) << " in " << formatTime(paymentValidIn);
LOG_INFO("playerbots", "{}: {} valid in {} [{}]", LOG_INFO("playerbots", "{}: {} valid in {} [{}]", charName.c_str(), name.str().c_str(),
charName.c_str(), name.str().c_str(), formatTime(validIn).c_str(), guild->GetName().c_str()); formatTime(validIn).c_str(), guild->GetName().c_str());
} } while (result->NextRow());
while (result->NextRow());
} }
return true; return true;
@ -780,7 +810,8 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* handler, char const* args)
uint32 owner = guid.GetCounter(); uint32 owner = guid.GetCounter();
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_OWNER_DISTINCT); PlayerbotsDatabasePreparedStatement* stmt =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_GUILD_TASKS_BY_OWNER_DISTINCT);
stmt->SetData(0, owner); stmt->SetData(0, owner);
if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt)) if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt))
{ {
@ -830,7 +861,8 @@ bool GuildTaskMgr::CheckItemTask(uint32 itemId, uint32 obtained, Player* ownerPl
uint32 itemTask = GetTaskValue(owner, guildId, "itemTask"); uint32 itemTask = GetTaskValue(owner, guildId, "itemTask");
if (itemTask != itemId) if (itemTask != itemId)
{ {
LOG_DEBUG("playerbots", "{} / {}: item {} is not guild task item ({})", guild->GetName().c_str(), ownerPlayer->GetName().c_str(), itemId, itemTask); LOG_DEBUG("playerbots", "{} / {}: item {} is not guild task item ({})", guild->GetName().c_str(),
ownerPlayer->GetName().c_str(), itemId, itemTask);
if (byMail) if (byMail)
SendCompletionMessage(ownerPlayer, "made a mistake with"); SendCompletionMessage(ownerPlayer, "made a mistake with");
@ -857,7 +889,8 @@ bool GuildTaskMgr::CheckItemTask(uint32 itemId, uint32 obtained, Player* ownerPl
if (obtained >= count) if (obtained >= count)
{ {
LOG_DEBUG("playerbots", "{} / {}: guild task complete", guild->GetName().c_str(), ownerPlayer->GetName().c_str()); LOG_DEBUG("playerbots", "{} / {}: guild task complete", guild->GetName().c_str(),
ownerPlayer->GetName().c_str());
SetTaskValue(owner, guildId, "reward", 1, rewardTime - 15); SetTaskValue(owner, guildId, "reward", 1, rewardTime - 15);
SetTaskValue(owner, guildId, "itemCount", 0, 0); SetTaskValue(owner, guildId, "itemCount", 0, 0);
SetTaskValue(owner, guildId, "thanks", 0, 0); SetTaskValue(owner, guildId, "thanks", 0, 0);
@ -865,7 +898,8 @@ bool GuildTaskMgr::CheckItemTask(uint32 itemId, uint32 obtained, Player* ownerPl
} }
else else
{ {
LOG_DEBUG("playerbots", "{} / {}: guild task progress {}/{}", guild->GetName().c_str(), ownerPlayer->GetName().c_str(), obtained, count); LOG_DEBUG("playerbots", "{} / {}: guild task progress {}/{}", guild->GetName().c_str(),
ownerPlayer->GetName().c_str(), obtained, count);
SetTaskValue(owner, guildId, "itemCount", count - obtained, sPlayerbotAIConfig->maxGuildTaskChangeTime); SetTaskValue(owner, guildId, "itemCount", count - obtained, sPlayerbotAIConfig->maxGuildTaskChangeTime);
SetTaskValue(owner, guildId, "thanks", 1, rewardTime - 30); SetTaskValue(owner, guildId, "thanks", 1, rewardTime - 30);
SendCompletionMessage(ownerPlayer, "made a progress with"); SendCompletionMessage(ownerPlayer, "made a progress with");
@ -904,12 +938,14 @@ bool GuildTaskMgr::Reward(CharacterDatabaseTransaction& trans, uint32 owner, uin
if (!proto) if (!proto)
return false; return false;
body << "We wish to thank you for the " << proto->Name1 << " you provided so kindly. We really appreciate this and may this small gift bring you our thanks!\n"; body << "We wish to thank you for the " << proto->Name1
<< " you provided so kindly. We really appreciate this and may this small gift bring you our thanks!\n";
body << "\n"; body << "\n";
body << "Many thanks,\n"; body << "Many thanks,\n";
body << guild->GetName() << "\n"; body << guild->GetName() << "\n";
body << leader->GetName() << "\n"; body << leader->GetName() << "\n";
rewardType = proto->Quality > ITEM_QUALITY_NORMAL ? RANDOM_ITEM_GUILD_TASK_REWARD_EQUIP_BLUE : RANDOM_ITEM_GUILD_TASK_REWARD_EQUIP_GREEN; rewardType = proto->Quality > ITEM_QUALITY_NORMAL ? RANDOM_ITEM_GUILD_TASK_REWARD_EQUIP_BLUE
: RANDOM_ITEM_GUILD_TASK_REWARD_EQUIP_GREEN;
itemId = sRandomItemMgr->GetRandomItem(player->GetLevel() - 5, rewardType); itemId = sRandomItemMgr->GetRandomItem(player->GetLevel() - 5, rewardType);
} }
else if (killTask) else if (killTask)
@ -918,12 +954,14 @@ bool GuildTaskMgr::Reward(CharacterDatabaseTransaction& trans, uint32 owner, uin
if (!proto) if (!proto)
return false; return false;
body << "We wish to thank you for the " << proto->Name << " you've killed recently. We really appreciate this and may this small gift bring you our thanks!\n"; body << "We wish to thank you for the " << proto->Name
<< " you've killed recently. We really appreciate this and may this small gift bring you our thanks!\n";
body << "\n"; body << "\n";
body << "Many thanks,\n"; body << "Many thanks,\n";
body << guild->GetName() << "\n"; body << guild->GetName() << "\n";
body << leader->GetName() << "\n"; body << leader->GetName() << "\n";
rewardType = proto->rank == CREATURE_ELITE_RARE ? RANDOM_ITEM_GUILD_TASK_REWARD_TRADE : RANDOM_ITEM_GUILD_TASK_REWARD_TRADE_RARE; rewardType = proto->rank == CREATURE_ELITE_RARE ? RANDOM_ITEM_GUILD_TASK_REWARD_TRADE
: RANDOM_ITEM_GUILD_TASK_REWARD_TRADE_RARE;
itemId = sRandomItemMgr->GetRandomItem(player->GetLevel(), rewardType); itemId = sRandomItemMgr->GetRandomItem(player->GetLevel(), rewardType);
if (itemId) if (itemId)
{ {
@ -1032,7 +1070,8 @@ void GuildTaskMgr::CheckKillTaskInternal(Player* player, Unit* victim)
continue; continue;
LOG_DEBUG("playerbots", "{} / {}: guild task complete", guild->GetName().c_str(), player->GetName().c_str()); LOG_DEBUG("playerbots", "{} / {}: guild task complete", guild->GetName().c_str(), player->GetName().c_str());
SetTaskValue(owner, guildId, "reward", 1, urand(sPlayerbotAIConfig->minGuildTaskRewardTime, sPlayerbotAIConfig->maxGuildTaskRewardTime)); SetTaskValue(owner, guildId, "reward", 1,
urand(sPlayerbotAIConfig->minGuildTaskRewardTime, sPlayerbotAIConfig->maxGuildTaskRewardTime));
SendCompletionMessage(player, "completed"); SendCompletionMessage(player, "completed");
} }
@ -1041,7 +1080,8 @@ void GuildTaskMgr::CheckKillTaskInternal(Player* player, Unit* victim)
void GuildTaskMgr::CleanupAdverts() void GuildTaskMgr::CleanupAdverts()
{ {
uint32 deliverTime = time(nullptr) - sPlayerbotAIConfig->minGuildTaskChangeTime; uint32 deliverTime = time(nullptr) - sPlayerbotAIConfig->minGuildTaskChangeTime;
QueryResult result = CharacterDatabase.Query("SELECT id, receiver FROM mail WHERE subject LIKE 'Guild Task%%' AND deliver_time <= {}", deliverTime); QueryResult result = CharacterDatabase.Query(
"SELECT id, receiver FROM mail WHERE subject LIKE 'Guild Task%%' AND deliver_time <= {}", deliverTime);
if (!result) if (!result)
return; return;
@ -1059,7 +1099,8 @@ void GuildTaskMgr::CleanupAdverts()
if (count > 0) if (count > 0)
{ {
CharacterDatabase.Execute("DELETE FROM mail WHERE subject LIKE 'Guild Task%%' AND deliver_time <= {}", deliverTime); CharacterDatabase.Execute("DELETE FROM mail WHERE subject LIKE 'Guild Task%%' AND deliver_time <= {}",
deliverTime);
LOG_INFO("playerbots", "{} old gtask adverts removed", count); LOG_INFO("playerbots", "{} old gtask adverts removed", count);
} }
} }
@ -1067,8 +1108,12 @@ void GuildTaskMgr::CleanupAdverts()
void GuildTaskMgr::RemoveDuplicatedAdverts() void GuildTaskMgr::RemoveDuplicatedAdverts()
{ {
uint32 deliverTime = time(nullptr); uint32 deliverTime = time(nullptr);
QueryResult result = CharacterDatabase.Query("SELECT m.id, m.receiver FROM (SELECT MAX(id) AS id, subject, receiver FROM mail WHERE subject LIKE 'Guild Task%%' " QueryResult result = CharacterDatabase.Query(
"AND deliver_time <= {} GROUP BY subject, receiver) q JOIN mail m ON m.subject = q.subject WHERE m.id <> q.id AND m.deliver_time <= {}", deliverTime, deliverTime); "SELECT m.id, m.receiver FROM (SELECT MAX(id) AS id, subject, receiver FROM mail WHERE subject LIKE 'Guild "
"Task%%' "
"AND deliver_time <= {} GROUP BY subject, receiver) q JOIN mail m ON m.subject = q.subject WHERE m.id <> q.id "
"AND m.deliver_time <= {}",
deliverTime, deliverTime);
if (!result) if (!result)
return; return;
@ -1103,7 +1148,6 @@ void GuildTaskMgr::RemoveDuplicatedAdverts()
DeleteMail(buffer); DeleteMail(buffer);
LOG_INFO("playerbots", "{} duplicated gtask adverts removed", count); LOG_INFO("playerbots", "{} duplicated gtask adverts removed", count);
} }
} }
void GuildTaskMgr::DeleteMail(std::vector<uint32> buffer) void GuildTaskMgr::DeleteMail(std::vector<uint32> buffer)
@ -1147,7 +1191,8 @@ bool GuildTaskMgr::CheckTaskTransfer(std::string const text, Player* ownerPlayer
if (text.empty()) if (text.empty())
return false; return false;
LOG_DEBUG("playerbots", "{} / {}: checking guild task transfer", guild->GetName().c_str(), ownerPlayer->GetName().c_str()); LOG_DEBUG("playerbots", "{} / {}: checking guild task transfer", guild->GetName().c_str(),
ownerPlayer->GetName().c_str());
uint32 account = ownerPlayer->GetSession()->GetAccountId(); uint32 account = ownerPlayer->GetSession()->GetAccountId();

View File

@ -1,15 +1,16 @@
/* /*
* 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. * 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_GUILDTASKMGR_H #ifndef _PLAYERBOT_GUILDTASKMGR_H
#define _PLAYERBOT_GUILDTASKMGR_H #define _PLAYERBOT_GUILDTASKMGR_H
#include <map>
#include "Common.h" #include "Common.h"
#include "Transaction.h" #include "Transaction.h"
#include <map>
class ChatHandler; class ChatHandler;
class Player; class Player;
class Unit; class Unit;
@ -41,8 +42,10 @@ class GuildTaskMgr
uint32 SetTaskValue(uint32 owner, uint32 guildId, std::string const type, uint32 value, uint32 validIn); uint32 SetTaskValue(uint32 owner, uint32 guildId, std::string const type, uint32 value, uint32 validIn);
uint32 CreateTask(Player* owner, uint32 guildId); uint32 CreateTask(Player* owner, uint32 guildId);
bool SendAdvertisement(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId); bool SendAdvertisement(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId);
bool SendItemAdvertisement(CharacterDatabaseTransaction& trans, uint32 itemId, uint32 owner, uint32 guildId, uint32 validIn); bool SendItemAdvertisement(CharacterDatabaseTransaction& trans, uint32 itemId, uint32 owner, uint32 guildId,
bool SendKillAdvertisement(CharacterDatabaseTransaction& trans, uint32 creatureId, uint32 owner, uint32 guildId, uint32 validIn); uint32 validIn);
bool SendKillAdvertisement(CharacterDatabaseTransaction& trans, uint32 creatureId, uint32 owner, uint32 guildId,
uint32 validIn);
bool SendThanks(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId, uint32 payment); bool SendThanks(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId, uint32 payment);
bool Reward(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId); bool Reward(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId);
bool CreateItemTask(Player* owner, uint32 guildId); bool CreateItemTask(Player* owner, uint32 guildId);

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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 "Helpers.h" #include "Helpers.h"
@ -46,7 +47,4 @@ std::string& rtrim(std::string& s)
return s; return s;
} }
std::string& trim(std::string& s) std::string& trim(std::string& s) { return ltrim(rtrim(s)); }
{
return ltrim(rtrim(s));
}

View File

@ -1,21 +1,23 @@
/* /*
* 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. * 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_HELPERS_H #ifndef _PLAYERBOT_HELPERS_H
#define _PLAYERBOT_HELPERS_H #define _PLAYERBOT_HELPERS_H
#include "Common.h"
#include <map>
#include <vector>
#include <functional>
#include <cctype>
#include <locale>
#include <sstream>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <algorithm> #include <algorithm>
#include <cctype>
#include <functional>
#include <locale>
#include <map>
#include <sstream>
#include <vector>
#include "Common.h"
void split(std::vector<std::string>& dest, std::string const str, char const* delim) void split(std::vector<std::string>& dest, std::string const str, char const* delim)
{ {

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_LAZYCALCULATEDVALUE_H #ifndef _PLAYERBOT_LAZYCALCULATEDVALUE_H
@ -12,10 +13,7 @@ class LazyCalculatedValue
typedef TValue (TOwner::*Calculator)(); typedef TValue (TOwner::*Calculator)();
public: public:
LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner) LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner) { Reset(); }
{
Reset();
}
public: public:
TValue GetValue() TValue GetValue()
@ -29,10 +27,7 @@ class LazyCalculatedValue
return value; return value;
} }
void Reset() void Reset() { calculated = false; }
{
calculated = false;
}
protected: protected:
Calculator calculator; Calculator calculator;

View File

@ -1,17 +1,17 @@
/* /*
* 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. * 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 "LootObjectStack.h" #include "LootObjectStack.h"
#include "LootMgr.h" #include "LootMgr.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Unit.h" #include "Unit.h"
#define MAX_LOOT_OBJECT_COUNT 10 #define MAX_LOOT_OBJECT_COUNT 10
LootTarget::LootTarget(ObjectGuid guid) : guid(guid), asOfTime(time(nullptr)) LootTarget::LootTarget(ObjectGuid guid) : guid(guid), asOfTime(time(nullptr)) {}
{
}
LootTarget::LootTarget(LootTarget const& other) LootTarget::LootTarget(LootTarget const& other)
{ {
@ -30,10 +30,7 @@ LootTarget& LootTarget::operator=(LootTarget const& other)
return *this; return *this;
} }
bool LootTarget::operator<(LootTarget const& other) const bool LootTarget::operator<(LootTarget const& other) const { return guid < other.guid; }
{
return guid < other.guid;
}
void LootTargetList::shrink(time_t fromTime) void LootTargetList::shrink(time_t fromTime)
{ {
@ -59,7 +56,8 @@ void LootObject::Refresh(Player* bot, ObjectGuid lootGUID)
guid.Clear(); guid.Clear();
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return; return;
} }
Creature* creature = botAI->GetCreature(lootGUID); Creature* creature = botAI->GetCreature(lootGUID);
@ -83,7 +81,6 @@ void LootObject::Refresh(Player* bot, ObjectGuid lootGUID)
GameObject* go = botAI->GetGameObject(lootGUID); GameObject* go = botAI->GetGameObject(lootGUID);
if (go && go->isSpawned() && go->GetGoState() == GO_STATE_READY) if (go && go->isSpawned() && go->GetGoState() == GO_STATE_READY)
{ {
bool isQuestItemOnly = false; bool isQuestItemOnly = false;
GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(go->GetEntry()); GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(go->GetEntry());
@ -178,7 +175,8 @@ WorldObject* LootObject::GetWorldObject(Player* bot)
Refresh(bot, guid); Refresh(bot, guid);
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return nullptr; return nullptr;
} }
Creature* creature = botAI->GetCreature(guid); Creature* creature = botAI->GetCreature(guid);
@ -206,7 +204,8 @@ bool LootObject::IsLootPossible(Player* bot)
return false; return false;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return false; return false;
} }
if (reqItem && !bot->HasItemCount(reqItem, 1)) if (reqItem && !bot->HasItemCount(reqItem, 1))
@ -249,11 +248,13 @@ bool LootObject::IsLootPossible(Player* bot)
bool LootObjectStack::Add(ObjectGuid guid) bool LootObjectStack::Add(ObjectGuid guid)
{ {
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) { if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT)
{
availableLoot.shrink(time(nullptr) - 30); availableLoot.shrink(time(nullptr) - 30);
} }
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) { if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT)
{
availableLoot.clear(); availableLoot.clear();
} }
@ -270,10 +271,7 @@ void LootObjectStack::Remove(ObjectGuid guid)
availableLoot.erase(i); availableLoot.erase(i);
} }
void LootObjectStack::Clear() void LootObjectStack::Clear() { availableLoot.clear(); }
{
availableLoot.clear();
}
bool LootObjectStack::CanLoot(float maxDistance) bool LootObjectStack::CanLoot(float maxDistance)
{ {
@ -311,4 +309,3 @@ std::vector<LootObject> LootObjectStack::OrderByDistance(float maxDistance)
return result; return result;
} }

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_LOOTOBJECTSTACK_H #ifndef _PLAYERBOT_LOOTOBJECTSTACK_H

View File

@ -1,11 +1,14 @@
/* /*
* 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. * 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 "PerformanceMonitor.h" #include "PerformanceMonitor.h"
#include "Playerbots.h" #include "Playerbots.h"
PerformanceMonitorOperation* PerformanceMonitor::start(PerformanceMetric metric, std::string const name, PerformanceStack* stack) PerformanceMonitorOperation* PerformanceMonitor::start(PerformanceMetric metric, std::string const name,
PerformanceStack* stack)
{ {
if (!sPlayerbotAIConfig->perfMonEnabled) if (!sPlayerbotAIConfig->perfMonEnabled)
return nullptr; return nullptr;
@ -50,7 +53,6 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
if (data.empty()) if (data.empty())
return; return;
if (!perTick) if (!perTick)
{ {
float updateAITotalTime = 0; float updateAITotalTime = 0;
@ -58,11 +60,17 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
if (map.first.find("PlayerbotAI::UpdateAIInternal") != std::string::npos) if (map.first.find("PlayerbotAI::UpdateAIInternal") != std::string::npos)
updateAITotalTime += map.second->totalTime; updateAITotalTime += map.second->totalTime;
LOG_INFO("playerbots", "--------------------------------------[TOTAL BOT]------------------------------------------------------"); LOG_INFO(
LOG_INFO("playerbots", "percentage time | min .. max ( avg of count) - type : name"); "playerbots",
LOG_INFO("playerbots", "-------------------------------------------------------------------------------------------------------"); "--------------------------------------[TOTAL BOT]------------------------------------------------------");
LOG_INFO("playerbots",
"percentage time | min .. max ( avg of count) - type : name");
LOG_INFO(
"playerbots",
"-------------------------------------------------------------------------------------------------------");
for (std::map<PerformanceMetric, std::map<std::string, PerformanceData*>>::iterator i = data.begin(); i != data.end(); ++i) for (std::map<PerformanceMetric, std::map<std::string, PerformanceData*>>::iterator i = data.begin();
i != data.end(); ++i)
{ {
std::map<std::string, PerformanceData*> pdMap = i->second; std::map<std::string, PerformanceData*> pdMap = i->second;
@ -99,10 +107,9 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
names.push_back(j->first); names.push_back(j->first);
} }
std::sort(names.begin(), names.end(), [pdMap](std::string const i, std::string const j) std::sort(names.begin(), names.end(),
{ [pdMap](std::string const i, std::string const j)
return pdMap.at(i)->totalTime < pdMap.at(j)->totalTime; { return pdMap.at(i)->totalTime < pdMap.at(j)->totalTime; });
});
uint64 typeTotalTime = 0; uint64 typeTotalTime = 0;
uint64 typeMinTime = 0xffffffffu; uint64 typeMinTime = 0xffffffffu;
@ -128,15 +135,9 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
if (perc >= 0.1f || avg >= 0.25f || pd->maxTime > 1000) if (perc >= 0.1f || avg >= 0.25f || pd->maxTime > 1000)
{ {
LOG_INFO("playerbots", "{:7.3f}% {:10.3f}s | {:7.1f} .. {:7.1f} ({:10.3f} of {:10d}) - {:6} : {}" LOG_INFO("playerbots",
, perc "{:7.3f}% {:10.3f}s | {:7.1f} .. {:7.1f} ({:10.3f} of {:10d}) - {:6} : {}", perc, time,
, time minTime, maxTime, avg, pd->count, key.c_str(), disName.c_str());
, minTime
, maxTime
, avg
, pd->count
, key.c_str()
, disName.c_str());
} }
} }
float tPerc = (float)typeTotalTime / (float)updateAITotalTime * 100.0f; float tPerc = (float)typeTotalTime / (float)updateAITotalTime * 100.0f;
@ -144,15 +145,8 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
float tMinTime = (float)typeMinTime / 1000.0f; float tMinTime = (float)typeMinTime / 1000.0f;
float tMaxTime = (float)typeMaxTime / 1000.0f; float tMaxTime = (float)typeMaxTime / 1000.0f;
float tAvg = (float)typeTotalTime / (float)typeCount / 1000.0f; float tAvg = (float)typeTotalTime / (float)typeCount / 1000.0f;
LOG_INFO("playerbots", "{:7.3f}% {:10.3f}s | {:7.1f} .. {:7.1f} ({:10.3f} of {:10d}) - {:6} : {}" LOG_INFO("playerbots", "{:7.3f}% {:10.3f}s | {:7.1f} .. {:7.1f} ({:10.3f} of {:10d}) - {:6} : {}", tPerc,
, tPerc tTime, tMinTime, tMaxTime, tAvg, typeCount, key.c_str(), "Total");
, tTime
, tMinTime
, tMaxTime
, tAvg
, typeCount
, key.c_str()
, "Total");
LOG_INFO("playerbots", " "); LOG_INFO("playerbots", " ");
} }
} }
@ -161,11 +155,17 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
float fullTickCount = data[PERF_MON_TOTAL]["RandomPlayerbotMgr::FullTick"]->count; float fullTickCount = data[PERF_MON_TOTAL]["RandomPlayerbotMgr::FullTick"]->count;
float fullTickTotalTime = data[PERF_MON_TOTAL]["RandomPlayerbotMgr::FullTick"]->totalTime; float fullTickTotalTime = data[PERF_MON_TOTAL]["RandomPlayerbotMgr::FullTick"]->totalTime;
LOG_INFO("playerbots", "---------------------------------------[PER TICK]------------------------------------------------------"); LOG_INFO(
LOG_INFO("playerbots", "percentage time | min .. max ( avg of count) - type : name"); "playerbots",
LOG_INFO("playerbots", "-------------------------------------------------------------------------------------------------------"); "---------------------------------------[PER TICK]------------------------------------------------------");
LOG_INFO("playerbots",
"percentage time | min .. max ( avg of count) - type : name");
LOG_INFO(
"playerbots",
"-------------------------------------------------------------------------------------------------------");
for (std::map<PerformanceMetric, std::map<std::string, PerformanceData*>>::iterator i = data.begin(); i != data.end(); ++i) for (std::map<PerformanceMetric, std::map<std::string, PerformanceData*>>::iterator i = data.begin();
i != data.end(); ++i)
{ {
std::map<std::string, PerformanceData*> pdMap = i->second; std::map<std::string, PerformanceData*> pdMap = i->second;
@ -198,10 +198,9 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
names.push_back(j->first); names.push_back(j->first);
} }
std::sort(names.begin(), names.end(), [pdMap](std::string const i, std::string const j) std::sort(names.begin(), names.end(),
{ [pdMap](std::string const i, std::string const j)
return pdMap.at(i)->totalTime < pdMap.at(j)->totalTime; { return pdMap.at(i)->totalTime < pdMap.at(j)->totalTime; });
});
uint64 typeTotalTime = 0; uint64 typeTotalTime = 0;
uint64 typeMinTime = 0xffffffffu; uint64 typeMinTime = 0xffffffffu;
@ -227,15 +226,9 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
disName = disName.substr(0, disName.find("|")) + "]"; disName = disName.substr(0, disName.find("|")) + "]";
if (perc >= 0.1f || avg >= 0.25f || pd->maxTime > 1000) if (perc >= 0.1f || avg >= 0.25f || pd->maxTime > 1000)
{ {
LOG_INFO("playerbots", "{:7.3f}% {:9.3f}ms | {:7.1f} .. {:7.1f} ({:10.3f} of {:10.2f}) - {:6} : {}" LOG_INFO("playerbots",
, perc "{:7.3f}% {:9.3f}ms | {:7.1f} .. {:7.1f} ({:10.3f} of {:10.2f}) - {:6} : {}", perc,
, time time, minTime, maxTime, avg, amount, key.c_str(), disName.c_str());
, minTime
, maxTime
, avg
, amount
, key.c_str()
, disName.c_str());
} }
} }
if (PERF_MON_TOTAL != i->first) if (PERF_MON_TOTAL != i->first)
@ -246,15 +239,8 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
float tMaxTime = (float)typeMaxTime / 1000.0f; float tMaxTime = (float)typeMaxTime / 1000.0f;
float tAvg = (float)typeTotalTime / (float)typeCount / 1000.0f; float tAvg = (float)typeTotalTime / (float)typeCount / 1000.0f;
float tAmount = (float)typeCount / fullTickCount; float tAmount = (float)typeCount / fullTickCount;
LOG_INFO("playerbots", "{:7.3f}% {:9.3f}ms | {:7.1f} .. {:7.1f} ({:10.3f} of {:10.2f}) - {:6} : {}" LOG_INFO("playerbots", "{:7.3f}% {:9.3f}ms | {:7.1f} .. {:7.1f} ({:10.3f} of {:10.2f}) - {:6} : {}",
, tPerc tPerc, tTime, tMinTime, tMaxTime, tAvg, tAmount, key.c_str(), "Total");
, tTime
, tMinTime
, tMaxTime
, tAvg
, tAmount
, key.c_str()
, "Total");
} }
LOG_INFO("playerbots", " "); LOG_INFO("playerbots", " ");
} }
@ -263,7 +249,8 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
void PerformanceMonitor::Reset() void PerformanceMonitor::Reset()
{ {
for (std::map<PerformanceMetric, std::map<std::string, PerformanceData*> >::iterator i = data.begin(); i != data.end(); ++i) for (std::map<PerformanceMetric, std::map<std::string, PerformanceData*>>::iterator i = data.begin();
i != data.end(); ++i)
{ {
std::map<std::string, PerformanceData*> pdMap = i->second; std::map<std::string, PerformanceData*> pdMap = i->second;
for (std::map<std::string, PerformanceData*>::iterator j = pdMap.begin(); j != pdMap.end(); ++j) for (std::map<std::string, PerformanceData*>::iterator j = pdMap.begin(); j != pdMap.end(); ++j)
@ -278,14 +265,19 @@ void PerformanceMonitor::Reset()
} }
} }
PerformanceMonitorOperation::PerformanceMonitorOperation(PerformanceData* data, std::string const name, PerformanceStack* stack) : data(data), name(name), stack(stack) PerformanceMonitorOperation::PerformanceMonitorOperation(PerformanceData* data, std::string const name,
PerformanceStack* stack)
: data(data), name(name), stack(stack)
{ {
started = (std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now())).time_since_epoch(); started = (std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()))
.time_since_epoch();
} }
void PerformanceMonitorOperation::finish() void PerformanceMonitorOperation::finish()
{ {
std::chrono::microseconds finished = (std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now())).time_since_epoch(); std::chrono::microseconds finished =
(std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()))
.time_since_epoch();
uint64_t elapsed = (finished - started).count(); uint64_t elapsed = (finished - started).count();
std::lock_guard<std::mutex> guard(data->lock); std::lock_guard<std::mutex> guard(data->lock);
@ -309,4 +301,3 @@ void PerformanceMonitorOperation::finish()
delete this; delete this;
} }

View File

@ -1,18 +1,19 @@
/* /*
* 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. * 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_PERFORMANCEMONITOR_H #ifndef _PLAYERBOT_PERFORMANCEMONITOR_H
#define _PLAYERBOT_PERFORMANCEMONITOR_H #define _PLAYERBOT_PERFORMANCEMONITOR_H
#include "Common.h"
#include <chrono> #include <chrono>
#include <ctime> #include <ctime>
#include <map> #include <map>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
#include "Common.h"
typedef std::vector<std::string> PerformanceStack; typedef std::vector<std::string> PerformanceStack;
struct PerformanceData struct PerformanceData
@ -58,7 +59,8 @@ class PerformanceMonitor
} }
public: public:
PerformanceMonitorOperation* start(PerformanceMetric metric, std::string const name, PerformanceStack* stack = nullptr); PerformanceMonitorOperation* start(PerformanceMetric metric, std::string const name,
PerformanceStack* stack = nullptr);
void PrintStats(bool perTick = false, bool fullStack = false); void PrintStats(bool perTick = false, bool fullStack = false);
void Reset(); void Reset();

View File

@ -1,18 +1,17 @@
/* /*
* 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. * 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 "PlaceholderHelper.h" #include "PlaceholderHelper.h"
#include "AiFactory.h" #include "AiFactory.h"
#include "Playerbots.h"
#include "PlayerbotTextMgr.h" #include "PlayerbotTextMgr.h"
#include "Playerbots.h"
#include "Util.h" #include "Util.h"
void PlaceholderHelper::MapDungeon( void PlaceholderHelper::MapDungeon(PlaceholderMap& placeholders, DungeonSuggestion const* dungeonSuggestion,
PlaceholderMap& placeholders, Player* bot)
DungeonSuggestion const* dungeonSuggestion,
Player* bot
)
{ {
std::ostringstream out; std::ostringstream out;
Insertion insertion = {out, dungeonSuggestion}; Insertion insertion = {out, dungeonSuggestion};
@ -23,7 +22,6 @@ void PlaceholderHelper::MapDungeon(
placeholders["%dungeon"] = out.str(); placeholders["%dungeon"] = out.str();
} }
void PlaceholderHelper::MapRole(PlaceholderMap& placeholders, Player* bot) void PlaceholderHelper::MapRole(PlaceholderMap& placeholders, Player* bot)
{ {
BotRoles const role = AiFactory::GetPlayerRoles(bot); BotRoles const role = AiFactory::GetPlayerRoles(bot);

View File

@ -1,27 +1,24 @@
/* /*
* 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. * 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_PLACEHOLDERHELPER_H #ifndef _PLAYERBOT_PLACEHOLDERHELPER_H
#define _PLAYERBOT_PLACEHOLDERHELPER_H #define _PLAYERBOT_PLACEHOLDERHELPER_H
#include <map>
#include "Common.h" #include "Common.h"
#include "Player.h" #include "Player.h"
#include "PlayerbotDungeonSuggestionMgr.h" #include "PlayerbotDungeonSuggestionMgr.h"
#include <map>
typedef std::map<std::string, std::string> PlaceholderMap; typedef std::map<std::string, std::string> PlaceholderMap;
class PlaceholderHelper class PlaceholderHelper
{ {
public: public:
static void MapRole(PlaceholderMap& placeholders, Player* bot); static void MapRole(PlaceholderMap& placeholders, Player* bot);
static void MapDungeon( static void MapDungeon(PlaceholderMap& placeholders, DungeonSuggestion const* dungeonSuggestion, Player* bot);
PlaceholderMap& placeholders,
DungeonSuggestion const* dungeonSuggestion,
Player* bot
);
private: private:
struct Insertion struct Insertion

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,26 @@
/* /*
* 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. * 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_PLAYERbotAI_H #ifndef _PLAYERBOT_PLAYERbotAI_H
#define _PLAYERBOT_PLAYERbotAI_H #define _PLAYERBOT_PLAYERbotAI_H
#include <queue>
#include <stack>
#include "Chat.h" #include "Chat.h"
#include "ChatHelper.h"
#include "ChatFilter.h" #include "ChatFilter.h"
#include "ChatHelper.h"
#include "Common.h" #include "Common.h"
#include "Event.h" #include "Event.h"
#include "Item.h" #include "Item.h"
#include "PlayerbotAIBase.h" #include "PlayerbotAIBase.h"
#include "PlayerbotAIConfig.h" #include "PlayerbotAIConfig.h"
#include "PlayerbotSecurity.h" #include "PlayerbotSecurity.h"
#include "PlayerbotTextMgr.h"
#include "SpellAuras.h" #include "SpellAuras.h"
#include "WorldPacket.h" #include "WorldPacket.h"
#include "PlayerbotTextMgr.h"
#include <stack>
#include <queue>
class AiObjectContext; class AiObjectContext;
class Creature; class Creature;
@ -120,7 +121,8 @@ enum SharpeningStoneDisplayId
HEAVY_SHARPENING_DISPLAYID = 24675, HEAVY_SHARPENING_DISPLAYID = 24675,
SOLID_SHARPENING_DISPLAYID = 24676, SOLID_SHARPENING_DISPLAYID = 24676,
DENSE_SHARPENING_DISPLAYID = 24677, DENSE_SHARPENING_DISPLAYID = 24677,
CONSECRATED_SHARPENING_DISPLAYID = 24674, // will not be used because bot can not know if it will face undead targets CONSECRATED_SHARPENING_DISPLAYID =
24674, // will not be used because bot can not know if it will face undead targets
ELEMENTAL_SHARPENING_DISPLAYID = 21072, ELEMENTAL_SHARPENING_DISPLAYID = 21072,
FEL_SHARPENING_DISPLAYID = 39192, FEL_SHARPENING_DISPLAYID = 39192,
ADAMANTITE_SHARPENING_DISPLAYID = 39193 ADAMANTITE_SHARPENING_DISPLAYID = 39193
@ -210,61 +212,71 @@ enum BotRoles : uint8
BOT_ROLE_DPS = 0x04 BOT_ROLE_DPS = 0x04
}; };
enum HUNTER_TABS { enum HUNTER_TABS
{
HUNTER_TAB_BEASTMASTER, HUNTER_TAB_BEASTMASTER,
HUNTER_TAB_MARKSMANSHIP, HUNTER_TAB_MARKSMANSHIP,
HUNTER_TAB_SURVIVAL, HUNTER_TAB_SURVIVAL,
}; };
enum ROGUE_TABS { enum ROGUE_TABS
{
ROGUE_TAB_ASSASSINATION, ROGUE_TAB_ASSASSINATION,
ROGUE_TAB_COMBAT, ROGUE_TAB_COMBAT,
ROGUE_TAB_SUBTLETY ROGUE_TAB_SUBTLETY
}; };
enum PRIEST_TABS { enum PRIEST_TABS
{
PRIEST_TAB_DISIPLINE, PRIEST_TAB_DISIPLINE,
PRIEST_TAB_HOLY, PRIEST_TAB_HOLY,
PRIEST_TAB_SHADOW, PRIEST_TAB_SHADOW,
}; };
enum DEATHKNIGT_TABS { enum DEATHKNIGT_TABS
{
DEATHKNIGT_TAB_BLOOD, DEATHKNIGT_TAB_BLOOD,
DEATHKNIGT_TAB_FROST, DEATHKNIGT_TAB_FROST,
DEATHKNIGT_TAB_UNHOLY, DEATHKNIGT_TAB_UNHOLY,
}; };
enum DRUID_TABS { enum DRUID_TABS
{
DRUID_TAB_BALANCE, DRUID_TAB_BALANCE,
DRUID_TAB_FERAL, DRUID_TAB_FERAL,
DRUID_TAB_RESTORATION, DRUID_TAB_RESTORATION,
}; };
enum MAGE_TABS { enum MAGE_TABS
{
MAGE_TAB_ARCANE, MAGE_TAB_ARCANE,
MAGE_TAB_FIRE, MAGE_TAB_FIRE,
MAGE_TAB_FROST, MAGE_TAB_FROST,
}; };
enum SHAMAN_TABS { enum SHAMAN_TABS
{
SHAMAN_TAB_ELEMENTAL, SHAMAN_TAB_ELEMENTAL,
SHAMAN_TAB_ENHANCEMENT, SHAMAN_TAB_ENHANCEMENT,
SHAMAN_TAB_RESTORATION, SHAMAN_TAB_RESTORATION,
}; };
enum PALADIN_TABS { enum PALADIN_TABS
{
PALADIN_TAB_HOLY, PALADIN_TAB_HOLY,
PALADIN_TAB_PROTECTION, PALADIN_TAB_PROTECTION,
PALADIN_TAB_RETRIBUTION, PALADIN_TAB_RETRIBUTION,
}; };
enum WARLOCK_TABS { enum WARLOCK_TABS
{
WARLOCK_TAB_AFFLICATION, WARLOCK_TAB_AFFLICATION,
WARLOCK_TAB_DEMONOLOGY, WARLOCK_TAB_DEMONOLOGY,
WARLOCK_TAB_DESTRUCTION, WARLOCK_TAB_DESTRUCTION,
}; };
enum WARRIOR_TABS { enum WARRIOR_TABS
{
WARRIOR_TAB_ARMS, WARRIOR_TAB_ARMS,
WARRIOR_TAB_FURY, WARRIOR_TAB_FURY,
WARRIOR_TAB_PROTECTION, WARRIOR_TAB_PROTECTION,
@ -285,8 +297,15 @@ class PacketHandlingHelper
class ChatCommandHolder class ChatCommandHolder
{ {
public: public:
ChatCommandHolder(std::string const command, Player* owner = nullptr, uint32 type = CHAT_MSG_WHISPER, time_t time = 0) : command(command), owner(owner), type(type), time(time) { } ChatCommandHolder(std::string const command, Player* owner = nullptr, uint32 type = CHAT_MSG_WHISPER,
ChatCommandHolder(ChatCommandHolder const& other) : command(other.command), owner(other.owner), type(other.type), time(other.time) { } time_t time = 0)
: command(command), owner(owner), type(type), time(time)
{
}
ChatCommandHolder(ChatCommandHolder const& other)
: command(other.command), owner(other.owner), type(other.type), time(other.time)
{
}
std::string const GetCommand() { return command; } std::string const GetCommand() { return command; }
Player* GetOwner() { return owner; } Player* GetOwner() { return owner; }
@ -312,14 +331,16 @@ class PlayerbotAI : public PlayerbotAIBase
std::string const HandleRemoteCommand(std::string const command); std::string const HandleRemoteCommand(std::string const command);
void HandleCommand(uint32 type, std::string const text, Player* fromPlayer); void HandleCommand(uint32 type, std::string const text, Player* fromPlayer);
void QueueChatResponse(uint8 msgtype, ObjectGuid guid1, ObjectGuid guid2, std::string message, std::string chanName, std::string name); void QueueChatResponse(uint8 msgtype, ObjectGuid guid1, ObjectGuid guid2, std::string message, std::string chanName,
std::string name);
void HandleBotOutgoingPacket(WorldPacket const& packet); void HandleBotOutgoingPacket(WorldPacket const& packet);
void HandleMasterIncomingPacket(WorldPacket const& packet); void HandleMasterIncomingPacket(WorldPacket const& packet);
void HandleMasterOutgoingPacket(WorldPacket const& packet); void HandleMasterOutgoingPacket(WorldPacket const& packet);
void HandleTeleportAck(); void HandleTeleportAck();
void ChangeEngine(BotState type); void ChangeEngine(BotState type);
void DoNextAction(bool minimal = false); void DoNextAction(bool minimal = false);
virtual bool DoSpecificAction(std::string const name, Event event = Event(), bool silent = false, std::string const qualifier = ""); virtual bool DoSpecificAction(std::string const name, Event event = Event(), bool silent = false,
std::string const qualifier = "");
void ChangeStrategy(std::string const name, BotState type); void ChangeStrategy(std::string const name, BotState type);
void ClearStrategies(BotState type); void ClearStrategies(BotState type);
std::vector<std::string> GetStrategies(BotState type); std::vector<std::string> GetStrategies(BotState type);
@ -358,8 +379,10 @@ class PlayerbotAI : public PlayerbotAIBase
WorldObject* GetWorldObject(ObjectGuid guid); WorldObject* GetWorldObject(ObjectGuid guid);
bool TellMaster(std::ostringstream& stream, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL); bool TellMaster(std::ostringstream& stream, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL);
bool TellMaster(std::string const text, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL); bool TellMaster(std::string const text, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL);
bool TellMasterNoFacing(std::ostringstream& stream, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL); bool TellMasterNoFacing(std::ostringstream& stream,
bool TellMasterNoFacing(std::string const text, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL); PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL);
bool TellMasterNoFacing(std::string const text,
PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL);
bool TellError(std::string const text, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL); bool TellError(std::string const text, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL);
void SpellInterrupted(uint32 spellid); void SpellInterrupted(uint32 spellid);
int32 CalculateGlobalCooldown(uint32 spellid); int32 CalculateGlobalCooldown(uint32 spellid);
@ -384,17 +407,21 @@ class PlayerbotAI : public PlayerbotAIBase
virtual bool CanCastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr); virtual bool CanCastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr);
virtual bool CastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr); virtual bool CastSpell(std::string const name, Unit* target, Item* itemTarget = nullptr);
virtual bool HasAura(std::string const spellName, Unit* player, bool maxStack = false, bool checkIsOwner = false, int maxAmount = -1, bool checkDuration = false); virtual bool HasAura(std::string const spellName, Unit* player, bool maxStack = false, bool checkIsOwner = false,
int maxAmount = -1, bool checkDuration = false);
virtual bool HasAnyAuraOf(Unit* player, ...); virtual bool HasAnyAuraOf(Unit* player, ...);
virtual bool IsInterruptableSpellCasting(Unit* player, std::string const spell); virtual bool IsInterruptableSpellCasting(Unit* player, std::string const spell);
virtual bool HasAuraToDispel(Unit* player, uint32 dispelType); virtual bool HasAuraToDispel(Unit* player, uint32 dispelType);
bool CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell = true, Item* itemTarget = nullptr, Item* castItem = nullptr); bool CanCastSpell(uint32 spellid, Unit* target, bool checkHasSpell = true, Item* itemTarget = nullptr,
Item* castItem = nullptr);
bool CanCastSpell(uint32 spellid, GameObject* goTarget, uint8 effectMask, bool checkHasSpell = true); bool CanCastSpell(uint32 spellid, GameObject* goTarget, uint8 effectMask, bool checkHasSpell = true);
bool CanCastSpell(uint32 spellid, float x, float y, float z, uint8 effectMask, bool checkHasSpell = true, Item* itemTarget = nullptr); bool CanCastSpell(uint32 spellid, float x, float y, float z, uint8 effectMask, bool checkHasSpell = true,
Item* itemTarget = nullptr);
bool HasAura(uint32 spellId, Unit const* player); bool HasAura(uint32 spellId, Unit const* player);
Aura* GetAura(std::string const spellName, Unit* unit, bool checkIsOwner = false, bool checkDuration = false, int checkStack = -1); Aura* GetAura(std::string const spellName, Unit* unit, bool checkIsOwner = false, bool checkDuration = false,
int checkStack = -1);
bool CastSpell(uint32 spellId, Unit* target, Item* itemTarget = nullptr); bool CastSpell(uint32 spellId, Unit* target, Item* itemTarget = nullptr);
bool CastSpell(uint32 spellId, float x, float y, float z, Item* itemTarget = nullptr); bool CastSpell(uint32 spellId, float x, float y, float z, Item* itemTarget = nullptr);
bool canDispel(SpellInfo const* spellInfo, uint32 dispelType); bool canDispel(SpellInfo const* spellInfo, uint32 dispelType);
@ -402,7 +429,8 @@ class PlayerbotAI : public PlayerbotAIBase
bool CanCastVehicleSpell(uint32 spellid, Unit* target); bool CanCastVehicleSpell(uint32 spellid, Unit* target);
bool CastVehicleSpell(uint32 spellId, Unit* target); bool CastVehicleSpell(uint32 spellId, Unit* target);
bool CastVehicleSpell(uint32 spellId, float x, float y, float z); bool CastVehicleSpell(uint32 spellId, float x, float y, float z);
bool IsInVehicle(bool canControl = false, bool canCast = false, bool canAttack = false, bool canTurn = false, bool fixed = false); bool IsInVehicle(bool canControl = false, bool canCast = false, bool canAttack = false, bool canTurn = false,
bool fixed = false);
uint32 GetEquipGearScore(Player* player, bool withBags, bool withBank); uint32 GetEquipGearScore(Player* player, bool withBags, bool withBank);
static uint32 GetMixedGearScore(Player* player, bool withBags, bool withBank, uint32 topN = 0); static uint32 GetMixedGearScore(Player* player, bool withBags, bool withBank, uint32 topN = 0);
@ -433,7 +461,11 @@ class PlayerbotAI : public PlayerbotAIBase
bool AllowActive(ActivityType activityType); bool AllowActive(ActivityType activityType);
bool AllowActivity(ActivityType activityType = ALL_ACTIVITY, bool checkNow = false); bool AllowActivity(ActivityType activityType = ALL_ACTIVITY, bool checkNow = false);
bool HasCheat(BotCheatMask mask) { return ((uint32)mask & (uint32)cheatMask) != 0 || ((uint32)mask & (uint32)sPlayerbotAIConfig->botCheatMask) != 0; } bool HasCheat(BotCheatMask mask)
{
return ((uint32)mask & (uint32)cheatMask) != 0 ||
((uint32)mask & (uint32)sPlayerbotAIConfig->botCheatMask) != 0;
}
BotCheatMask GetCheat() { return cheatMask; } BotCheatMask GetCheat() { return cheatMask; }
void SetCheat(BotCheatMask mask) { cheatMask = mask; } void SetCheat(BotCheatMask mask) { cheatMask = mask; }
@ -454,9 +486,12 @@ class PlayerbotAI : public PlayerbotAIBase
bool EqualLowercaseName(std::string s1, std::string s2); bool EqualLowercaseName(std::string s1, std::string s2);
InventoryResult CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading = true) const; InventoryResult CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading = true) const;
uint8 FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) const; uint8 FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) const;
private: private:
static void _fillGearScoreData(Player* player, Item* item, std::vector<uint32>* gearScore, uint32& twoHandScore, bool mixed = false); static void _fillGearScoreData(Player* player, Item* item, std::vector<uint32>* gearScore, uint32& twoHandScore,
bool mixed = false);
bool IsTellAllowed(PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL); bool IsTellAllowed(PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL);
protected: protected:
Player* bot; Player* bot;
Player* master; Player* master;

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_PLAYERbotAIAWARE_H #ifndef _PLAYERBOT_PLAYERbotAIAWARE_H

View File

@ -1,13 +1,13 @@
/* /*
* 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. * 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 "PlayerbotAIBase.h" #include "PlayerbotAIBase.h"
#include "Playerbots.h" #include "Playerbots.h"
PlayerbotAIBase::PlayerbotAIBase(bool isBotAI) : nextAICheckDelay(0), _isBotAI(isBotAI) PlayerbotAIBase::PlayerbotAIBase(bool isBotAI) : nextAICheckDelay(0), _isBotAI(isBotAI) {}
{
}
void PlayerbotAIBase::UpdateAI(uint32 elapsed, bool minimal) void PlayerbotAIBase::UpdateAI(uint32 elapsed, bool minimal)
{ {
@ -42,10 +42,7 @@ void PlayerbotAIBase::IncreaseNextCheckDelay(uint32 delay)
// LOG_DEBUG("playerbots", "increase next check delay: {}", nextAICheckDelay); // LOG_DEBUG("playerbots", "increase next check delay: {}", nextAICheckDelay);
} }
bool PlayerbotAIBase::CanUpdateAI() bool PlayerbotAIBase::CanUpdateAI() { return nextAICheckDelay == 0; }
{
return nextAICheckDelay == 0;
}
void PlayerbotAIBase::YieldThread(bool delay) void PlayerbotAIBase::YieldThread(bool delay)
{ {
@ -53,12 +50,6 @@ void PlayerbotAIBase::YieldThread(bool delay)
nextAICheckDelay = delay ? sPlayerbotAIConfig->reactDelay * 10 : sPlayerbotAIConfig->reactDelay; nextAICheckDelay = delay ? sPlayerbotAIConfig->reactDelay * 10 : sPlayerbotAIConfig->reactDelay;
} }
bool PlayerbotAIBase::IsActive() bool PlayerbotAIBase::IsActive() { return nextAICheckDelay < sPlayerbotAIConfig->maxWaitForMove; }
{
return nextAICheckDelay < sPlayerbotAIConfig->maxWaitForMove;
}
bool PlayerbotAIBase::IsBotAI() const bool PlayerbotAIBase::IsBotAI() const { return _isBotAI; }
{
return _isBotAI;
}

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_PLAYERBOTAIBASE_H #ifndef _PLAYERBOT_PLAYERBOTAIBASE_H

View File

@ -1,17 +1,19 @@
/* /*
* 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. * 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 "PlayerbotAIConfig.h" #include "PlayerbotAIConfig.h"
#include <iostream>
#include "Config.h" #include "Config.h"
#include "Playerbots.h" #include "PlayerbotDungeonSuggestionMgr.h"
#include "PlayerbotFactory.h" #include "PlayerbotFactory.h"
#include "Playerbots.h"
#include "RandomItemMgr.h" #include "RandomItemMgr.h"
#include "RandomPlayerbotFactory.h" #include "RandomPlayerbotFactory.h"
#include "Talentspec.h" #include "Talentspec.h"
#include "PlayerbotDungeonSuggestionMgr.h"
#include <iostream>
template <class T> template <class T>
void LoadList(std::string const value, T& list) void LoadList(std::string const value, T& list)
@ -110,49 +112,71 @@ bool PlayerbotAIConfig::Initialize()
randomBotMapsAsString = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotMaps", "0,1,530,571"); randomBotMapsAsString = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotMaps", "0,1,530,571");
LoadList<std::vector<uint32>>(randomBotMapsAsString, randomBotMaps); LoadList<std::vector<uint32>>(randomBotMapsAsString, randomBotMaps);
probTeleToBankers = sConfigMgr->GetOption<float>("AiPlayerbot.ProbTeleToBankers", 0.25f); probTeleToBankers = sConfigMgr->GetOption<float>("AiPlayerbot.ProbTeleToBankers", 0.25f);
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestItems", "6948,5175,5176,5177,5178,16309,12382,13704,11000"), randomBotQuestItems); LoadList<std::vector<uint32>>(
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotSpellIds", "54197"), randomBotSpellIds); sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestItems",
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.PvpProhibitedZoneIds", "2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565,3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395"), pvpProhibitedZoneIds); "6948,5175,5176,5177,5178,16309,12382,13704,11000"),
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.PvpProhibitedAreaIds", "976,35"), pvpProhibitedAreaIds); randomBotQuestItems);
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotSpellIds", "54197"),
randomBotSpellIds);
LoadList<std::vector<uint32>>(
sConfigMgr->GetOption<std::string>("AiPlayerbot.PvpProhibitedZoneIds",
"2255,656,2361,2362,2363,976,35,2268,3425,392,541,1446,3828,3712,3738,3565,"
"3539,3623,4152,3988,4658,4284,4418,4436,4275,4323,4395"),
pvpProhibitedZoneIds);
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.PvpProhibitedAreaIds", "976,35"),
pvpProhibitedAreaIds);
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestIds", "7848,3802,5505,6502,7761"), randomBotQuestIds); LoadList<std::vector<uint32>>(
sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotQuestIds", "7848,3802,5505,6502,7761"),
randomBotQuestIds);
botAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.BotAutologin", false); botAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.BotAutologin", false);
randomBotAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutologin", true); randomBotAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutologin", true);
minRandomBots = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBots", 50); minRandomBots = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBots", 50);
maxRandomBots = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBots", 200); maxRandomBots = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBots", 200);
randomBotUpdateInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotUpdateInterval", MINUTE); randomBotUpdateInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotUpdateInterval", MINUTE);
randomBotCountChangeMinInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotCountChangeMinInterval", 30 * MINUTE); randomBotCountChangeMinInterval =
randomBotCountChangeMaxInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotCountChangeMaxInterval", 2 * HOUR); sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotCountChangeMinInterval", 30 * MINUTE);
randomBotCountChangeMaxInterval =
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotCountChangeMaxInterval", 2 * HOUR);
minRandomBotInWorldTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotInWorldTime", 2 * HOUR); minRandomBotInWorldTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotInWorldTime", 2 * HOUR);
maxRandomBotInWorldTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotInWorldTime", 12 * HOUR); maxRandomBotInWorldTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotInWorldTime", 12 * HOUR);
minRandomBotRandomizeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotRandomizeTime", 2 * HOUR); minRandomBotRandomizeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotRandomizeTime", 2 * HOUR);
maxRandomBotRandomizeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotRandomizeTime", 14 * 24 * HOUR); maxRandomBotRandomizeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotRandomizeTime", 14 * 24 * HOUR);
minRandomBotChangeStrategyTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotChangeStrategyTime", 30 * MINUTE); minRandomBotChangeStrategyTime =
maxRandomBotChangeStrategyTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotChangeStrategyTime", 2 * HOUR); sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotChangeStrategyTime", 30 * MINUTE);
maxRandomBotChangeStrategyTime =
sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotChangeStrategyTime", 2 * HOUR);
minRandomBotReviveTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotReviveTime", MINUTE); minRandomBotReviveTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotReviveTime", MINUTE);
maxRandomBotReviveTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotReviveTime", 5 * MINUTE); maxRandomBotReviveTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotReviveTime", 5 * MINUTE);
minRandomBotTeleportInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotTeleportInterval", 1 * HOUR); minRandomBotTeleportInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotTeleportInterval", 1 * HOUR);
maxRandomBotTeleportInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotTeleportInterval", 5 * HOUR); maxRandomBotTeleportInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotTeleportInterval", 5 * HOUR);
randomBotInWorldWithRotationDisabled = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotInWorldWithRotationDisabled", 1 * YEAR); randomBotInWorldWithRotationDisabled =
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotInWorldWithRotationDisabled", 1 * YEAR);
randomBotTeleportDistance = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotTeleportDistance", 100); randomBotTeleportDistance = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotTeleportDistance", 100);
randomBotsPerInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotsPerInterval", MINUTE); randomBotsPerInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotsPerInterval", MINUTE);
minRandomBotsPriceChangeInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotsPriceChangeInterval", 2 * HOUR); minRandomBotsPriceChangeInterval =
maxRandomBotsPriceChangeInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR); sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotsPriceChangeInterval", 2 * 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); randomBotTalk = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotTalk", false);
randomBotEmote = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotEmote", false); randomBotEmote = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotEmote", false);
randomBotSuggestDungeons = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotSuggestDungeons", true); randomBotSuggestDungeons = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotSuggestDungeons", true);
randomBotGuildTalk = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotGuildTalk", false); randomBotGuildTalk = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotGuildTalk", false);
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);
randomBotAutoJoinBG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutoJoinBG", false); randomBotAutoJoinBG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutoJoinBG", false);
randomBotAutoJoinWarsongBracket = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinWarsongBracket", 14); randomBotAutoJoinWarsongBracket = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinWarsongBracket", 14);
randomBotAutoJoinArenaBracket = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinArenaBracket", 7); randomBotAutoJoinArenaBracket = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinArenaBracket", 7);
randomBotAutoJoinBGWarsongCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGWarsongCount", 0); randomBotAutoJoinBGWarsongCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGWarsongCount", 0);
randomBotAutoJoinBGRatedArena2v2Count = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena2v2Count", 0); randomBotAutoJoinBGRatedArena2v2Count =
randomBotAutoJoinBGRatedArena3v3Count = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena3v3Count", 0); sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena2v2Count", 0);
randomBotAutoJoinBGRatedArena5v5Count = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena5v5Count", 0); randomBotAutoJoinBGRatedArena3v3Count =
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena3v3Count", 0);
randomBotAutoJoinBGRatedArena5v5Count =
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena5v5Count", 0);
logInGroupOnly = sConfigMgr->GetOption<bool>("AiPlayerbot.LogInGroupOnly", true); logInGroupOnly = sConfigMgr->GetOption<bool>("AiPlayerbot.LogInGroupOnly", true);
logValuesPerTick = sConfigMgr->GetOption<bool>("AiPlayerbot.LogValuesPerTick", false); logValuesPerTick = sConfigMgr->GetOption<bool>("AiPlayerbot.LogValuesPerTick", false);
fleeingEnabled = sConfigMgr->GetOption<bool>("AiPlayerbot.FleeingEnabled", true); fleeingEnabled = sConfigMgr->GetOption<bool>("AiPlayerbot.FleeingEnabled", true);
@ -183,7 +207,8 @@ bool PlayerbotAIConfig::Initialize()
for (uint32 cls = 1; cls < MAX_CLASSES; ++cls) for (uint32 cls = 1; cls < MAX_CLASSES; ++cls)
{ {
if (cls == 10) { if (cls == 10)
{
continue; continue;
} }
for (uint32 spec = 0; spec < MAX_SPECNO; ++spec) for (uint32 spec = 0; spec < MAX_SPECNO; ++spec)
@ -196,12 +221,15 @@ bool PlayerbotAIConfig::Initialize()
os << "AiPlayerbot.PremadeSpecGlyph." << cls << "." << spec; os << "AiPlayerbot.PremadeSpecGlyph." << cls << "." << spec;
premadeSpecGlyph[cls][spec] = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false); premadeSpecGlyph[cls][spec] = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
std::vector<std::string> splitSpecGlyph = split(premadeSpecGlyph[cls][spec], ','); std::vector<std::string> splitSpecGlyph = split(premadeSpecGlyph[cls][spec], ',');
for (std::string &split : splitSpecGlyph) { for (std::string& split : splitSpecGlyph)
if (split.size() != 0) { {
if (split.size() != 0)
{
parsedSpecGlyph[cls][spec].push_back(atoi(split.c_str())); parsedSpecGlyph[cls][spec].push_back(atoi(split.c_str()));
} }
} }
for (uint32 level = 0; level < MAX_LEVEL; ++level) { for (uint32 level = 0; level < MAX_LEVEL; ++level)
{
std::ostringstream os; std::ostringstream os;
os << "AiPlayerbot.PremadeSpecLink." << cls << "." << spec << "." << level; os << "AiPlayerbot.PremadeSpecLink." << cls << "." << spec << "." << level;
premadeSpecLink[cls][spec][level] = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false); premadeSpecLink[cls][spec][level] = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
@ -221,7 +249,8 @@ bool PlayerbotAIConfig::Initialize()
} }
botCheats.clear(); botCheats.clear();
LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.BotCheats", "taxi"), botCheats); LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.BotCheats", "taxi"),
botCheats);
botCheatMask = 0; botCheatMask = 0;
@ -236,7 +265,8 @@ bool PlayerbotAIConfig::Initialize()
if (std::find(botCheats.begin(), botCheats.end(), "power") != botCheats.end()) if (std::find(botCheats.begin(), botCheats.end(), "power") != botCheats.end())
botCheatMask |= (uint32)BotCheatMask::power; botCheatMask |= (uint32)BotCheatMask::power;
LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.AllowedLogFiles", ""), allowedLogFiles); LoadListString<std::vector<std::string>>(sConfigMgr->GetOption<std::string>("AiPlayerbot.AllowedLogFiles", ""),
allowedLogFiles);
worldBuffs.clear(); worldBuffs.clear();
@ -264,7 +294,8 @@ bool PlayerbotAIConfig::Initialize()
minGuildTaskChangeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinGuildTaskChangeTime", 3 * 24 * 3600); minGuildTaskChangeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinGuildTaskChangeTime", 3 * 24 * 3600);
maxGuildTaskChangeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxGuildTaskChangeTime", 4 * 24 * 3600); maxGuildTaskChangeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxGuildTaskChangeTime", 4 * 24 * 3600);
minGuildTaskAdvertisementTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinGuildTaskAdvertisementTime", 300); minGuildTaskAdvertisementTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinGuildTaskAdvertisementTime", 300);
maxGuildTaskAdvertisementTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxGuildTaskAdvertisementTime", 12 * 3600); maxGuildTaskAdvertisementTime =
sConfigMgr->GetOption<int32>("AiPlayerbot.MaxGuildTaskAdvertisementTime", 12 * 3600);
minGuildTaskRewardTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinGuildTaskRewardTime", 300); minGuildTaskRewardTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinGuildTaskRewardTime", 300);
maxGuildTaskRewardTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxGuildTaskRewardTime", 3600); maxGuildTaskRewardTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxGuildTaskRewardTime", 3600);
guildTaskAdvertCleanupTime = sConfigMgr->GetOption<int32>("AiPlayerbot.GuildTaskAdvertCleanupTime", 300); guildTaskAdvertCleanupTime = sConfigMgr->GetOption<int32>("AiPlayerbot.GuildTaskAdvertCleanupTime", 300);
@ -352,7 +383,8 @@ bool PlayerbotAIConfig::Initialize()
selfBotLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.SelfBotLevel", 1); selfBotLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.SelfBotLevel", 1);
RandomPlayerbotFactory::CreateRandomBots(); RandomPlayerbotFactory::CreateRandomBots();
if (World::IsStopped()) { if (World::IsStopped())
{
return true; return true;
} }
PlayerbotFactory::Init(); PlayerbotFactory::Init();
@ -418,7 +450,8 @@ std::string const PlayerbotAIConfig::GetTimestampStr()
// MM minutes (2 digits 00-59) // MM minutes (2 digits 00-59)
// SS seconds (2 digits 00-59) // SS seconds (2 digits 00-59)
char buf[20]; char buf[20];
snprintf(buf, 20, "%04d-%02d-%02d %02d-%02d-%02d", aTm->tm_year + 1900, aTm->tm_mon + 1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec); snprintf(buf, 20, "%04d-%02d-%02d %02d-%02d-%02d", aTm->tm_year + 1900, aTm->tm_mon + 1, aTm->tm_mday, aTm->tm_hour,
aTm->tm_min, aTm->tm_sec);
return std::string(buf); return std::string(buf);
} }
@ -447,7 +480,6 @@ bool PlayerbotAIConfig::openLog(std::string const fileName, char const* mode)
m_logsDir.append("/"); m_logsDir.append("/");
} }
file = fopen((m_logsDir + fileName).c_str(), mode); file = fopen((m_logsDir + fileName).c_str(), mode);
fileOpen = true; fileOpen = true;
@ -572,7 +604,8 @@ static std::vector<std::string> split(const std::string &str, const std::string
return res; return res;
} }
std::vector<std::vector<uint32>> PlayerbotAIConfig::ParseTempTalentsOrder(uint32 cls, std::string tab_link) { std::vector<std::vector<uint32>> PlayerbotAIConfig::ParseTempTalentsOrder(uint32 cls, std::string tab_link)
{
// check bad link // check bad link
uint32 classMask = 1 << (cls - 1); uint32 classMask = 1 << (cls - 1);
std::vector<std::vector<uint32>> res; std::vector<std::vector<uint32>> res;
@ -594,27 +627,31 @@ std::vector<std::vector<uint32>> PlayerbotAIConfig::ParseTempTalentsOrder(uint32
spells[talentTabInfo->tabpage].push_back(talentInfo); spells[talentTabInfo->tabpage].push_back(talentInfo);
} }
for (int tab = 0; tab < 3; tab++) { for (int tab = 0; tab < 3; tab++)
if (tab_links.size() <= tab) { {
if (tab_links.size() <= tab)
{
break; break;
} }
std::sort(spells[tab].begin(), spells[tab].end(), [&](TalentEntry const* lhs, TalentEntry const* rhs) { std::sort(spells[tab].begin(), spells[tab].end(),
return lhs->Row != rhs->Row ? lhs->Row < rhs->Row : lhs->Col < rhs->Col; [&](TalentEntry const* lhs, TalentEntry const* rhs)
}); { return lhs->Row != rhs->Row ? lhs->Row < rhs->Row : lhs->Col < rhs->Col; });
for (int i = 0; i < tab_links[tab].size(); i++) { for (int i = 0; i < tab_links[tab].size(); i++)
if (i >= spells[tab].size()) { {
if (i >= spells[tab].size())
{
break; break;
} }
int lvl = tab_links[tab][i] - '0'; int lvl = tab_links[tab][i] - '0';
if (lvl == 0) continue; if (lvl == 0)
continue;
orders[tab].push_back({(uint32)tab, spells[tab][i]->Row, spells[tab][i]->Col, (uint32)lvl}); orders[tab].push_back({(uint32)tab, spells[tab][i]->Row, spells[tab][i]->Col, (uint32)lvl});
} }
} }
// sort by talent tab size // sort by talent tab size
std::sort(orders.begin(), orders.end(), [&](auto &lhs, auto &rhs) { std::sort(orders.begin(), orders.end(), [&](auto& lhs, auto& rhs) { return lhs.size() > rhs.size(); });
return lhs.size() > rhs.size(); for (auto& order : orders)
}); {
for (auto &order : orders) {
res.insert(res.end(), order.begin(), order.end()); res.insert(res.end(), order.begin(), order.end());
} }
return res; return res;

View File

@ -1,17 +1,18 @@
/* /*
* 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. * 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_PLAYERbotAICONFIG_H #ifndef _PLAYERBOT_PLAYERbotAICONFIG_H
#define _PLAYERBOT_PLAYERbotAICONFIG_H #define _PLAYERBOT_PLAYERbotAICONFIG_H
#include <mutex>
#include "Common.h" #include "Common.h"
#include "DBCEnums.h" #include "DBCEnums.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "Talentspec.h" #include "Talentspec.h"
#include <mutex>
enum class BotCheatMask : uint32 enum class BotCheatMask : uint32
{ {
none = 0, none = 0,
@ -54,12 +55,11 @@ class PlayerbotAIConfig
bool enabled; bool enabled;
bool allowGuildBots, allowPlayerBots; bool allowGuildBots, allowPlayerBots;
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime, uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime, expireActionTime,
expireActionTime, dispelAuraDuration, passiveDelay, repeatDelay, dispelAuraDuration, passiveDelay, repeatDelay, errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay; float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance, fleeDistance,
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance, tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance, aoeRadius, rpgDistance,
fleeDistance, tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance, targetPosRecalcDistance, farDistance, healDistance, aggroDistance;
aoeRadius, rpgDistance, targetPosRecalcDistance, farDistance, healDistance, aggroDistance;
uint32 criticalHealth, lowHealth, mediumHealth, almostFullHealth; uint32 criticalHealth, lowHealth, mediumHealth, almostFullHealth;
uint32 lowMana, mediumMana; uint32 lowMana, mediumMana;
bool autoSaveMana; bool autoSaveMana;
@ -118,7 +118,6 @@ class PlayerbotAIConfig
uint32 randomBotMinLevel, randomBotMaxLevel; uint32 randomBotMinLevel, randomBotMaxLevel;
float randomChangeMultiplier; float randomChangeMultiplier;
// std::string premadeLevelSpec[MAX_CLASSES][10][91]; //lvl 10 - 100 // std::string premadeLevelSpec[MAX_CLASSES][10][91]; //lvl 10 - 100
// ClassSpecs classSpecs[MAX_CLASSES]; // ClassSpecs classSpecs[MAX_CLASSES];
@ -244,9 +243,16 @@ class PlayerbotAIConfig
int32 autoGearCommand, autoGearQualityLimit, autoGearScoreLimit; int32 autoGearCommand, autoGearQualityLimit, autoGearScoreLimit;
std::string const GetTimestampStr(); std::string const GetTimestampStr();
bool hasLog(std::string const fileName) { return std::find(allowedLogFiles.begin(), allowedLogFiles.end(), fileName) != allowedLogFiles.end(); }; bool hasLog(std::string const fileName)
{
return std::find(allowedLogFiles.begin(), allowedLogFiles.end(), fileName) != allowedLogFiles.end();
};
bool openLog(std::string const fileName, char const* mode = "a"); bool openLog(std::string const fileName, char const* mode = "a");
bool isLogOpen(std::string const fileName) { auto it = logFiles.find(fileName); return it != logFiles.end() && it->second.second; } bool isLogOpen(std::string const fileName)
{
auto it = logFiles.find(fileName);
return it != logFiles.end() && it->second.second;
}
void log(std::string const fileName, const char* str, ...); void log(std::string const fileName, const char* str, ...);
void loadWorldBuf(uint32 factionId, uint32 classId, uint32 minLevel, uint32 maxLevel); void loadWorldBuf(uint32 factionId, uint32 classId, uint32 minLevel, uint32 maxLevel);

View File

@ -1,18 +1,19 @@
/* /*
* 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. * 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 "PlayerbotCommandServer.h" #include "PlayerbotCommandServer.h"
#include "IoContext.h"
#include "Playerbots.h"
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/thread/thread.hpp>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <boost/bind.hpp> #include "IoContext.h"
#include <boost/smart_ptr.hpp> #include "Playerbots.h"
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
typedef boost::shared_ptr<tcp::socket> socket_ptr; typedef boost::shared_ptr<tcp::socket> socket_ptr;

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_PLAYERBOTCOMMANDSERVER_H #ifndef _PLAYERBOT_PLAYERBOTCOMMANDSERVER_H

View File

@ -1,12 +1,14 @@
/* /*
* 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. * 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 "PlayerbotDbStore.h" #include "PlayerbotDbStore.h"
#include "Playerbots.h"
#include <iostream> #include <iostream>
#include "Playerbots.h"
void PlayerbotDbStore::Load(PlayerbotAI* botAI) void PlayerbotDbStore::Load(PlayerbotAI* botAI)
{ {
ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter(); ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter();
@ -35,8 +37,7 @@ void PlayerbotDbStore::Load(PlayerbotAI* botAI)
botAI->ChangeStrategy(value, BOT_STATE_NON_COMBAT); botAI->ChangeStrategy(value, BOT_STATE_NON_COMBAT);
else if (key == "dead") else if (key == "dead")
botAI->ChangeStrategy(value, BOT_STATE_DEAD); botAI->ChangeStrategy(value, BOT_STATE_DEAD);
} } while (result->NextRow());
while (result->NextRow());
botAI->GetAiObjectContext()->Load(values); botAI->GetAiObjectContext()->Load(values);
} }

View File

@ -1,14 +1,15 @@
/* /*
* 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. * 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_PLAYERBOTDBSTORE_H #ifndef _PLAYERBOT_PLAYERBOTDBSTORE_H
#define _PLAYERBOT_PLAYERBOTDBSTORE_H #define _PLAYERBOT_PLAYERBOTDBSTORE_H
#include "Common.h"
#include <vector> #include <vector>
#include "Common.h"
class PlayerbotAI; class PlayerbotAI;
class PlayerbotDbStore class PlayerbotDbStore

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "PlayerbotDungeonSuggestionMgr.h" #include "PlayerbotDungeonSuggestionMgr.h"
#include "Playerbots.h" #include "Playerbots.h"
std::vector<DungeonSuggestion> const PlayerbotDungeonSuggestionMgr::GetDungeonSuggestions() std::vector<DungeonSuggestion> const PlayerbotDungeonSuggestionMgr::GetDungeonSuggestions()
@ -33,22 +35,14 @@ void PlayerbotDungeonSuggestionMgr::LoadDungeonSuggestions()
std::string const abbrevation = fields[4].Get<std::string>(); std::string const abbrevation = fields[4].Get<std::string>();
std::string const strategy = fields[5].Get<std::string>(); std::string const strategy = fields[5].Get<std::string>();
DungeonSuggestion const row = DungeonSuggestion const row = {
{ name, static_cast<Difficulty>(difficulty), min_level, max_level, abbrevation, strategy};
name,
static_cast<Difficulty>(difficulty),
min_level,
max_level,
abbrevation,
strategy
};
m_dungeonSuggestions.push_back(row); m_dungeonSuggestions.push_back(row);
++count; ++count;
} } while (result->NextRow());
while (result->NextRow());
} }
LOG_INFO("server.loading", "{} playerbots dungeon suggestions loaded in {} ms", LOG_INFO("server.loading", "{} playerbots dungeon suggestions loaded in {} ms", count,
count, GetMSTimeDiffToNow(oldMSTime)); GetMSTimeDiffToNow(oldMSTime));
} }

View File

@ -1,16 +1,17 @@
/* /*
* 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. * 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_PLAYERBOTDUNGEONSUGGESTIONMGR_H #ifndef _PLAYERBOT_PLAYERBOTDUNGEONSUGGESTIONMGR_H
#define _PLAYERBOT_PLAYERBOTDUNGEONSUGGESTIONMGR_H #define _PLAYERBOT_PLAYERBOTDUNGEONSUGGESTIONMGR_H
#include "Common.h"
#include "DBCEnums.h"
#include <map> #include <map>
#include <vector> #include <vector>
#include "Common.h"
#include "DBCEnums.h"
struct DungeonSuggestion struct DungeonSuggestion
{ {
std::string name; std::string name;

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_PLAYERBOTFACTORY_H #ifndef _PLAYERBOT_PLAYERBOTFACTORY_H
@ -137,6 +138,7 @@ class PlayerbotFactory
void ApplyEnchantAndGemsNew(bool destoryOld = true); void ApplyEnchantAndGemsNew(bool destoryOld = true);
void InitInstanceQuests(); void InitInstanceQuests();
void UnbindInstance(); void UnbindInstance();
private: private:
void Prepare(); void Prepare();
// void InitSecondEquipmentSet(); // void InitSecondEquipmentSet();
@ -194,6 +196,7 @@ class PlayerbotFactory
std::vector<uint32> trainerIdCache; std::vector<uint32> trainerIdCache;
static std::vector<uint32> enchantSpellIdCache; static std::vector<uint32> enchantSpellIdCache;
static std::vector<uint32> enchantGemIdCache; static std::vector<uint32> enchantGemIdCache;
protected: protected:
EnchantContainer m_EnchantContainer; EnchantContainer m_EnchantContainer;
Player* bot; Player* bot;

View File

@ -1,7 +1,16 @@
/* /*
* 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. * 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 "PlayerbotMgr.h"
#include <cstdio>
#include <cstring>
#include <istream>
#include <string>
#include "ChannelMgr.h"
#include "CharacterCache.h" #include "CharacterCache.h"
#include "CharacterPackets.h" #include "CharacterPackets.h"
#include "Common.h" #include "Common.h"
@ -11,22 +20,14 @@
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "PlayerbotAIConfig.h" #include "PlayerbotAIConfig.h"
#include "PlayerbotMgr.h"
#include "PlayerbotSecurity.h"
#include "Playerbots.h"
#include "PlayerbotDbStore.h" #include "PlayerbotDbStore.h"
#include "PlayerbotFactory.h" #include "PlayerbotFactory.h"
#include "PlayerbotSecurity.h"
#include "Playerbots.h"
#include "SharedDefines.h" #include "SharedDefines.h"
#include "WorldSession.h" #include "WorldSession.h"
#include "ChannelMgr.h"
#include <cstdio>
#include <cstring>
#include <istream>
#include <string>
PlayerbotHolder::PlayerbotHolder() : PlayerbotAIBase(false) PlayerbotHolder::PlayerbotHolder() : PlayerbotAIBase(false) {}
{
}
class PlayerbotLoginQueryHolder : public LoginQueryHolder class PlayerbotLoginQueryHolder : public LoginQueryHolder
{ {
@ -36,7 +37,9 @@ class PlayerbotLoginQueryHolder : public LoginQueryHolder
public: public:
PlayerbotLoginQueryHolder(PlayerbotHolder* playerbotHolder, uint32 masterAccount, uint32 accountId, ObjectGuid guid) PlayerbotLoginQueryHolder(PlayerbotHolder* playerbotHolder, uint32 masterAccount, uint32 accountId, ObjectGuid guid)
: LoginQueryHolder(accountId, guid), masterAccountId(masterAccount), playerbotHolder(playerbotHolder) { } : LoginQueryHolder(accountId, guid), masterAccountId(masterAccount), playerbotHolder(playerbotHolder)
{
}
uint32 GetMasterAccountId() const { return masterAccountId; } uint32 GetMasterAccountId() const { return masterAccountId; }
PlayerbotHolder* GetPlayerbotHolder() { return playerbotHolder; } PlayerbotHolder* GetPlayerbotHolder() { return playerbotHolder; }
@ -53,7 +56,8 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
if (!accountId) if (!accountId)
return; return;
std::shared_ptr<PlayerbotLoginQueryHolder> holder = std::make_shared<PlayerbotLoginQueryHolder>(this, masterAccountId, accountId, playerGuid); std::shared_ptr<PlayerbotLoginQueryHolder> holder =
std::make_shared<PlayerbotLoginQueryHolder>(this, masterAccountId, accountId, playerGuid);
if (!holder->Initialize()) if (!holder->Initialize())
{ {
return; return;
@ -61,17 +65,15 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
if (WorldSession* masterSession = sWorld->FindSession(masterAccountId)) if (WorldSession* masterSession = sWorld->FindSession(masterAccountId))
{ {
masterSession->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder) masterSession->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder))
{ .AfterComplete([this](SQLQueryHolderBase const& holder)
HandlePlayerBotLoginCallback(static_cast<PlayerbotLoginQueryHolder const&>(holder)); { HandlePlayerBotLoginCallback(static_cast<PlayerbotLoginQueryHolder const&>(holder)); });
});
} }
else else
{ {
sWorld->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder) sWorld->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder))
{ .AfterComplete([this](SQLQueryHolderBase const& holder)
HandlePlayerBotLoginCallback(static_cast<PlayerbotLoginQueryHolder const&>(holder)); { HandlePlayerBotLoginCallback(static_cast<PlayerbotLoginQueryHolder const&>(holder)); });
});
} }
} }
@ -79,14 +81,17 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
{ {
// has bot already been added? // has bot already been added?
Player* loginBot = ObjectAccessor::FindConnectedPlayer(holder.GetGuid()); Player* loginBot = ObjectAccessor::FindConnectedPlayer(holder.GetGuid());
if (loginBot && loginBot->IsInWorld()) { if (loginBot && loginBot->IsInWorld())
{
return; return;
} }
uint32 botAccountId = holder.GetAccountId(); uint32 botAccountId = holder.GetAccountId();
// 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) // At login DBC locale should be what the server is set to use by default (as spells etc are hardcoded to ENUS this
WorldSession* botSession = new WorldSession(botAccountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING, time_t(0), sWorld->GetDefaultDbcLocale(), 0, false, false, 0, true); // 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
@ -95,7 +100,8 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
{ {
botSession->LogoutPlayer(true); botSession->LogoutPlayer(true);
delete botSession; delete botSession;
// LOG_ERROR("playerbots", "Error logging in bot {}, please try to reset all random bots", holder.GetGuid().ToString().c_str()); // LOG_ERROR("playerbots", "Error logging in bot {}, please try to reset all random bots",
// holder.GetGuid().ToString().c_str());
return; return;
} }
@ -103,25 +109,37 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
WorldSession* masterSession = masterAccount ? sWorld->FindSession(masterAccount) : nullptr; WorldSession* masterSession = masterAccount ? sWorld->FindSession(masterAccount) : nullptr;
std::ostringstream out; std::ostringstream out;
bool allowed = false; bool allowed = false;
if (botAccountId == masterAccount) { if (botAccountId == masterAccount)
{
allowed = true; allowed = true;
} else if (masterSession && sPlayerbotAIConfig->allowGuildBots && bot->GetGuildId() != 0 && bot->GetGuildId() == masterSession->GetPlayer()->GetGuildId()) { }
else if (masterSession && sPlayerbotAIConfig->allowGuildBots && bot->GetGuildId() != 0 &&
bot->GetGuildId() == masterSession->GetPlayer()->GetGuildId())
{
allowed = true; allowed = true;
} else if (sPlayerbotAIConfig->IsInRandomAccountList(botAccountId)) { }
else if (sPlayerbotAIConfig->IsInRandomAccountList(botAccountId))
{
allowed = true; allowed = true;
} else { }
else
{
allowed = false; allowed = false;
out << "Failure: You are not allowed to control bot " << bot->GetName().c_str(); out << "Failure: You are not allowed to control bot " << bot->GetName().c_str();
} }
if (allowed && masterSession) { if (allowed && masterSession)
{
Player* player = masterSession->GetPlayer(); Player* player = masterSession->GetPlayer();
PlayerbotMgr* mgr = GET_PLAYERBOT_MGR(player); PlayerbotMgr* mgr = GET_PLAYERBOT_MGR(player);
uint32 count = mgr->GetPlayerbotsCount(); uint32 count = mgr->GetPlayerbotsCount();
uint32 cls_count = mgr->GetPlayerbotsCountByClass(bot->getClass()); uint32 cls_count = mgr->GetPlayerbotsCountByClass(bot->getClass());
if (count >= sPlayerbotAIConfig->maxAddedBots) { if (count >= sPlayerbotAIConfig->maxAddedBots)
{
allowed = false; allowed = false;
out << "Failure: You have added too many bots"; out << "Failure: You have added too many bots";
} else if (cls_count >= sPlayerbotAIConfig->maxAddedBotsPerClass) { }
else if (cls_count >= sPlayerbotAIConfig->maxAddedBotsPerClass)
{
allowed = false; allowed = false;
out << "Failure: You have added too many bots for this class"; out << "Failure: You have added too many bots for this class";
} }
@ -143,7 +161,8 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
// OnBotLogin(bot); // OnBotLogin(bot);
// LogoutPlayerBot(bot->GetGUID()); // LogoutPlayerBot(bot->GetGUID());
// LOG_ERROR("playerbots", "Attempt to add not allowed bot {}, please try to reset all random bots", bot->GetName()); // LOG_ERROR("playerbots", "Attempt to add not allowed bot {}, please try to reset all random bots",
// bot->GetName());
} }
} }
@ -155,7 +174,8 @@ void PlayerbotHolder::UpdateSessions()
if (bot->IsBeingTeleported()) if (bot->IsBeingTeleported())
{ {
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (botAI) { if (botAI)
{
botAI->HandleTeleportAck(); botAI->HandleTeleportAck();
} }
} }
@ -229,7 +249,8 @@ void PlayerbotMgr::CancelLogout()
} }
} }
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin(); it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it) for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{ {
Player* const bot = it->second; Player* const bot = it->second;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@ -289,8 +310,10 @@ void PlayerbotHolder::LogoutPlayerBot(ObjectGuid guid)
logout = true; logout = true;
} }
if (master && (master->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || master->HasUnitState(UNIT_STATE_IN_FLIGHT) || if (master &&
(masterWorldSessionPtr && masterWorldSessionPtr->GetSecurity() >= (AccountTypes)sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT)))) (master->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || master->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
(masterWorldSessionPtr &&
masterWorldSessionPtr->GetSecurity() >= (AccountTypes)sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))))
{ {
logout = true; logout = true;
} }
@ -347,7 +370,8 @@ void PlayerbotHolder::DisablePlayerBot(ObjectGuid guid)
if (Player* bot = GetPlayerBot(guid)) if (Player* bot = GetPlayerBot(guid))
{ {
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return; return;
} }
botAI->TellMaster("Goodbye!"); botAI->TellMaster("Goodbye!");
@ -393,7 +417,8 @@ Player* PlayerbotHolder::GetPlayerBot(ObjectGuid::LowType lowGuid) const
void PlayerbotHolder::OnBotLogin(Player* const bot) void PlayerbotHolder::OnBotLogin(Player* const bot)
{ {
// Prevent duplicate login // Prevent duplicate login
if (playerBots.find(bot->GetGUID()) != playerBots.end()) { if (playerBots.find(bot->GetGUID()) != playerBots.end())
{
return; return;
} }
@ -401,9 +426,9 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
playerBots[bot->GetGUID()] = bot; playerBots[bot->GetGUID()] = bot;
OnBotLoginInternal(bot); OnBotLoginInternal(bot);
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return; return;
} }
Player* master = botAI->GetMaster(); Player* master = botAI->GetMaster();
@ -475,19 +500,27 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
botAI->TellMaster("Hello!", PLAYERBOT_SECURITY_TALK); botAI->TellMaster("Hello!", PLAYERBOT_SECURITY_TALK);
if (master && master->GetGroup() && !group) { if (master && master->GetGroup() && !group)
{
Group* mgroup = master->GetGroup(); Group* mgroup = master->GetGroup();
if (mgroup->GetMembersCount() >= 5) { if (mgroup->GetMembersCount() >= 5)
if (!mgroup->isRaidGroup() && !mgroup->isLFGGroup() && !mgroup->isBGGroup() && !mgroup->isBFGroup()) { {
if (!mgroup->isRaidGroup() && !mgroup->isLFGGroup() && !mgroup->isBGGroup() && !mgroup->isBFGroup())
{
mgroup->ConvertToRaid(); mgroup->ConvertToRaid();
} }
if (mgroup->isRaidGroup()) { if (mgroup->isRaidGroup())
{
mgroup->AddMember(bot); mgroup->AddMember(bot);
} }
} else { }
else
{
mgroup->AddMember(bot); mgroup->AddMember(bot);
} }
} else if (master && !group) { }
else if (master && !group)
{
Group* newGroup = new Group(); Group* newGroup = new Group();
newGroup->Create(master); newGroup->Create(master);
sGroupMgr->AddGroup(newGroup); sGroupMgr->AddGroup(newGroup);
@ -497,23 +530,29 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
uint32 accountId = bot->GetSession()->GetAccountId(); uint32 accountId = bot->GetSession()->GetAccountId();
bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(accountId); bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(accountId);
if (isRandomAccount && sPlayerbotAIConfig->randomBotFixedLevel) { if (isRandomAccount && sPlayerbotAIConfig->randomBotFixedLevel)
{
bot->SetPlayerFlag(PLAYER_FLAGS_NO_XP_GAIN); bot->SetPlayerFlag(PLAYER_FLAGS_NO_XP_GAIN);
} else if (isRandomAccount && !sPlayerbotAIConfig->randomBotFixedLevel) { }
else if (isRandomAccount && !sPlayerbotAIConfig->randomBotFixedLevel)
{
bot->RemovePlayerFlag(PLAYER_FLAGS_NO_XP_GAIN); bot->RemovePlayerFlag(PLAYER_FLAGS_NO_XP_GAIN);
} }
bot->SaveToDB(false, false); bot->SaveToDB(false, false);
if (master && isRandomAccount && master->GetLevel() < bot->GetLevel()) { if (master && isRandomAccount && master->GetLevel() < bot->GetLevel())
{
// PlayerbotFactory factory(bot, master->GetLevel()); // PlayerbotFactory factory(bot, master->GetLevel());
// factory.Randomize(false); // factory.Randomize(false);
uint32 mixedGearScore = PlayerbotAI::GetMixedGearScore(master, true, false, 12) * sPlayerbotAIConfig->autoInitEquipLevelLimitRatio; uint32 mixedGearScore =
PlayerbotAI::GetMixedGearScore(master, true, false, 12) * sPlayerbotAIConfig->autoInitEquipLevelLimitRatio;
PlayerbotFactory factory(bot, master->GetLevel(), ITEM_QUALITY_LEGENDARY, mixedGearScore); PlayerbotFactory factory(bot, master->GetLevel(), ITEM_QUALITY_LEGENDARY, mixedGearScore);
factory.Randomize(false); factory.Randomize(false);
} }
// bots join World chat if not solo oriented // bots join World chat if not solo oriented
if (bot->GetLevel() >= 10 && sRandomPlayerbotMgr->IsRandomBot(bot) && GET_PLAYERBOT_AI(bot) && GET_PLAYERBOT_AI(bot)->GetGrouperType() != GrouperType::SOLO) if (bot->GetLevel() >= 10 && sRandomPlayerbotMgr->IsRandomBot(bot) && GET_PLAYERBOT_AI(bot) &&
GET_PLAYERBOT_AI(bot)->GetGrouperType() != GrouperType::SOLO)
{ {
// TODO make action/config // TODO make action/config
// Make the bot join the world channel for chat // Make the bot join the world channel for chat
@ -533,7 +572,8 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
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;
bool isLfg = (channel->flags & CHANNEL_DBC_FLAG_LFG) != 0; bool isLfg = (channel->flags & CHANNEL_DBC_FLAG_LFG) != 0;
@ -551,7 +591,8 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
else else
{ {
char new_channel_name_buf[100]; char new_channel_name_buf[100];
snprintf(new_channel_name_buf, 100, channel->pattern[sWorld->GetDefaultDbcLocale()], 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)
@ -560,7 +601,8 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
} }
} }
std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, ObjectGuid guid, ObjectGuid masterguid, bool admin, uint32 masterAccountId, uint32 masterGuildId) std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, ObjectGuid guid, ObjectGuid masterguid,
bool admin, uint32 masterAccountId, uint32 masterGuildId)
{ {
if (!sPlayerbotAIConfig->enabled || guid.IsEmpty()) if (!sPlayerbotAIConfig->enabled || guid.IsEmpty())
return "bot system is disabled"; return "bot system is disabled";
@ -573,7 +615,8 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
if (!isRandomAccount && !isMasterAccount && !admin && masterguid) if (!isRandomAccount && !isMasterAccount && !admin && masterguid)
{ {
Player* master = ObjectAccessor::FindConnectedPlayer(masterguid); Player* master = ObjectAccessor::FindConnectedPlayer(masterguid);
if (master && (!sPlayerbotAIConfig->allowGuildBots || !masterGuildId || (masterGuildId && sCharacterCache->GetCharacterGuildIdByGuid(guid) != masterGuildId))) if (master && (!sPlayerbotAIConfig->allowGuildBots || !masterGuildId ||
(masterGuildId && sCharacterCache->GetCharacterGuildIdByGuid(guid) != masterGuildId)))
return "not in your guild or account"; return "not in your guild or account";
} }
@ -609,21 +652,27 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
if (!bot) if (!bot)
return "bot not found"; return "bot not found";
if (!isRandomAccount || isRandomBot) { if (!isRandomAccount || isRandomBot)
{
return "ERROR: You can not use this command on non-summoned random bot."; return "ERROR: You can not use this command on non-summoned random bot.";
} }
if (!admin) { if (!admin)
{
Player* master = ObjectAccessor::FindConnectedPlayer(masterguid); Player* master = ObjectAccessor::FindConnectedPlayer(masterguid);
if (master && (master->IsInCombat() || bot->IsInCombat())) { if (master && (master->IsInCombat() || bot->IsInCombat()))
{
return "ERROR: You can not use this command during combat."; return "ERROR: You can not use this command during combat.";
} }
} }
if (GET_PLAYERBOT_AI(bot)) { if (GET_PLAYERBOT_AI(bot))
{
if (Player* master = GET_PLAYERBOT_AI(bot)->GetMaster()) if (Player* master = GET_PLAYERBOT_AI(bot)->GetMaster())
{ {
if (master->GetSession()->GetSecurity() <= SEC_PLAYER && sPlayerbotAIConfig->autoInitOnly && cmd != "init=auto") { if (master->GetSession()->GetSecurity() <= SEC_PLAYER && sPlayerbotAIConfig->autoInitOnly &&
cmd != "init=auto")
{
return "The command is not allowed, use init=auto instead."; return "The command is not allowed, use init=auto instead.";
} }
int gs; int gs;
@ -659,10 +708,12 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
} }
else if (cmd == "init=auto") else if (cmd == "init=auto")
{ {
uint32 mixedGearScore = PlayerbotAI::GetMixedGearScore(master, true, false, 12) * sPlayerbotAIConfig->autoInitEquipLevelLimitRatio; uint32 mixedGearScore = PlayerbotAI::GetMixedGearScore(master, true, false, 12) *
sPlayerbotAIConfig->autoInitEquipLevelLimitRatio;
PlayerbotFactory factory(bot, master->GetLevel(), ITEM_QUALITY_LEGENDARY, mixedGearScore); PlayerbotFactory factory(bot, master->GetLevel(), ITEM_QUALITY_LEGENDARY, mixedGearScore);
factory.Randomize(false); factory.Randomize(false);
return "ok, gear score limit: " + std::to_string(mixedGearScore / (ITEM_QUALITY_EPIC + 1)) + "(for epic)"; return "ok, gear score limit: " + std::to_string(mixedGearScore / (ITEM_QUALITY_EPIC + 1)) +
"(for epic)";
} }
else if (cmd.starts_with("init=") && sscanf(cmd.c_str(), "init=%d", &gs) != -1) else if (cmd.starts_with("init=") && sscanf(cmd.c_str(), "init=%d", &gs) != -1)
{ {
@ -698,7 +749,8 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
sRandomPlayerbotMgr->Randomize(bot); sRandomPlayerbotMgr->Randomize(bot);
return "ok"; return "ok";
} }
else if (cmd == "quests"){ else if (cmd == "quests")
{
PlayerbotFactory factory(bot, bot->GetLevel()); PlayerbotFactory factory(bot, bot->GetLevel());
factory.InitInstanceQuests(); factory.InitInstanceQuests();
return "Initialization quests"; return "Initialization quests";
@ -762,53 +814,70 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
return messages; return messages;
} }
if (!strcmp(cmd, "initself")) { if (!strcmp(cmd, "initself"))
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) { {
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
{
// OnBotLogin(master); // OnBotLogin(master);
PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_EPIC); PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_EPIC);
factory.Randomize(false); factory.Randomize(false);
messages.push_back("initself ok"); messages.push_back("initself ok");
return messages; return messages;
} else { }
else
{
messages.push_back("ERROR: Only GM can use this command."); messages.push_back("ERROR: Only GM can use this command.");
return messages; return messages;
} }
} }
if (!strncmp(cmd, "initself=", 9)) { if (!strncmp(cmd, "initself=", 9))
if (!strcmp(cmd, "initself=rare")) { {
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) { if (!strcmp(cmd, "initself=rare"))
{
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
{
// OnBotLogin(master); // OnBotLogin(master);
PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_RARE); PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_RARE);
factory.Randomize(false); factory.Randomize(false);
messages.push_back("initself ok"); messages.push_back("initself ok");
return messages; return messages;
} else { }
else
{
messages.push_back("ERROR: Only GM can use this command."); messages.push_back("ERROR: Only GM can use this command.");
return messages; return messages;
} }
} }
if (!strcmp(cmd, "initself=epic")) { if (!strcmp(cmd, "initself=epic"))
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) { {
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
{
// OnBotLogin(master); // OnBotLogin(master);
PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_EPIC); PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_EPIC);
factory.Randomize(false); factory.Randomize(false);
messages.push_back("initself ok"); messages.push_back("initself ok");
return messages; return messages;
} else { }
else
{
messages.push_back("ERROR: Only GM can use this command."); messages.push_back("ERROR: Only GM can use this command.");
return messages; return messages;
} }
} }
int32 gs; int32 gs;
if (sscanf(cmd, "initself=%d", &gs) != -1) { if (sscanf(cmd, "initself=%d", &gs) != -1)
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) { {
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
{
// OnBotLogin(master); // OnBotLogin(master);
PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_LEGENDARY, gs); PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_LEGENDARY, gs);
factory.Randomize(false); factory.Randomize(false);
messages.push_back("initself ok, gs = " + std::to_string(gs)); messages.push_back("initself ok, gs = " + std::to_string(gs));
return messages; return messages;
} else { }
else
{
messages.push_back("ERROR: Only GM can use this command."); messages.push_back("ERROR: Only GM can use this command.");
return messages; return messages;
} }
@ -867,12 +936,15 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
if (!strcmp(cmd, "addclass")) if (!strcmp(cmd, "addclass"))
{ {
if (sPlayerbotAIConfig->addClassCommand == 0 && master->GetSession()->GetSecurity() < SEC_GAMEMASTER) { if (sPlayerbotAIConfig->addClassCommand == 0 && master->GetSession()->GetSecurity() < SEC_GAMEMASTER)
{
messages.push_back("You do not have permission to create bot by addclass command"); messages.push_back("You do not have permission to create bot by addclass command");
return messages; return messages;
} }
if (!charname) { if (!charname)
messages.push_back("addclass: invalid CLASSNAME(warrior/paladin/hunter/rogue/priest/shaman/mage/warlock/druid/dk)"); {
messages.push_back(
"addclass: invalid CLASSNAME(warrior/paladin/hunter/rogue/priest/shaman/mage/warlock/druid/dk)");
return messages; return messages;
} }
uint8 claz; uint8 claz;
@ -942,10 +1014,13 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
} }
uint32 maxAccountId = sPlayerbotAIConfig->randomBotAccounts.back(); uint32 maxAccountId = sPlayerbotAIConfig->randomBotAccounts.back();
// find a bot fit conditions and not in any guild // find a bot fit conditions and not in any guild
QueryResult results = CharacterDatabase.Query("SELECT guid FROM characters " QueryResult results = CharacterDatabase.Query(
"WHERE name IN (SELECT name FROM playerbots_names) AND class = '{}' AND online = 0 AND race IN ({}) AND guid NOT IN ( SELECT guid FROM guild_member ) " "SELECT guid FROM characters "
"WHERE name IN (SELECT name FROM playerbots_names) AND class = '{}' AND online = 0 AND race IN ({}) AND "
"guid NOT IN ( SELECT guid FROM guild_member ) "
"AND account <= {} " "AND account <= {} "
"ORDER BY account DESC LIMIT 1", claz, race_limit, maxAccountId); "ORDER BY account DESC LIMIT 1",
claz, race_limit, maxAccountId);
if (results) if (results)
{ {
Field* fields = results->Fetch(); Field* fields = results->Fetch();
@ -966,13 +1041,18 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
std::string name; std::string name;
bool isPlayer = sCharacterCache->GetCharacterNameByGuid(master->GetTarget(), name); bool isPlayer = sCharacterCache->GetCharacterNameByGuid(master->GetTarget(), name);
// Player* tPlayer = ObjectAccessor::FindConnectedPlayer(master->GetTarget()); // Player* tPlayer = ObjectAccessor::FindConnectedPlayer(master->GetTarget());
if (isPlayer) { if (isPlayer)
{
charnameStr = name; charnameStr = name;
} else { }
else
{
messages.push_back("usage: list/reload/tweak/self or add/init/remove PLAYERNAME"); messages.push_back("usage: list/reload/tweak/self or add/init/remove PLAYERNAME");
return messages; return messages;
} }
} else { }
else
{
charnameStr = charname; charnameStr = charname;
} }
@ -1050,7 +1130,9 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
} }
else if (master && member != master->GetGUID()) else if (master && member != master->GetGUID())
{ {
out << ProcessBotCommand(cmdStr, member, master->GetGUID(), master->GetSession()->GetSecurity() >= SEC_GAMEMASTER, master->GetSession()->GetAccountId(), master->GetGuildId()); out << ProcessBotCommand(cmdStr, member, master->GetGUID(),
master->GetSession()->GetSecurity() >= SEC_GAMEMASTER,
master->GetSession()->GetAccountId(), master->GetGuildId());
} }
else if (!master) else if (!master)
{ {
@ -1063,10 +1145,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
return messages; return messages;
} }
uint32 PlayerbotHolder::GetAccountId(std::string const name) uint32 PlayerbotHolder::GetAccountId(std::string const name) { return AccountMgr::GetId(name); }
{
return AccountMgr::GetId(name);
}
uint32 PlayerbotHolder::GetAccountId(ObjectGuid guid) uint32 PlayerbotHolder::GetAccountId(ObjectGuid guid)
{ {
@ -1122,7 +1201,8 @@ std::string const PlayerbotHolder::ListBots(Player* master)
if (master) if (master)
{ {
QueryResult results = CharacterDatabase.Query("SELECT class, name FROM characters WHERE account = {}", master->GetSession()->GetAccountId()); QueryResult results = CharacterDatabase.Query("SELECT class, name FROM characters WHERE account = {}",
master->GetSession()->GetAccountId());
if (results) if (results)
{ {
do do
@ -1192,7 +1272,8 @@ std::string const PlayerbotHolder::LookupBots(Player* master)
messages.push_back("DK"); messages.push_back("DK");
messages.push_back("(Usage: .bot lookup CLASS)"); messages.push_back("(Usage: .bot lookup CLASS)");
std::string ret_msg; std::string ret_msg;
for (std::string msg: messages) { for (std::string msg : messages)
{
ret_msg += msg + "\n"; ret_msg += msg + "\n";
} }
return ret_msg; return ret_msg;
@ -1204,16 +1285,15 @@ uint32 PlayerbotHolder::GetPlayerbotsCountByClass(uint32 cls)
for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it) for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it)
{ {
Player* const bot = it->second; Player* const bot = it->second;
if (bot->getClass() == cls) { if (bot->getClass() == cls)
{
count++; count++;
} }
} }
return count; return count;
} }
PlayerbotMgr::PlayerbotMgr(Player* const master) : PlayerbotHolder(), master(master), lastErrorTell(0) PlayerbotMgr::PlayerbotMgr(Player* const master) : PlayerbotHolder(), master(master), lastErrorTell(0) {}
{
}
PlayerbotMgr::~PlayerbotMgr() PlayerbotMgr::~PlayerbotMgr()
{ {
@ -1253,7 +1333,8 @@ void PlayerbotMgr::HandleCommand(uint32 type, std::string const text)
botAI->HandleCommand(type, text, master); botAI->HandleCommand(type, text, master);
} }
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin(); it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it) for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{ {
Player* const bot = it->second; Player* const bot = it->second;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@ -1274,7 +1355,8 @@ void PlayerbotMgr::HandleMasterIncomingPacket(WorldPacket const& packet)
botAI->HandleMasterIncomingPacket(packet); botAI->HandleMasterIncomingPacket(packet);
} }
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin(); it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it) for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{ {
Player* const bot = it->second; Player* const bot = it->second;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@ -1309,7 +1391,8 @@ void PlayerbotMgr::HandleMasterOutgoingPacket(WorldPacket const& packet)
botAI->HandleMasterOutgoingPacket(packet); botAI->HandleMasterOutgoingPacket(packet);
} }
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin(); it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it) for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{ {
Player* const bot = it->second; Player* const bot = it->second;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
@ -1326,7 +1409,8 @@ void PlayerbotMgr::SaveToDB()
bot->SaveToDB(false, false); bot->SaveToDB(false, false);
} }
for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin(); it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it) for (PlayerBotMap::const_iterator it = sRandomPlayerbotMgr->GetPlayerBotsBegin();
it != sRandomPlayerbotMgr->GetPlayerBotsEnd(); ++it)
{ {
Player* const bot = it->second; Player* const bot = it->second;
if (GET_PLAYERBOT_AI(bot) && GET_PLAYERBOT_AI(bot)->GetMaster() == GetMaster()) if (GET_PLAYERBOT_AI(bot) && GET_PLAYERBOT_AI(bot)->GetMaster() == GetMaster())
@ -1337,7 +1421,8 @@ void PlayerbotMgr::SaveToDB()
void PlayerbotMgr::OnBotLoginInternal(Player* const bot) void PlayerbotMgr::OnBotLoginInternal(Player* const bot)
{ {
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return; return;
} }
botAI->SetMaster(master); botAI->SetMaster(master);
@ -1458,13 +1543,16 @@ void PlayerbotsMgr::AddPlayerbotData(Player* player, bool isBotAI)
void PlayerbotsMgr::RemovePlayerBotData(ObjectGuid const& guid, bool is_AI) void PlayerbotsMgr::RemovePlayerBotData(ObjectGuid const& guid, bool is_AI)
{ {
if (is_AI) { if (is_AI)
{
std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsAIMap.find(guid); std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsAIMap.find(guid);
if (itr != _playerbotsAIMap.end()) if (itr != _playerbotsAIMap.end())
{ {
_playerbotsAIMap.erase(itr); _playerbotsAIMap.erase(itr);
} }
} else { }
else
{
std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsMgrMap.find(guid); std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsMgrMap.find(guid);
if (itr != _playerbotsMgrMap.end()) if (itr != _playerbotsMgrMap.end())
{ {

View File

@ -1,15 +1,16 @@
/* /*
* 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. * 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_PLAYERBOTMGR_H #ifndef _PLAYERBOT_PLAYERBOTMGR_H
#define _PLAYERBOT_PLAYERBOTMGR_H #define _PLAYERBOT_PLAYERBOTMGR_H
#include "Common.h" #include "Common.h"
#include "QueryHolder.h"
#include "QueryResult.h"
#include "Player.h" #include "Player.h"
#include "PlayerbotAIBase.h" #include "PlayerbotAIBase.h"
#include "QueryHolder.h"
#include "QueryResult.h"
class ChatHandler; class ChatHandler;
class PlayerbotAI; class PlayerbotAI;
@ -43,13 +44,15 @@ class PlayerbotHolder : public PlayerbotAIBase
void OnBotLogin(Player* const bot); void OnBotLogin(Player* const bot);
std::vector<std::string> HandlePlayerbotCommand(char const* args, Player* master = nullptr); std::vector<std::string> HandlePlayerbotCommand(char const* args, Player* master = nullptr);
std::string const ProcessBotCommand(std::string const cmd, ObjectGuid guid, ObjectGuid masterguid, bool admin, uint32 masterAccountId, uint32 masterGuildId); std::string const ProcessBotCommand(std::string const cmd, ObjectGuid guid, ObjectGuid masterguid, bool admin,
uint32 masterAccountId, uint32 masterGuildId);
uint32 GetAccountId(std::string const name); uint32 GetAccountId(std::string const name);
uint32 GetAccountId(ObjectGuid guid); uint32 GetAccountId(ObjectGuid guid);
std::string const ListBots(Player* master); std::string const ListBots(Player* master);
std::string const LookupBots(Player* master); std::string const LookupBots(Player* master);
uint32 GetPlayerbotsCount() { return playerBots.size(); } uint32 GetPlayerbotsCount() { return playerBots.size(); }
uint32 GetPlayerbotsCountByClass(uint32 cls); uint32 GetPlayerbotsCountByClass(uint32 cls);
protected: protected:
virtual void OnBotLoginInternal(Player* const bot) = 0; virtual void OnBotLoginInternal(Player* const bot) = 0;

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "PlayerbotSecurity.h" #include "PlayerbotSecurity.h"
#include "LFGMgr.h" #include "LFGMgr.h"
#include "PlayerbotAIConfig.h" #include "PlayerbotAIConfig.h"
#include "Playerbots.h" #include "Playerbots.h"
@ -19,7 +21,8 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
return PLAYERBOT_SECURITY_ALLOW_ALL; return PLAYERBOT_SECURITY_ALLOW_ALL;
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot); PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
if (!botAI) { if (!botAI)
{
return PLAYERBOT_SECURITY_DENY_ALL; return PLAYERBOT_SECURITY_DENY_ALL;
} }
if (botAI->IsOpposing(from)) if (botAI->IsOpposing(from))
@ -62,7 +65,8 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
} }
} }
if (sPlayerbotAIConfig->groupInvitationPermission <= 0) { if (sPlayerbotAIConfig->groupInvitationPermission <= 0)
{
if (reason) if (reason)
*reason = PLAYERBOT_DENY_NONE; *reason = PLAYERBOT_DENY_NONE;
@ -85,9 +89,11 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
if (sPlayerbotAIConfig->gearscorecheck) if (sPlayerbotAIConfig->gearscorecheck)
{ {
if (botGS && bot->GetLevel() > 15 && botGS > fromGS && if (botGS && bot->GetLevel() > 15 && botGS > fromGS &&
static_cast<float>(100 * (botGS - fromGS) / botGS) >= static_cast<float>(12 * sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) / from->GetLevel())) static_cast<float>(100 * (botGS - fromGS) / botGS) >=
static_cast<float>(12 * sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) / from->GetLevel()))
{ {
if (reason) *reason = PLAYERBOT_DENY_GEARSCORE; if (reason)
*reason = PLAYERBOT_DENY_GEARSCORE;
return PLAYERBOT_SECURITY_TALK; return PLAYERBOT_SECURITY_TALK;
} }
} }
@ -199,7 +205,8 @@ bool PlayerbotSecurity::CheckLevelFor(PlayerbotSecurityLevel level, bool silent,
out << "I'll do it later"; out << "I'll do it later";
break; break;
case PLAYERBOT_DENY_LOW_LEVEL: case PLAYERBOT_DENY_LOW_LEVEL:
out << "You are too low level: |cffff0000" << (uint32)from->GetLevel() << "|cffffffff/|cff00ff00" << (uint32)bot->GetLevel(); out << "You are too low level: |cffff0000" << (uint32)from->GetLevel() << "|cffffffff/|cff00ff00"
<< (uint32)bot->GetLevel();
break; break;
case PLAYERBOT_DENY_GEARSCORE: case PLAYERBOT_DENY_GEARSCORE:
{ {
@ -207,7 +214,8 @@ bool PlayerbotSecurity::CheckLevelFor(PlayerbotSecurityLevel level, bool silent,
int fromGS = (int)botAI->GetEquipGearScore(from, false, false); int fromGS = (int)botAI->GetEquipGearScore(from, false, false);
int diff = (100 * (botGS - fromGS) / botGS); int diff = (100 * (botGS - fromGS) / botGS);
int req = 12 * sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) / from->GetLevel(); int req = 12 * sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) / from->GetLevel();
out << "Your gearscore is too low: |cffff0000" << fromGS << "|cffffffff/|cff00ff00" << botGS << " |cffff0000" << diff << "%|cffffffff/|cff00ff00" << req << "%"; out << "Your gearscore is too low: |cffff0000" << fromGS << "|cffffffff/|cff00ff00" << botGS
<< " |cffff0000" << diff << "%|cffffffff/|cff00ff00" << req << "%";
} }
break; break;
case PLAYERBOT_DENY_NOT_YOURS: case PLAYERBOT_DENY_NOT_YOURS:
@ -244,7 +252,8 @@ bool PlayerbotSecurity::CheckLevelFor(PlayerbotSecurityLevel level, bool silent,
case PLAYERBOT_DENY_NOT_LEADER: case PLAYERBOT_DENY_NOT_LEADER:
if (botAI->GetGroupMaster()) if (botAI->GetGroupMaster())
{ {
out << "I am in a group with " << botAI->GetGroupMaster()->GetName() << ". You can ask him for invite."; out << "I am in a group with " << botAI->GetGroupMaster()->GetName()
<< ". You can ask him for invite.";
} }
else else
{ {

View File

@ -1,15 +1,16 @@
/* /*
* 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. * 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_PLAYERBOTSECURITY_H #ifndef _PLAYERBOT_PLAYERBOTSECURITY_H
#define _PLAYERBOT_PLAYERBOTSECURITY_H #define _PLAYERBOT_PLAYERBOTSECURITY_H
#include <map>
#include "Common.h" #include "Common.h"
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include <map>
class Player; class Player;
enum PlayerbotSecurityLevel : uint32 enum PlayerbotSecurityLevel : uint32

View File

@ -1,15 +1,19 @@
/* /*
* 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. * 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 "PlayerbotTextMgr.h" #include "PlayerbotTextMgr.h"
#include "Playerbots.h" #include "Playerbots.h"
void PlayerbotTextMgr::replaceAll(std::string & str, const std::string & from, const std::string & to) { void PlayerbotTextMgr::replaceAll(std::string& str, const std::string& from, const std::string& to)
{
if (from.empty()) if (from.empty())
return; return;
size_t start_pos = 0; size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos) { while ((start_pos = str.find(from, start_pos)) != std::string::npos)
{
str.replace(start_pos, from.length(), to); str.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
} }
@ -20,7 +24,8 @@ void PlayerbotTextMgr::LoadBotTexts()
LOG_INFO("playerbots", "Loading playerbots texts..."); LOG_INFO("playerbots", "Loading playerbots texts...");
uint32 count = 0; uint32 count = 0;
if (PreparedQueryResult result = PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TEXT))) if (PreparedQueryResult result =
PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TEXT)))
{ {
do do
{ {
@ -37,8 +42,7 @@ void PlayerbotTextMgr::LoadBotTexts()
botTexts[name].push_back(BotTextEntry(name, text, sayType, replyType)); botTexts[name].push_back(BotTextEntry(name, text, sayType, replyType));
++count; ++count;
} } while (result->NextRow());
while (result->NextRow());
} }
LOG_INFO("playerbots", "{} playerbots texts loaded", count); LOG_INFO("playerbots", "{} playerbots texts loaded", count);
@ -123,14 +127,14 @@ std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::map<std::
return ""; return "";
BotTextEntry textEntry = proper_list[urand(0, proper_list.size() - 1)]; BotTextEntry textEntry = proper_list[urand(0, proper_list.size() - 1)];
std::string botText = !textEntry.m_text[GetLocalePriority()].empty() ? textEntry.m_text[GetLocalePriority()] : textEntry.m_text[0]; std::string botText =
!textEntry.m_text[GetLocalePriority()].empty() ? textEntry.m_text[GetLocalePriority()] : textEntry.m_text[0];
for (auto& placeholder : placeholders) for (auto& placeholder : placeholders)
replaceAll(botText, placeholder.first, placeholder.second); replaceAll(botText, placeholder.first, placeholder.second);
return botText; return botText;
} }
std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::string name) std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::string name)
{ {
std::map<std::string, std::string> placeholders; std::map<std::string, std::string> placeholders;
@ -167,7 +171,6 @@ bool PlayerbotTextMgr::GetBotText(std::string name, std::string& text, std::map<
return !text.empty(); return !text.empty();
} }
void PlayerbotTextMgr::AddLocalePriority(uint32 locale) void PlayerbotTextMgr::AddLocalePriority(uint32 locale)
{ {
if (!locale) if (!locale)

View File

@ -1,21 +1,25 @@
/* /*
* 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. * 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_PLAYERBOTTEXTMGR_H #ifndef _PLAYERBOT_PLAYERBOTTEXTMGR_H
#define _PLAYERBOT_PLAYERBOTTEXTMGR_H #define _PLAYERBOT_PLAYERBOTTEXTMGR_H
#include "Common.h"
#include <map> #include <map>
#include <vector> #include <vector>
#include "Common.h"
#define BOT_TEXT1(name) sPlayerbotTextMgr->GetBotText(name) #define BOT_TEXT1(name) sPlayerbotTextMgr->GetBotText(name)
#define BOT_TEXT2(name, replace) sPlayerbotTextMgr->GetBotText(name, replace) #define BOT_TEXT2(name, replace) sPlayerbotTextMgr->GetBotText(name, replace)
struct BotTextEntry struct BotTextEntry
{ {
BotTextEntry(std::string name, std::map<uint32, std::string> text, uint32 say_type, uint32 reply_type) : m_name(name), m_text(text), m_sayType(say_type), m_replyType(reply_type) {} BotTextEntry(std::string name, std::map<uint32, std::string> text, uint32 say_type, uint32 reply_type)
: m_name(name), m_text(text), m_sayType(say_type), m_replyType(reply_type)
{
}
std::string m_name; std::string m_name;
std::map<uint32, std::string> m_text; std::map<uint32, std::string> m_text;
uint32 m_sayType; uint32 m_sayType;
@ -31,7 +35,11 @@ struct ChatReplyData
struct ChatQueuedReply struct ChatQueuedReply
{ {
ChatQueuedReply(uint32 type, uint32 guid1, uint32 guid2, std::string msg, std::string chanName, std::string name, time_t time) : m_type(type), m_guid1(guid1), m_guid2(guid2), m_msg(msg), m_chanName(chanName), m_name(name), m_time(time) {} ChatQueuedReply(uint32 type, uint32 guid1, uint32 guid2, std::string msg, std::string chanName, std::string name,
time_t time)
: m_type(type), m_guid1(guid1), m_guid2(guid2), m_msg(msg), m_chanName(chanName), m_name(name), m_time(time)
{
}
uint32 m_type; uint32 m_type;
uint32 m_guid1; uint32 m_guid1;
uint32 m_guid2; uint32 m_guid2;
@ -55,7 +63,8 @@ enum ChatReplyType
class PlayerbotTextMgr class PlayerbotTextMgr
{ {
public: public:
PlayerbotTextMgr() { PlayerbotTextMgr()
{
for (uint8 i = 0; i < MAX_LOCALES; ++i) for (uint8 i = 0; i < MAX_LOCALES; ++i)
{ {
botTextLocalePriority[i] = 0; botTextLocalePriority[i] = 0;

View File

@ -15,16 +15,17 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "cs_playerbots.h" #include "Playerbots.h"
#include "Channel.h" #include "Channel.h"
#include "Config.h" #include "Config.h"
#include "DatabaseEnv.h" #include "DatabaseEnv.h"
#include "DatabaseLoader.h" #include "DatabaseLoader.h"
#include "GuildTaskMgr.h" #include "GuildTaskMgr.h"
#include "Metric.h" #include "Metric.h"
#include "Playerbots.h"
#include "RandomPlayerbotMgr.h" #include "RandomPlayerbotMgr.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "cs_playerbots.h"
class PlayerbotsDatabaseScript : public DatabaseScript class PlayerbotsDatabaseScript : public DatabaseScript
{ {
@ -34,26 +35,19 @@ class PlayerbotsDatabaseScript : public DatabaseScript
bool OnDatabasesLoading() override bool OnDatabasesLoading() override
{ {
DatabaseLoader playerbotLoader("server.playerbots"); DatabaseLoader playerbotLoader("server.playerbots");
playerbotLoader.SetUpdateFlags(sConfigMgr->GetOption<bool>("Playerbots.Updates.EnableDatabases", true) ? DatabaseLoader::DATABASE_PLAYERBOTS : 0); playerbotLoader.SetUpdateFlags(sConfigMgr->GetOption<bool>("Playerbots.Updates.EnableDatabases", true)
? DatabaseLoader::DATABASE_PLAYERBOTS
: 0);
playerbotLoader.AddDatabase(PlayerbotsDatabase, "Playerbots"); playerbotLoader.AddDatabase(PlayerbotsDatabase, "Playerbots");
return playerbotLoader.Load(); return playerbotLoader.Load();
} }
void OnDatabasesKeepAlive() override void OnDatabasesKeepAlive() override { PlayerbotsDatabase.KeepAlive(); }
{
PlayerbotsDatabase.KeepAlive();
}
void OnDatabasesClosing() override void OnDatabasesClosing() override { PlayerbotsDatabase.Close(); }
{
PlayerbotsDatabase.Close();
}
void OnDatabaseWarnAboutSyncQueries(bool apply) override void OnDatabaseWarnAboutSyncQueries(bool apply) override { PlayerbotsDatabase.WarnAboutSyncQueries(apply); }
{
PlayerbotsDatabase.WarnAboutSyncQueries(apply);
}
void OnDatabaseSelectIndexLogout(Player* player, uint32& statementIndex, uint32& statementParam) override void OnDatabaseSelectIndexLogout(Player* player, uint32& statementIndex, uint32& statementParam) override
{ {
@ -63,7 +57,8 @@ class PlayerbotsDatabaseScript : public DatabaseScript
void OnDatabaseGetDBRevision(std::string& revision) override void OnDatabaseGetDBRevision(std::string& revision) override
{ {
if (QueryResult resultPlayerbot = PlayerbotsDatabase.Query("SELECT date FROM version_db_playerbots ORDER BY date DESC LIMIT 1")) if (QueryResult resultPlayerbot =
PlayerbotsDatabase.Query("SELECT date FROM version_db_playerbots ORDER BY date DESC LIMIT 1"))
{ {
Field* fields = resultPlayerbot->Fetch(); Field* fields = resultPlayerbot->Fetch();
revision = fields[0].Get<std::string>(); revision = fields[0].Get<std::string>();
@ -152,7 +147,8 @@ class PlayerbotsPlayerScript : public PlayerScript
{ {
if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player)) if (PlayerbotMgr* playerbotMgr = GET_PLAYERBOT_MGR(player))
{ {
for (PlayerBotMap::const_iterator it = playerbotMgr->GetPlayerBotsBegin(); it != playerbotMgr->GetPlayerBotsEnd(); ++it) for (PlayerBotMap::const_iterator it = playerbotMgr->GetPlayerBotsBegin();
it != playerbotMgr->GetPlayerBotsEnd(); ++it)
{ {
if (Player* const bot = it->second) if (Player* const bot = it->second)
{ {
@ -332,10 +328,7 @@ class PlayerbotsScript : public PlayerbotScript
sRandomPlayerbotMgr->OnPlayerLogout(player); sRandomPlayerbotMgr->OnPlayerLogout(player);
} }
void OnPlayerbotLogoutBots() override void OnPlayerbotLogoutBots() override { sRandomPlayerbotMgr->LogoutAllBots(); }
{
sRandomPlayerbotMgr->LogoutAllBots();
}
}; };
void AddPlayerbotsScripts() void AddPlayerbotsScripts()

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_H #ifndef _PLAYERBOT_H
@ -43,7 +44,8 @@ int strcmpi(char const* s1, char const* s2);
#define RESET_AI_VALUE2(type, name, param) context->GetValue<type>(name, param)->Reset() #define RESET_AI_VALUE2(type, name, param) context->GetValue<type>(name, param)->Reset()
#define PAI_VALUE(type, name) sPlayerbotsMgr->GetPlayerbotAI(player)->GetAiObjectContext()->GetValue<type>(name)->Get() #define PAI_VALUE(type, name) sPlayerbotsMgr->GetPlayerbotAI(player)->GetAiObjectContext()->GetValue<type>(name)->Get()
#define PAI_VALUE2(type, name, param) sPlayerbotsMgr->GetPlayerbotAI(player)->GetAiObjectContext()->GetValue<type>(name, param)->Get() #define PAI_VALUE2(type, name, param) \
sPlayerbotsMgr->GetPlayerbotAI(player)->GetAiObjectContext()->GetValue<type>(name, param)->Get()
#define GAI_VALUE(type, name) sSharedValueContext->getGlobalValue<type>(name)->Get() #define GAI_VALUE(type, name) sSharedValueContext->getGlobalValue<type>(name)->Get()
#define GAI_VALUE2(type, name, param) sSharedValueContext->getGlobalValue<type>(name, param)->Get() #define GAI_VALUE2(type, name, param) sSharedValueContext->getGlobalValue<type>(name, param)->Get()

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,19 @@
/* /*
* 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. * 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_RANDOMITEMMGR_H #ifndef _PLAYERBOT_RANDOMITEMMGR_H
#define _PLAYERBOT_RANDOMITEMMGR_H #define _PLAYERBOT_RANDOMITEMMGR_H
#include "AiFactory.h"
#include "Common.h"
#include "ItemTemplate.h"
#include <map> #include <map>
#include <set> #include <set>
#include <vector> #include <vector>
#include "AiFactory.h"
#include "Common.h"
#include "ItemTemplate.h"
class ChatHandler; class ChatHandler;
struct ItemTemplate; struct ItemTemplate;
@ -60,7 +61,8 @@ struct StatWeight
struct ItemInfoEntry struct ItemInfoEntry
{ {
ItemInfoEntry() : minLevel(0), source(0), sourceId(0), team(0), repRank(0), repFaction(0), quality(0), slot(0), itemId(0) ItemInfoEntry()
: minLevel(0), source(0), sourceId(0), team(0), repRank(0), repFaction(0), quality(0), slot(0), itemId(0)
{ {
for (uint8 i = 1; i <= MAX_STAT_SCALES; ++i) for (uint8 i = 1; i <= MAX_STAT_SCALES; ++i)
{ {
@ -106,13 +108,16 @@ class BotEquipKey
{ {
public: public:
BotEquipKey() : level(0), clazz(0), slot(0), quality(0), key(GetKey()) {} BotEquipKey() : level(0), clazz(0), slot(0), quality(0), key(GetKey()) {}
BotEquipKey(uint32 level, uint8 clazz, uint8 slot, uint32 quality) : level(level), clazz(clazz), slot(slot), quality(quality), key(GetKey()) { } BotEquipKey(uint32 level, uint8 clazz, uint8 slot, uint32 quality)
BotEquipKey(BotEquipKey const& other) : level(other.level), clazz(other.clazz), slot(other.slot), quality(other.quality), key(GetKey()) { } : level(level), clazz(clazz), slot(slot), quality(quality), key(GetKey())
bool operator<(BotEquipKey const& other) const
{ {
return other.key < this->key;
} }
BotEquipKey(BotEquipKey const& other)
: level(other.level), clazz(other.clazz), slot(other.slot), quality(other.quality), key(GetKey())
{
}
bool operator<(BotEquipKey const& other) const { return other.key < this->key; }
uint32 level; uint32 level;
uint8 clazz; uint8 clazz;
@ -144,7 +149,8 @@ class RandomItemMgr
RandomItemList Query(uint32 level, RandomItemType type, RandomItemPredicate* predicate); RandomItemList Query(uint32 level, RandomItemType type, RandomItemPredicate* predicate);
RandomItemList Query(uint32 level, uint8 clazz, uint8 slot, uint32 quality); RandomItemList Query(uint32 level, uint8 clazz, uint8 slot, uint32 quality);
uint32 GetUpgrade(Player* player, std::string spec, uint8 slot, uint32 quality, uint32 itemId); uint32 GetUpgrade(Player* player, std::string spec, uint8 slot, uint32 quality, uint32 itemId);
std::vector<uint32> GetUpgradeList(Player* player, std::string spec, uint8 slot, uint32 quality, uint32 itemId, uint32 amount = 1); std::vector<uint32> GetUpgradeList(Player* player, std::string spec, uint8 slot, uint32 quality, uint32 itemId,
uint32 amount = 1);
bool HasStatWeight(uint32 itemId); bool HasStatWeight(uint32 itemId);
uint32 GetMinLevelFromCache(uint32 itemId); uint32 GetMinLevelFromCache(uint32 itemId);
uint32 GetStatWeight(Player* player, uint32 itemId); uint32 GetStatWeight(Player* player, uint32 itemId);
@ -182,6 +188,7 @@ class RandomItemMgr
bool CanEquipItemNew(ItemTemplate const* proto); bool CanEquipItemNew(ItemTemplate const* proto);
void AddItemStats(uint32 mod, uint8& sp, uint8& ap, uint8& tank); void AddItemStats(uint32 mod, uint8& sp, uint8& ap, uint8& tank);
bool CheckItemStats(uint8 clazz, uint8 sp, uint8 ap, uint8 tank); bool CheckItemStats(uint8 clazz, uint8 sp, uint8 ap, uint8 tank);
private: private:
std::map<uint32, RandomItemCache> randomItemCache; std::map<uint32, RandomItemCache> randomItemCache;
std::map<RandomItemType, RandomItemPredicate*> predicates; std::map<RandomItemType, RandomItemPredicate*> predicates;

View File

@ -1,14 +1,16 @@
/* /*
* 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. * 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 "RandomPlayerbotFactory.h" #include "RandomPlayerbotFactory.h"
#include "ArenaTeamMgr.h"
#include "AccountMgr.h" #include "AccountMgr.h"
#include "ArenaTeamMgr.h"
#include "DatabaseEnv.h" #include "DatabaseEnv.h"
#include "GuildMgr.h" #include "GuildMgr.h"
#include "Playerbots.h"
#include "PlayerbotFactory.h" #include "PlayerbotFactory.h"
#include "Playerbots.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "SocialMgr.h" #include "SocialMgr.h"
@ -124,15 +126,18 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
uint8 gender = rand() % 2 ? GENDER_MALE : GENDER_FEMALE; uint8 gender = rand() % 2 ? GENDER_MALE : GENDER_FEMALE;
uint8 alliance = rand() % 2; uint8 alliance = rand() % 2;
uint8 race; uint8 race;
for (int attempt = 0; attempt < 15; attempt++) { for (int attempt = 0; attempt < 15; attempt++)
{
race = availableRaces[cls][urand(0, availableRaces[cls].size() - 1)]; race = availableRaces[cls][urand(0, availableRaces[cls].size() - 1)];
if ((alliance && IsAlliance(race)) || (!alliance && !IsAlliance(race))) { if ((alliance && IsAlliance(race)) || (!alliance && !IsAlliance(race)))
{
break; break;
} }
} }
std::string name = CreateRandomBotName(gender); std::string name = CreateRandomBotName(gender);
if (name.empty()) { if (name.empty())
{
LOG_ERROR("playerbots", "Unable to get random bot name!"); LOG_ERROR("playerbots", "Unable to get random bot name!");
return nullptr; return nullptr;
} }
@ -166,10 +171,12 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
std::pair<uint8, uint8> face = faces[urand(0, faces.size() - 1)]; std::pair<uint8, uint8> face = faces[urand(0, faces.size() - 1)];
std::pair<uint8, uint8> hair = hairs[urand(0, hairs.size() - 1)]; std::pair<uint8, uint8> hair = hairs[urand(0, hairs.size() - 1)];
bool excludeCheck = (race == RACE_TAUREN) || (race == RACE_DRAENEI) || (gender == GENDER_FEMALE && race != RACE_NIGHTELF && race != RACE_UNDEAD_PLAYER); bool excludeCheck = (race == RACE_TAUREN) || (race == RACE_DRAENEI) ||
(gender == GENDER_FEMALE && race != RACE_NIGHTELF && race != RACE_UNDEAD_PLAYER);
uint8 facialHair = excludeCheck ? 0 : facialHairTypes[urand(0, facialHairTypes.size() - 1)]; uint8 facialHair = excludeCheck ? 0 : facialHairTypes[urand(0, facialHairTypes.size() - 1)];
std::unique_ptr<CharacterCreateInfo> characterInfo = std::make_unique<CharacterCreateInfo>(name, race, cls, gender, face.second, face.first, hair.first, hair.second, facialHair); std::unique_ptr<CharacterCreateInfo> characterInfo = std::make_unique<CharacterCreateInfo>(
name, race, cls, gender, face.second, face.first, hair.first, hair.second, facialHair);
Player* player = new Player(session); Player* player = new Player(session);
player->GetMotionMaster()->Initialize(); player->GetMotionMaster()->Initialize();
@ -178,7 +185,8 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
player->CleanupsBeforeDelete(); player->CleanupsBeforeDelete();
delete player; delete player;
LOG_ERROR("playerbots", "Unable to create random bot for account {} - name: \"{}\"; race: {}; class: {}", accountId, name.c_str(), race, cls); LOG_ERROR("playerbots", "Unable to create random bot for account {} - name: \"{}\"; race: {}; class: {}",
accountId, name.c_str(), race, cls);
return nullptr; return nullptr;
} }
@ -191,7 +199,8 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
} }
// player->SaveToDB(true, false); // player->SaveToDB(true, false);
// player->RewardQuest(const Quest *quest, uint32 reward, Object *questGiver) // player->RewardQuest(const Quest *quest, uint32 reward, Object *questGiver)
LOG_DEBUG("playerbots", "Random bot created for account {} - name: \"{}\"; race: {}; class: {}", accountId, name.c_str(), race, cls); LOG_DEBUG("playerbots", "Random bot created for account {} - name: \"{}\"; race: {}; class: {}", accountId,
name.c_str(), race, cls);
return player; return player;
} }
@ -200,9 +209,12 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
{ {
std::string botName = ""; std::string botName = "";
int tries = 10; int tries = 10;
while(--tries) { while (--tries)
QueryResult result = CharacterDatabase.Query("SELECT name FROM playerbots_names " {
"WHERE in_use = 0 AND gender = {} ORDER BY RAND() LIMIT 1", gender); QueryResult result = CharacterDatabase.Query(
"SELECT name FROM playerbots_names "
"WHERE in_use = 0 AND gender = {} ORDER BY RAND() LIMIT 1",
gender);
if (!result) if (!result)
{ {
break; break;
@ -218,27 +230,17 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
// CONLANG NAME GENERATION // CONLANG NAME GENERATION
LOG_ERROR("playerbots", "No more names left for random bots. Attempting conlang name generation."); LOG_ERROR("playerbots", "No more names left for random bots. Attempting conlang name generation.");
const std::string groupCategory = "SCVKRU"; const std::string groupCategory = "SCVKRU";
const std::string groupFormStart[2][4] = { const std::string groupFormStart[2][4] = {{"SV", "SV", "VK", "RV"}, {"V", "SU", "VS", "RV"}};
{"SV","SV","VK","RV"}, const std::string groupFormMid[2][6] = {{"CV", "CVC", "CVC", "CVK", "VC", "VK"},
{"V" ,"SU","VS","RV"} {"CV", "CVC", "CVK", "KVC", "VC", "KV"}};
}; const std::string groupFormEnd[2][4] = {{"CV", "VC", "VK", "CV"}, {"RU", "UR", "VR", "V"}};
const std::string groupFormMid[2][6] = {
{"CV","CVC","CVC","CVK","VC","VK"},
{"CV","CVC","CVK","KVC","VC","KV"}
};
const std::string groupFormEnd[2][4] = {
{"CV","VC","VK","CV"},
{"RU","UR","VR","V" }
};
const std::string groupLetter[2][6] = { const std::string groupLetter[2][6] = {
// S C V K R U // S C V K R U
{"dtspkThfS", "bcCdfghjkmnNqqrrlsStTvwxyz", "aaeeiouA", "ppttkkbdg", "lmmnrr", "AEO"}, {"dtspkThfS", "bcCdfghjkmnNqqrrlsStTvwxyz", "aaeeiouA", "ppttkkbdg", "lmmnrr", "AEO"},
{"dtskThfS" ,"bcCdfghjkmmnNqrrlssStTvwyz","aaaeeiiuAAEIO","ppttkbbdg","lmmnrrr","AEOy"} {"dtskThfS", "bcCdfghjkmmnNqrrlssStTvwyz", "aaaeeiiuAAEIO", "ppttkbbdg", "lmmnrrr", "AEOy"}};
};
const std::string replaceRule[2][17] = { const std::string replaceRule[2][17] = {
{"ST", "ka", "ko", "ku", "kr", "S", "T", "C", "N", "jj", "AA", "AI", "A", "E", "O", "I", "aa"}, {"ST", "ka", "ko", "ku", "kr", "S", "T", "C", "N", "jj", "AA", "AI", "A", "E", "O", "I", "aa"},
{"sth","ca","co","cu","cr","sh","th","ch","ng","dg","A" ,"ayu","ai","ei","ou","iu","ae"} {"sth", "ca", "co", "cu", "cr", "sh", "th", "ch", "ng", "dg", "A", "ayu", "ai", "ei", "ou", "iu", "ae"}};
};
tries = 10; tries = 10;
while (--tries) while (--tries)
@ -260,7 +262,8 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
// Replace Catagory value with random Letter from that Catagory's Letter string for a given bot gender // Replace Catagory value with random Letter from that Catagory's Letter string for a given bot gender
for (int i = 0; i < botName.size(); i++) for (int i = 0; i < botName.size(); i++)
{ {
botName[i] = groupLetter[gender][groupCategory.find(botName[i])][rand()%groupLetter[gender][groupCategory.find(botName[i])].size()]; botName[i] = groupLetter[gender][groupCategory.find(botName[i])]
[rand() % groupLetter[gender][groupCategory.find(botName[i])].size()];
} }
// Itterate over replace rules // Itterate over replace rules
@ -289,8 +292,10 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
// TRUE RANDOM NAME GENERATION // TRUE RANDOM NAME GENERATION
LOG_ERROR("playerbots", "Conlang name generation failed. True random name fallback."); LOG_ERROR("playerbots", "Conlang name generation failed. True random name fallback.");
tries = 10; tries = 10;
while(--tries) { while (--tries)
for (uint8 i = 0; i < 10; i++) { {
for (uint8 i = 0; i < 10; i++)
{
botName += (i == 0 ? 'A' : 'a') + rand() % 26; botName += (i == 0 ? 'A' : 'a') + rand() % 26;
} }
if (ObjectMgr::CheckPlayerName(botName) != CHAR_NAME_SUCCESS || if (ObjectMgr::CheckPlayerName(botName) != CHAR_NAME_SUCCESS ||
@ -325,7 +330,8 @@ void RandomPlayerbotFactory::CreateRandomBots()
} }
LOG_INFO("playerbots", "Deleting all random bot characters, {} accounts collected...", botAccounts.size()); LOG_INFO("playerbots", "Deleting all random bot characters, {} accounts collected...", botAccounts.size());
QueryResult results = LoginDatabase.Query("SELECT id FROM account WHERE username LIKE '{}%%'", sPlayerbotAIConfig->randomBotAccountPrefix.c_str()); QueryResult results = LoginDatabase.Query("SELECT id FROM account WHERE username LIKE '{}%%'",
sPlayerbotAIConfig->randomBotAccountPrefix.c_str());
int32 deletion_count = 0; int32 deletion_count = 0;
if (results) if (results)
{ {
@ -340,8 +346,8 @@ void RandomPlayerbotFactory::CreateRandomBots()
PlayerbotsDatabase.Execute(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_RANDOM_BOTS)); PlayerbotsDatabase.Execute(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_RANDOM_BOTS));
CharacterDatabase.DirectExecute("UPDATE playerbots_names SET in_use = 0 WHERE in_use = 1"); CharacterDatabase.DirectExecute("UPDATE playerbots_names SET in_use = 0 WHERE in_use = 1");
/* TODO(yunfan): we need to sleep here to wait for async account deleted, or the newly account won't be created correctly /* TODO(yunfan): we need to sleep here to wait for async account deleted, or the newly account won't be created
the better way is turning the async db operation to sync db operation */ correctly the better way is turning the async db operation to sync db operation */
std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount); std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount);
LOG_INFO("playerbots", "Random bot characters deleted."); LOG_INFO("playerbots", "Random bot characters deleted.");
LOG_INFO("playerbots", "Please reset the AiPlayerbot.DeleteRandomBotAccounts to 0 and restart the server..."); LOG_INFO("playerbots", "Please reset the AiPlayerbot.DeleteRandomBotAccounts to 0 and restart the server...");
@ -385,7 +391,8 @@ void RandomPlayerbotFactory::CreateRandomBots()
LOG_DEBUG("playerbots", "Account {} created for random bots", accountName.c_str()); LOG_DEBUG("playerbots", "Account {} created for random bots", accountName.c_str());
} }
if (account_creation) { if (account_creation)
{
/* wait for async accounts create to make character create correctly, same as account delete */ /* wait for async accounts create to make character create correctly, same as account delete */
LOG_INFO("playerbots", "Waiting for {} accounts loading into database...", account_creation); LOG_INFO("playerbots", "Waiting for {} accounts loading into database...", account_creation);
std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount); std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount);
@ -420,10 +427,12 @@ void RandomPlayerbotFactory::CreateRandomBots()
{ {
continue; continue;
} }
LOG_INFO("playerbots", "Creating random bot characters for account: [{}/{}]", accountNumber + 1, sPlayerbotAIConfig->randomBotAccountCount); LOG_INFO("playerbots", "Creating random bot characters for account: [{}/{}]", accountNumber + 1,
sPlayerbotAIConfig->randomBotAccountCount);
RandomPlayerbotFactory factory(accountId); RandomPlayerbotFactory factory(accountId);
WorldSession* session = new WorldSession(accountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING, time_t(0), LOCALE_enUS, 0, false, false, 0, true); WorldSession* session = new WorldSession(accountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING,
time_t(0), LOCALE_enUS, 0, false, false, 0, true);
sessionBots.push_back(session); sessionBots.push_back(session);
for (uint8 cls = CLASS_WARRIOR; cls < MAX_CLASSES - count; ++cls) for (uint8 cls = CLASS_WARRIOR; cls < MAX_CLASSES - count; ++cls)
@ -433,29 +442,33 @@ void RandomPlayerbotFactory::CreateRandomBots()
continue; continue;
if (bool const isClassDeathKnight = cls == CLASS_DEATH_KNIGHT; if (bool const isClassDeathKnight = cls == CLASS_DEATH_KNIGHT;
isClassDeathKnight && isClassDeathKnight && sWorld->getIntConfig(CONFIG_EXPANSION) != EXPANSION_WRATH_OF_THE_LICH_KING)
sWorld->getIntConfig(CONFIG_EXPANSION) !=
EXPANSION_WRATH_OF_THE_LICH_KING)
{ {
continue; continue;
} }
if (cls != 10) { if (cls != 10)
if (Player* playerBot = factory.CreateRandomBot(session, cls)) { {
if (Player* playerBot = factory.CreateRandomBot(session, cls))
{
playerBot->SaveToDB(true, false); playerBot->SaveToDB(true, false);
sCharacterCache->AddCharacterCacheEntry(playerBot->GetGUID(), accountId, playerBot->GetName(), sCharacterCache->AddCharacterCacheEntry(playerBot->GetGUID(), accountId, playerBot->GetName(),
playerBot->getGender(), playerBot->getRace(), playerBot->getClass(), playerBot->GetLevel()); playerBot->getGender(), playerBot->getRace(),
playerBot->getClass(), playerBot->GetLevel());
playerBot->CleanupsBeforeDelete(); playerBot->CleanupsBeforeDelete();
delete playerBot; delete playerBot;
bot_creation++; bot_creation++;
} else { }
else
{
LOG_ERROR("playerbots", "Fail to create character for account {}", accountId); LOG_ERROR("playerbots", "Fail to create character for account {}", accountId);
} }
} }
} }
} }
if (bot_creation) { if (bot_creation)
{
LOG_INFO("playerbots", "Waiting for {} characters loading into database...", bot_creation); LOG_INFO("playerbots", "Waiting for {} characters loading into database...", bot_creation);
/* wait for characters load into database, or characters will fail to loggin */ /* wait for characters load into database, or characters will fail to loggin */
std::this_thread::sleep_for(10s); std::this_thread::sleep_for(10s);
@ -464,11 +477,13 @@ void RandomPlayerbotFactory::CreateRandomBots()
for (WorldSession* session : sessionBots) for (WorldSession* session : sessionBots)
delete session; delete session;
for (uint32 accountId : sPlayerbotAIConfig->randomBotAccounts) { for (uint32 accountId : sPlayerbotAIConfig->randomBotAccounts)
{
totalRandomBotChars += AccountMgr::GetCharactersCount(accountId); totalRandomBotChars += AccountMgr::GetCharactersCount(accountId);
} }
LOG_INFO("server.loading", "{} random bot accounts with {} characters available", sPlayerbotAIConfig->randomBotAccounts.size(), totalRandomBotChars); LOG_INFO("server.loading", "{} random bot accounts with {} characters available",
sPlayerbotAIConfig->randomBotAccounts.size(), totalRandomBotChars);
} }
void RandomPlayerbotFactory::CreateRandomGuilds() void RandomPlayerbotFactory::CreateRandomGuilds()
@ -484,8 +499,7 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
Field* fields = result->Fetch(); Field* fields = result->Fetch();
uint32 bot = fields[0].Get<uint32>(); uint32 bot = fields[0].Get<uint32>();
randomBots.push_back(bot); randomBots.push_back(bot);
} } while (result->NextRow());
while (result->NextRow());
} }
if (sPlayerbotAIConfig->deleteRandomBotGuilds) if (sPlayerbotAIConfig->deleteRandomBotGuilds)
@ -538,7 +552,8 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
Player* player = ObjectAccessor::FindPlayer(leader); Player* player = ObjectAccessor::FindPlayer(leader);
if (!player) if (!player)
{ {
LOG_ERROR("playerbots", "ObjectAccessor Cannot find player to set leader for guild {} . Skipped...", guildName.c_str()); LOG_ERROR("playerbots", "ObjectAccessor Cannot find player to set leader for guild {} . Skipped...",
guildName.c_str());
continue; continue;
} }
@ -548,7 +563,8 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
Guild* guild = new Guild(); Guild* guild = new Guild();
if (!guild->Create(player, guildName)) if (!guild->Create(player, guildName))
{ {
LOG_ERROR("playerbots", "Error creating guild [ {} ] with leader [ {} ]", guildName.c_str(), player->GetName().c_str()); LOG_ERROR("playerbots", "Error creating guild [ {} ] with leader [ {} ]", guildName.c_str(),
player->GetName().c_str());
delete guild; delete guild;
continue; continue;
} }
@ -586,8 +602,10 @@ std::string const RandomPlayerbotFactory::CreateRandomGuildName()
uint32 maxId = fields[0].Get<uint32>(); uint32 maxId = fields[0].Get<uint32>();
uint32 id = urand(0, maxId); uint32 id = urand(0, maxId);
result = CharacterDatabase.Query("SELECT n.name FROM playerbots_guild_names n " result = CharacterDatabase.Query(
"LEFT OUTER JOIN guild e ON e.name = n.name WHERE e.guildid IS NULL AND n.name_id >= {} LIMIT 1", id); "SELECT n.name FROM playerbots_guild_names n "
"LEFT OUTER JOIN guild e ON e.name = n.name WHERE e.guildid IS NULL AND n.name_id >= {} LIMIT 1",
id);
if (!result) if (!result)
{ {
LOG_ERROR("playerbots", "No more names left for random guilds"); LOG_ERROR("playerbots", "No more names left for random guilds");
@ -613,8 +631,7 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
Field* fields = result->Fetch(); Field* fields = result->Fetch();
uint32 bot = fields[0].Get<uint32>(); uint32 bot = fields[0].Get<uint32>();
randomBots.push_back(bot); randomBots.push_back(bot);
} } while (result->NextRow());
while (result->NextRow());
} }
uint32 arenaTeamNumber = 0; uint32 arenaTeamNumber = 0;
@ -664,10 +681,10 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
continue; continue;
} }
// Below query no longer required as now user has control over the number of each type of arena team they want to create. // Below query no longer required as now user has control over the number of each type of arena team they want
// Keeping commented for potential future reference. // to create. Keeping commented for potential future reference. QueryResult results =
// QueryResult results = CharacterDatabase.Query("SELECT `type` FROM playerbots_arena_team_names WHERE name = '{}'", arenaTeamName.c_str()); // CharacterDatabase.Query("SELECT `type` FROM playerbots_arena_team_names WHERE name = '{}'",
// if (!results) // arenaTeamName.c_str()); if (!results)
// { // {
// LOG_ERROR("playerbots", "No valid types for arena teams"); // LOG_ERROR("playerbots", "No valid types for arena teams");
// return; // return;
@ -686,7 +703,8 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
arenateam->SetCaptain(player->GetGUID()); arenateam->SetCaptain(player->GetGUID());
// set random rating // set random rating
arenateam->SetRatingForAll(urand(sPlayerbotAIConfig->randomBotArenaTeamMinRating, sPlayerbotAIConfig->randomBotArenaTeamMaxRating)); arenateam->SetRatingForAll(
urand(sPlayerbotAIConfig->randomBotArenaTeamMinRating, sPlayerbotAIConfig->randomBotArenaTeamMaxRating));
// set random emblem // set random emblem
uint32 backgroundColor = urand(0xFF000000, 0xFFFFFFFF); uint32 backgroundColor = urand(0xFF000000, 0xFFFFFFFF);
@ -699,8 +717,9 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
// set random kills (wip) // set random kills (wip)
// arenateam->SetStats(STAT_TYPE_GAMES_WEEK, urand(0, 30)); // arenateam->SetStats(STAT_TYPE_GAMES_WEEK, urand(0, 30));
// arenateam->SetStats(STAT_TYPE_WINS_WEEK, urand(0, arenateam->GetStats().games_week)); // arenateam->SetStats(STAT_TYPE_WINS_WEEK, urand(0, arenateam->GetStats().games_week));
//arenateam->SetStats(STAT_TYPE_GAMES_SEASON, urand(arenateam->GetStats().games_week, arenateam->GetStats().games_week * 5)); // arenateam->SetStats(STAT_TYPE_GAMES_SEASON, urand(arenateam->GetStats().games_week,
//arenateam->SetStats(STAT_TYPE_WINS_SEASON, urand(arenateam->GetStats().wins_week, arenateam->GetStats().games // arenateam->GetStats().games_week * 5)); arenateam->SetStats(STAT_TYPE_WINS_SEASON,
// urand(arenateam->GetStats().wins_week, arenateam->GetStats().games
arenateam->SaveToDB(); arenateam->SaveToDB();
sArenaTeamMgr->AddArenaTeam(arenateam); sArenaTeamMgr->AddArenaTeam(arenateam);
@ -725,8 +744,10 @@ std::string const RandomPlayerbotFactory::CreateRandomArenaTeamName()
uint32 maxId = fields[0].Get<uint32>(); uint32 maxId = fields[0].Get<uint32>();
uint32 id = urand(0, maxId); uint32 id = urand(0, maxId);
result = CharacterDatabase.Query("SELECT n.name FROM playerbots_arena_team_names n LEFT OUTER JOIN arena_team e ON e.name = n.name " result = CharacterDatabase.Query(
"WHERE e.arenateamid IS NULL AND n.name_id >= {} LIMIT 1", id); "SELECT n.name FROM playerbots_arena_team_names n LEFT OUTER JOIN arena_team e ON e.name = n.name "
"WHERE e.arenateamid IS NULL AND n.name_id >= {} LIMIT 1",
id);
if (!result) if (!result)
{ {

View File

@ -1,15 +1,16 @@
/* /*
* 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. * 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_RANDOMPLAYERBOTFACTORY_H #ifndef _PLAYERBOT_RANDOMPLAYERBOTFACTORY_H
#define _PLAYERBOT_RANDOMPLAYERBOTFACTORY_H #define _PLAYERBOT_RANDOMPLAYERBOTFACTORY_H
#include "Common.h"
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "Common.h"
#include "DBCEnums.h" #include "DBCEnums.h"
class Player; class Player;

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_RANDOMPLAYERBOTMGR_H #ifndef _PLAYERBOT_RANDOMPLAYERBOTMGR_H
@ -7,7 +8,8 @@
#include "PlayerbotMgr.h" #include "PlayerbotMgr.h"
struct BattlegroundInfo { struct BattlegroundInfo
{
std::vector<uint32> bgInstances; std::vector<uint32> bgInstances;
std::vector<uint32> ratedArenaInstances; std::vector<uint32> ratedArenaInstances;
std::vector<uint32> skirmishArenaInstances; std::vector<uint32> skirmishArenaInstances;
@ -45,8 +47,14 @@ class CachedEvent
{ {
public: public:
CachedEvent() : value(0), lastChangeTime(0), validIn(0), data("") {} CachedEvent() : value(0), lastChangeTime(0), validIn(0), data("") {}
CachedEvent(const CachedEvent& other) : value(other.value), lastChangeTime(other.lastChangeTime), validIn(other.validIn), data(other.data) { } CachedEvent(const CachedEvent& other)
CachedEvent(uint32 value, uint32 lastChangeTime, uint32 validIn, std::string const data = "") : value(value), lastChangeTime(lastChangeTime), validIn(validIn), data(data) { } : value(other.value), lastChangeTime(other.lastChangeTime), validIn(other.validIn), data(other.data)
{
}
CachedEvent(uint32 value, uint32 lastChangeTime, uint32 validIn, std::string const data = "")
: value(value), lastChangeTime(lastChangeTime), validIn(validIn), data(data)
{
}
bool IsEmpty() { return !lastChangeTime; } bool IsEmpty() { return !lastChangeTime; }
@ -150,7 +158,10 @@ class RandomPlayerbotMgr : public PlayerbotHolder
void CheckPlayers(); void CheckPlayers();
void LogBattlegroundInfo(); void LogBattlegroundInfo();
std::map<TeamId, std::map<BattlegroundTypeId, std::vector<uint32>>> getBattleMastersCache() { return BattleMastersCache; } std::map<TeamId, std::map<BattlegroundTypeId, std::vector<uint32>>> getBattleMastersCache()
{
return BattleMastersCache;
}
float getActivityMod() { return activityMod; } float getActivityMod() { return activityMod; }
float getActivityPercentage() { return activityMod * 100.0f; } float getActivityPercentage() { return activityMod * 100.0f; }
@ -165,7 +176,8 @@ class RandomPlayerbotMgr : public PlayerbotHolder
float activityMod = 0.25; float activityMod = 0.25;
uint32 GetEventValue(uint32 bot, std::string const event); uint32 GetEventValue(uint32 bot, std::string const event);
std::string const GetEventData(uint32 bot, std::string const event); std::string const GetEventData(uint32 bot, std::string const event);
uint32 SetEventValue(uint32 bot, std::string const event, uint32 value, uint32 validIn, std::string const data = ""); uint32 SetEventValue(uint32 bot, std::string const event, uint32 value, uint32 validIn,
std::string const data = "");
void GetBots(); void GetBots();
std::vector<uint32> GetBgBots(uint32 bracket); std::vector<uint32> GetBgBots(uint32 bracket);
time_t BgCheckTimer; time_t BgCheckTimer;

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "ServerFacade.h" #include "ServerFacade.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "TargetedMovementGenerator.h" #include "TargetedMovementGenerator.h"
@ -33,15 +35,9 @@ bool ServerFacade::IsDistanceGreaterThan(float dist1, float dist2)
return dist1 > dist2; return dist1 > dist2;
} }
bool ServerFacade::IsDistanceGreaterOrEqualThan(float dist1, float dist2) bool ServerFacade::IsDistanceGreaterOrEqualThan(float dist1, float dist2) { return !IsDistanceLessThan(dist1, dist2); }
{
return !IsDistanceLessThan(dist1, dist2);
}
bool ServerFacade::IsDistanceLessOrEqualThan(float dist1, float dist2) bool ServerFacade::IsDistanceLessOrEqualThan(float dist1, float dist2) { return !IsDistanceGreaterThan(dist1, dist2); }
{
return !IsDistanceGreaterThan(dist1, dist2);
}
void ServerFacade::SetFacingTo(Player* bot, WorldObject* wo, bool force) void ServerFacade::SetFacingTo(Player* bot, WorldObject* wo, bool force)
{ {

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_SERVERFACADE_H #ifndef _PLAYERBOT_SERVERFACADE_H

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "Talentspec.h" #include "Talentspec.h"
#include "Event.h" #include "Event.h"
#include "Playerbots.h" #include "Playerbots.h"
@ -50,10 +52,7 @@ uint32 TalentSpec::PointstoLevel(uint32 points) const
return uint32(ceil(points / sWorld->getRate(RATE_TALENT))) + 9; return uint32(ceil(points / sWorld->getRate(RATE_TALENT))) + 9;
} }
TalentSpec::TalentSpec(uint32 classMask) TalentSpec::TalentSpec(uint32 classMask) { GetTalents(classMask); }
{
GetTalents(classMask);
}
TalentSpec::TalentSpec(TalentSpec* base, std::string const link) TalentSpec::TalentSpec(TalentSpec* base, std::string const link)
{ {
@ -81,7 +80,8 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
if (entry.rank > entry.maxRank) if (entry.rank > entry.maxRank)
{ {
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry.talentInfo->RankID[0]); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry.talentInfo->RankID[0]);
*out << "spec is not for this class. " << spellInfo->SpellName[0] << " has " << (entry.rank - entry.maxRank) << " points above max rank."; *out << "spec is not for this class. " << spellInfo->SpellName[0] << " has " << (entry.rank - entry.maxRank)
<< " points above max rank.";
return false; return false;
} }
@ -103,7 +103,8 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
if (!found) if (!found)
{ {
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry.talentInfo->RankID[0]); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry.talentInfo->RankID[0]);
*out << "spec is invalid. Talent:" << spellInfo->SpellName[0] << " needs: " << spellInfodep->SpellName[0] << " at rank: " << entry.talentInfo->DependsOnRank; *out << "spec is invalid. Talent:" << spellInfo->SpellName[0]
<< " needs: " << spellInfodep->SpellName[0] << " at rank: " << entry.talentInfo->DependsOnRank;
return false; return false;
} }
} }
@ -120,7 +121,8 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
if (entry.rank > 0 && entry.talentInfo->Row * 5 > points) if (entry.rank > 0 && entry.talentInfo->Row * 5 > points)
{ {
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry.talentInfo->RankID[0]); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(entry.talentInfo->RankID[0]);
*out << "spec is is invalid. Talent " << spellInfo->SpellName[0] << " is selected with only " << points << " in row below it."; *out << "spec is is invalid. Talent " << spellInfo->SpellName[0] << " is selected with only " << points
<< " in row below it.";
return false; return false;
} }
@ -140,7 +142,8 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
// Set the talents for the bots to the current spec. // Set the talents for the bots to the current spec.
void TalentSpec::ApplyTalents(Player* bot, std::ostringstream* out) void TalentSpec::ApplyTalents(Player* bot, std::ostringstream* out)
{ {
for (auto& entry : talents) { for (auto& entry : talents)
{
if (entry.rank == 0) if (entry.rank == 0)
continue; continue;
bot->LearnTalent(entry.talentInfo->TalentID, entry.rank - 1); bot->LearnTalent(entry.talentInfo->TalentID, entry.rank - 1);
@ -208,10 +211,7 @@ bool sortTalentMap(TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j,
return false; return false;
} }
void TalentSpec::SortTalents(uint32 sortBy) void TalentSpec::SortTalents(uint32 sortBy) { SortTalents(talents, sortBy); }
{
SortTalents(talents, sortBy);
}
// Sort the talents. // Sort the talents.
void TalentSpec::SortTalents(std::vector<TalentListEntry>& talents, uint32 sortBy) void TalentSpec::SortTalents(std::vector<TalentListEntry>& talents, uint32 sortBy)
@ -221,19 +221,19 @@ void TalentSpec::SortTalents(std::vector<TalentListEntry>& talents, uint32 sortB
case SORT_BY_DEFAULT: case SORT_BY_DEFAULT:
{ {
uint32 tabSort[] = {0, 1, 2}; uint32 tabSort[] = {0, 1, 2};
std::sort(talents.begin(), talents.end(), [&tabSort](TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j) std::sort(talents.begin(), talents.end(),
{ [&tabSort](TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j)
return sortTalentMap(i, j, tabSort); { return sortTalentMap(i, j, tabSort); });
});
break; break;
} }
case SORT_BY_POINTS_TREE: case SORT_BY_POINTS_TREE:
{ {
uint32 tabSort[] = { GetTalentPoints(talents, 0) * 100 - urand(0, 99), GetTalentPoints(talents, 1) * 100 - urand(0, 99), GetTalentPoints(talents, 2) * 100 - urand(0, 99) }; uint32 tabSort[] = {GetTalentPoints(talents, 0) * 100 - urand(0, 99),
std::sort(talents.begin(), talents.end(), [&tabSort](TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j) GetTalentPoints(talents, 1) * 100 - urand(0, 99),
{ GetTalentPoints(talents, 2) * 100 - urand(0, 99)};
return sortTalentMap(i, j, tabSort); std::sort(talents.begin(), talents.end(),
}); [&tabSort](TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j)
{ return sortTalentMap(i, j, tabSort); });
break; break;
} }
} }
@ -320,10 +320,7 @@ std::vector<TalentSpec::TalentListEntry> TalentSpec::GetTalentTree(uint32 tabpag
return std::move(retList); return std::move(retList);
} }
uint32 TalentSpec::GetTalentPoints(int32 tabpage) uint32 TalentSpec::GetTalentPoints(int32 tabpage) { return GetTalentPoints(talents, tabpage); };
{
return GetTalentPoints(talents, tabpage);
};
// Counts the point in a talent list. // Counts the point in a talent list.
uint32 TalentSpec::GetTalentPoints(std::vector<TalentListEntry>& talents, int32 tabpage) uint32 TalentSpec::GetTalentPoints(std::vector<TalentListEntry>& talents, int32 tabpage)
@ -437,7 +434,9 @@ void TalentSpec::CropTalents(uint32 level)
} }
// Substracts ranks. Follows the sorting of the newList. // Substracts ranks. Follows the sorting of the newList.
std::vector<TalentSpec::TalentListEntry> TalentSpec::SubTalentList(std::vector<TalentListEntry>& oldList, std::vector<TalentListEntry>& newList, uint32 reverse = SUBSTRACT_OLD_NEW) std::vector<TalentSpec::TalentListEntry> TalentSpec::SubTalentList(std::vector<TalentListEntry>& oldList,
std::vector<TalentListEntry>& newList,
uint32 reverse = SUBSTRACT_OLD_NEW)
{ {
std::vector<TalentSpec::TalentListEntry> deltaList = newList; std::vector<TalentSpec::TalentListEntry> deltaList = newList;

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_TALENTSPEC_H #ifndef _PLAYERBOT_TALENTSPEC_H
@ -67,7 +68,8 @@ class TalentSpec
void ReadTalents(std::string const link); void ReadTalents(std::string const link);
std::vector<TalentListEntry> GetTalentTree(uint32 tabpage); std::vector<TalentListEntry> GetTalentTree(uint32 tabpage);
std::vector<TalentListEntry> SubTalentList(std::vector<TalentListEntry>& oldList, std::vector<TalentListEntry>& newList, uint32 reverse); std::vector<TalentListEntry> SubTalentList(std::vector<TalentListEntry>& oldList,
std::vector<TalentListEntry>& newList, uint32 reverse);
}; };
class TalentPath class TalentPath

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,20 @@
/* /*
* 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. * 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_TRAVELMGR_H #ifndef _PLAYERBOT_TRAVELMGR_H
#define _PLAYERBOT_TRAVELMGR_H #define _PLAYERBOT_TRAVELMGR_H
#include <boost/functional/hash.hpp>
#include <random>
#include "AiObject.h" #include "AiObject.h"
#include "CreatureData.h" #include "CreatureData.h"
#include "GameObject.h" #include "GameObject.h"
#include "GridDefines.h" #include "GridDefines.h"
#include "PlayerbotAIConfig.h" #include "PlayerbotAIConfig.h"
#include <boost/functional/hash.hpp>
#include <random>
class GuidPosition; class GuidPosition;
class ObjectGuid; class ObjectGuid;
class Quest; class Quest;
@ -27,7 +28,7 @@ namespace G3D
class Vector2; class Vector2;
class Vector3; class Vector3;
class Vector4; class Vector4;
} } // namespace G3D
// Constructor types for WorldPosition // Constructor types for WorldPosition
enum WorldPositionConst enum WorldPositionConst
@ -84,7 +85,10 @@ class WorldPosition : public WorldLocation
WorldPosition(WorldLocation const& loc) : WorldLocation(loc) {} WorldPosition(WorldLocation const& loc) : WorldLocation(loc) {}
WorldPosition(WorldPosition const& pos) : WorldLocation(pos), visitors(pos.visitors) {} WorldPosition(WorldPosition const& pos) : WorldLocation(pos), visitors(pos.visitors) {}
WorldPosition(std::string const str); WorldPosition(std::string const str);
WorldPosition(uint32 mapid, float x, float y, float z = 0.f, float orientation = 0.f) : WorldLocation(mapid, x, y, z, orientation) { } WorldPosition(uint32 mapid, float x, float y, float z = 0.f, float orientation = 0.f)
: WorldLocation(mapid, x, y, z, orientation)
{
}
WorldPosition(uint32 mapId, const Position& pos); WorldPosition(uint32 mapId, const Position& pos);
WorldPosition(WorldObject const* wo); WorldPosition(WorldObject const* wo);
WorldPosition(std::vector<WorldPosition*> list, WorldPositionConst conType); WorldPosition(std::vector<WorldPosition*> list, WorldPositionConst conType);
@ -101,15 +105,9 @@ class WorldPosition : public WorldLocation
void setZ(float z); void setZ(float z);
void setO(float o); void setO(float o);
void addVisitor() void addVisitor() { ++visitors; }
{
++visitors;
}
void remVisitor() void remVisitor() { --visitors; }
{
--visitors;
}
// Getters // Getters
operator bool() const; operator bool() const;
@ -146,24 +144,17 @@ class WorldPosition : public WorldLocation
// Slow distance function using possible map transfers. // Slow distance function using possible map transfers.
float distance(WorldPosition* center); float distance(WorldPosition* center);
float distance(WorldPosition center) float distance(WorldPosition center) { return distance(&center); }
{
return distance(&center);
}
float fDist(WorldPosition* center); float fDist(WorldPosition* center);
float fDist(WorldPosition center) float fDist(WorldPosition center) { return fDist(&center); }
{
return fDist(&center);
}
template <class T> template <class T>
std::pair<T, WorldPosition> closest(std::vector<std::pair<T, WorldPosition>> list) std::pair<T, WorldPosition> closest(std::vector<std::pair<T, WorldPosition>> list)
{ {
return *std::min_element(list.begin(), list.end(), [this](std::pair<T, WorldPosition> i, std::pair<T, WorldPosition> j) return *std::min_element(list.begin(), list.end(),
{ [this](std::pair<T, WorldPosition> i, std::pair<T, WorldPosition> j)
return this->distance(i.second) < this->distance(j.second); { return this->distance(i.second) < this->distance(j.second); });
});
} }
template <class T> template <class T>
@ -175,47 +166,59 @@ class WorldPosition : public WorldLocation
// Returns the closest point from the list. // Returns the closest point from the list.
WorldPosition* closest(std::vector<WorldPosition*> list) WorldPosition* closest(std::vector<WorldPosition*> list)
{ {
return *std::min_element(list.begin(), list.end(), [this](WorldPosition* i, WorldPosition* j) { return this->distance(i) < this->distance(j); }); return *std::min_element(list.begin(), list.end(),
[this](WorldPosition* i, WorldPosition* j)
{ return this->distance(i) < this->distance(j); });
} }
WorldPosition closest(std::vector<WorldPosition> list) WorldPosition closest(std::vector<WorldPosition> list)
{ {
return *std::min_element(list.begin(), list.end(), [this](WorldPosition i, WorldPosition j) { return this->distance(i) < this->distance(j); }); return *std::min_element(list.begin(), list.end(),
[this](WorldPosition i, WorldPosition j)
{ return this->distance(i) < this->distance(j); });
} }
// Quick square distance in 2d plane. // Quick square distance in 2d plane.
float sqDistance2d(WorldPosition center) float sqDistance2d(WorldPosition center)
{ {
return (getX() - center.getX()) * (getX() - center.getX()) + (getY() - center.getY()) * (getY() - center.getY()); return (getX() - center.getX()) * (getX() - center.getX()) +
(getY() - center.getY()) * (getY() - center.getY());
} }
// Quick square distance calculation without map check. Used for getting the minimum distant points. // Quick square distance calculation without map check. Used for getting the minimum distant points.
float sqDistance(WorldPosition center) float sqDistance(WorldPosition center)
{ {
return (getX() - center.getX()) * (getX() - center.getX()) + (getY() - center.getY()) * return (getX() - center.getX()) * (getX() - center.getX()) +
(getY() - center.getY()) + (getZ() - center.getZ()) * (getZ() - center.getZ()); (getY() - center.getY()) * (getY() - center.getY()) +
(getZ() - center.getZ()) * (getZ() - center.getZ());
} }
float sqDistance2d(WorldPosition* center) float sqDistance2d(WorldPosition* center)
{ {
return (getX() - center->getX()) * (getX() - center->getX()) + (getY() - center->getY()) * (getY() - center->getY()); return (getX() - center->getX()) * (getX() - center->getX()) +
(getY() - center->getY()) * (getY() - center->getY());
} }
float sqDistance(WorldPosition* center) float sqDistance(WorldPosition* center)
{ {
return (getX() - center->getX()) * (getX() - center->getX()) + (getY() - center->getY()) * return (getX() - center->getX()) * (getX() - center->getX()) +
(getY() - center->getY()) + (getZ() - center->getZ()) * (getZ() - center->getZ()); (getY() - center->getY()) * (getY() - center->getY()) +
(getZ() - center->getZ()) * (getZ() - center->getZ());
} }
// Returns the closest point of the list. Fast but only works for the same map. // Returns the closest point of the list. Fast but only works for the same map.
WorldPosition* closestSq(std::vector<WorldPosition*> list) WorldPosition* closestSq(std::vector<WorldPosition*> list)
{ {
return *std::min_element(list.begin(), list.end(), [this](WorldPosition* i, WorldPosition* j) { return this->sqDistance(i) < this->sqDistance(j); }); return *std::min_element(list.begin(), list.end(),
[this](WorldPosition* i, WorldPosition* j)
{ return this->sqDistance(i) < this->sqDistance(j); });
} }
WorldPosition closestSq(std::vector<WorldPosition> list) WorldPosition closestSq(std::vector<WorldPosition> list)
{ {
return *std::min_element(list.begin(), list.end(), [this](WorldPosition i, WorldPosition j) { return this->sqDistance(i) < this->sqDistance(j); }); return *std::min_element(list.begin(), list.end(),
[this](WorldPosition i, WorldPosition j)
{ return this->sqDistance(i) < this->sqDistance(j); });
} }
float getAngleTo(WorldPosition endPos) float getAngleTo(WorldPosition endPos)
@ -224,10 +227,7 @@ class WorldPosition : public WorldLocation
return (ang >= 0) ? ang : 2 * static_cast<float>(M_PI) + ang; return (ang >= 0) ? ang : 2 * static_cast<float>(M_PI) + ang;
} }
float getAngleBetween(WorldPosition dir1, WorldPosition dir2) float getAngleBetween(WorldPosition dir1, WorldPosition dir2) { return abs(getAngleTo(dir1) - getAngleTo(dir2)); }
{
return abs(getAngleTo(dir1) - getAngleTo(dir2));
}
WorldPosition lastInRange(std::vector<WorldPosition> list, float minDist = -1.f, float maxDist = -1.f); WorldPosition lastInRange(std::vector<WorldPosition> list, float minDist = -1.f, float maxDist = -1.f);
WorldPosition firstOutRange(std::vector<WorldPosition> list, float minDist = -1.f, float maxDist = -1.f); WorldPosition firstOutRange(std::vector<WorldPosition> list, float minDist = -1.f, float maxDist = -1.f);
@ -257,7 +257,8 @@ class WorldPosition : public WorldLocation
mGridCoord getmGridCoord() mGridCoord getmGridCoord()
{ {
return std::make_pair((int32)(CENTER_GRID_ID - getX() / SIZE_OF_GRIDS), (int32)(CENTER_GRID_ID - getY() / SIZE_OF_GRIDS)); return std::make_pair((int32)(CENTER_GRID_ID - getX() / SIZE_OF_GRIDS),
(int32)(CENTER_GRID_ID - getY() / SIZE_OF_GRIDS));
} }
std::vector<mGridCoord> getmGridCoords(WorldPosition secondPos); std::vector<mGridCoord> getmGridCoords(WorldPosition secondPos);
@ -265,24 +266,15 @@ class WorldPosition : public WorldLocation
void loadMapAndVMap(uint32 mapId, uint8 x, uint8 y); void loadMapAndVMap(uint32 mapId, uint8 x, uint8 y);
void loadMapAndVMap() void loadMapAndVMap() { loadMapAndVMap(getMapId(), getmGridCoord().first, getmGridCoord().second); }
{
loadMapAndVMap(getMapId(), getmGridCoord().first, getmGridCoord().second);
}
void loadMapAndVMaps(WorldPosition secondPos); void loadMapAndVMaps(WorldPosition secondPos);
// Display functions // Display functions
WorldPosition getDisplayLocation(); WorldPosition getDisplayLocation();
float getDisplayX() float getDisplayX() { return getDisplayLocation().getY() * -1.0; }
{
return getDisplayLocation().getY() * -1.0;
}
float getDisplayY() float getDisplayY() { return getDisplayLocation().getX(); }
{
return getDisplayLocation().getX();
}
uint16 getAreaId(); uint16 getAreaId();
AreaTableEntry const* getArea(); AreaTableEntry const* getArea();
@ -299,12 +291,12 @@ class WorldPosition : public WorldLocation
return getPathFromPath({startPos}, bot); return getPathFromPath({startPos}, bot);
} }
std::vector<WorldPosition> getPathTo(WorldPosition endPos, Unit* bot) std::vector<WorldPosition> getPathTo(WorldPosition endPos, Unit* bot) { return endPos.getPathFrom(*this, bot); }
{
return endPos.getPathFrom(*this, bot);
}
bool isPathTo(std::vector<WorldPosition> path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance) { return !path.empty() && distance(path.back()) < maxDistance; }; bool isPathTo(std::vector<WorldPosition> path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance)
{
return !path.empty() && distance(path.back()) < maxDistance;
};
bool cropPathTo(std::vector<WorldPosition>& path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance); bool cropPathTo(std::vector<WorldPosition>& path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance);
bool canPathTo(WorldPosition endPos, Unit* bot) { return endPos.isPathTo(getPathTo(endPos, bot)); } bool canPathTo(WorldPosition endPos, Unit* bot) { return endPos.isPathTo(getPathTo(endPos, bot)); }
@ -369,7 +361,12 @@ inline ByteBuffer& operator>>(ByteBuffer& b, [[maybe_unused]] WorldPosition& g)
class FindPointCreatureData class FindPointCreatureData
{ {
public: public:
FindPointCreatureData(WorldPosition point1 = WorldPosition(), float radius1 = 0, uint32 entry1 = 0) { point = point1; radius = radius1; entry = entry1; } FindPointCreatureData(WorldPosition point1 = WorldPosition(), float radius1 = 0, uint32 entry1 = 0)
{
point = point1;
radius = radius1;
entry = entry1;
}
void operator()(CreatureData const& dataPair); void operator()(CreatureData const& dataPair);
std::vector<CreatureData const*> GetResult() const { return data; }; std::vector<CreatureData const*> GetResult() const { return data; };
@ -386,7 +383,12 @@ class FindPointCreatureData
class FindPointGameObjectData class FindPointGameObjectData
{ {
public: public:
FindPointGameObjectData(WorldPosition point1 = WorldPosition(), float radius1 = 0, uint32 entry1 = 0) { point = point1; radius = radius1; entry = entry1; } FindPointGameObjectData(WorldPosition point1 = WorldPosition(), float radius1 = 0, uint32 entry1 = 0)
{
point = point1;
radius = radius1;
entry = entry1;
}
void operator()(GameObjectData const& dataPair); void operator()(GameObjectData const& dataPair);
std::vector<GameObjectData const*> GetResult() const { return data; }; std::vector<GameObjectData const*> GetResult() const { return data; };
@ -453,42 +455,26 @@ class mapTransfer
{ {
public: public:
mapTransfer(WorldPosition pointFrom1, WorldPosition pointTo1, float portalLength1 = 0.1f) mapTransfer(WorldPosition pointFrom1, WorldPosition pointTo1, float portalLength1 = 0.1f)
: pointFrom(pointFrom1), pointTo(pointTo1), portalLength(portalLength1) { } : pointFrom(pointFrom1), pointTo(pointTo1), portalLength(portalLength1)
bool isFrom(WorldPosition point)
{ {
return point.getMapId() == pointFrom.getMapId();
} }
bool isTo(WorldPosition point) bool isFrom(WorldPosition point) { return point.getMapId() == pointFrom.getMapId(); }
{
return point.getMapId() == pointTo.getMapId();
}
WorldPosition* getPointFrom() bool isTo(WorldPosition point) { return point.getMapId() == pointTo.getMapId(); }
{
return &pointFrom;
}
WorldPosition* getPointTo() WorldPosition* getPointFrom() { return &pointFrom; }
{
return &pointTo;
}
bool isUseful(WorldPosition point) WorldPosition* getPointTo() { return &pointTo; }
{
return isFrom(point) || isTo(point); bool isUseful(WorldPosition point) { return isFrom(point) || isTo(point); }
}
float distance(WorldPosition point) float distance(WorldPosition point)
{ {
return isUseful(point) ? (isFrom(point) ? point.distance(pointFrom) : point.distance(pointTo)) : 200000; return isUseful(point) ? (isFrom(point) ? point.distance(pointFrom) : point.distance(pointTo)) : 200000;
} }
bool isUseful(WorldPosition start, WorldPosition end) bool isUseful(WorldPosition start, WorldPosition end) { return isFrom(start) && isTo(end); }
{
return isFrom(start) && isTo(end);
}
float distance(WorldPosition start, WorldPosition end) float distance(WorldPosition start, WorldPosition end)
{ {
@ -510,28 +496,22 @@ class TravelDestination
TravelDestination() {} TravelDestination() {}
TravelDestination(float radiusMin1, float radiusMax1) TravelDestination(float radiusMin1, float radiusMax1)
{ {
radiusMin = radiusMin1; radiusMax = radiusMax1; radiusMin = radiusMin1;
radiusMax = radiusMax1;
} }
TravelDestination(std::vector<WorldPosition*> points1, float radiusMin1, float radiusMax1) TravelDestination(std::vector<WorldPosition*> points1, float radiusMin1, float radiusMax1)
{ {
points = points1; radiusMin = radiusMin1; radiusMax = radiusMax1; points = points1;
radiusMin = radiusMin1;
radiusMax = radiusMax1;
} }
virtual ~TravelDestination() = default; virtual ~TravelDestination() = default;
void addPoint(WorldPosition* pos) void addPoint(WorldPosition* pos) { points.push_back(pos); }
{
points.push_back(pos);
}
void setExpireDelay(uint32 delay) void setExpireDelay(uint32 delay) { expireDelay = delay; }
{
expireDelay = delay;
}
void setCooldownDelay(uint32 delay) void setCooldownDelay(uint32 delay) { cooldownDelay = delay; }
{
cooldownDelay = delay;
}
void setMaxVisitors(uint32 maxVisitors1 = 0, uint32 maxVisitorsPerPoint1 = 0) void setMaxVisitors(uint32 maxVisitors1 = 0, uint32 maxVisitorsPerPoint1 = 0)
{ {
@ -543,20 +523,11 @@ class TravelDestination
uint32 getExpireDelay() { return expireDelay; } uint32 getExpireDelay() { return expireDelay; }
uint32 getCooldownDelay() { return cooldownDelay; } uint32 getCooldownDelay() { return cooldownDelay; }
void addVisitor() void addVisitor() { ++visitors; }
{
++visitors;
}
void remVisitor() void remVisitor() { --visitors; }
{
--visitors;
}
uint32 getVisitors() uint32 getVisitors() { return visitors; }
{
return visitors;
}
virtual Quest const* GetQuestTemplate() { return nullptr; } virtual Quest const* GetQuestTemplate() { return nullptr; }
virtual bool isActive([[maybe_unused]] Player* bot) { return false; } virtual bool isActive([[maybe_unused]] Player* bot) { return false; }
@ -571,8 +542,14 @@ class TravelDestination
float distanceTo(WorldPosition* pos) { return nearestPoint(pos)->distance(pos); } float distanceTo(WorldPosition* pos) { return nearestPoint(pos)->distance(pos); }
bool onMap(WorldPosition* pos) { return nearestPoint(pos)->getMapId() == pos->getMapId(); } bool onMap(WorldPosition* pos) { return nearestPoint(pos)->getMapId() == pos->getMapId(); }
virtual bool isIn(WorldPosition* pos, float radius = 0.f) { return onMap(pos) && distanceTo(pos) <= (radius? radius : radiusMin); } virtual bool isIn(WorldPosition* pos, float radius = 0.f)
virtual bool isOut(WorldPosition* pos, float radius = 0.f) { return !onMap(pos) || distanceTo(pos) > (radius? radius : radiusMax); } {
return onMap(pos) && distanceTo(pos) <= (radius ? radius : radiusMin);
}
virtual bool isOut(WorldPosition* pos, float radius = 0.f)
{
return !onMap(pos) || distanceTo(pos) > (radius ? radius : radiusMax);
}
float getRadiusMin() { return radiusMin; } float getRadiusMin() { return radiusMin; }
std::vector<WorldPosition*> touchingPoints(WorldPosition* pos); std::vector<WorldPosition*> touchingPoints(WorldPosition* pos);
@ -634,8 +611,9 @@ class QuestTravelDestination : public TravelDestination
class QuestRelationTravelDestination : public QuestTravelDestination class QuestRelationTravelDestination : public QuestTravelDestination
{ {
public: public:
QuestRelationTravelDestination(uint32 quest_id1, uint32 entry1, uint32 relation1, float radiusMin1, float radiusMax1) : QuestRelationTravelDestination(uint32 quest_id1, uint32 entry1, uint32 relation1, float radiusMin1,
QuestTravelDestination(quest_id1, radiusMin1, radiusMax1) float radiusMax1)
: QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
{ {
entry = entry1; entry = entry1;
relation = relation1; relation = relation1;
@ -656,8 +634,9 @@ class QuestRelationTravelDestination : public QuestTravelDestination
class QuestObjectiveTravelDestination : public QuestTravelDestination class QuestObjectiveTravelDestination : public QuestTravelDestination
{ {
public: public:
QuestObjectiveTravelDestination(uint32 quest_id1, uint32 entry1, uint32 objective1, float radiusMin1, float radiusMax1, uint32 itemId1 = 0) : QuestObjectiveTravelDestination(uint32 quest_id1, uint32 entry1, uint32 objective1, float radiusMin1,
QuestTravelDestination(quest_id1, radiusMin1, radiusMax1) float radiusMax1, uint32 itemId1 = 0)
: QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
{ {
objective = objective1; objective = objective1;
entry = entry1; entry = entry1;
@ -703,7 +682,8 @@ class RpgTravelDestination : public TravelDestination
class ExploreTravelDestination : public TravelDestination class ExploreTravelDestination : public TravelDestination
{ {
public: public:
ExploreTravelDestination(uint32 areaId1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1) ExploreTravelDestination(uint32 areaId1, float radiusMin1, float radiusMax1)
: TravelDestination(radiusMin1, radiusMax1)
{ {
areaId = areaId1; areaId = areaId1;
} }
@ -770,7 +750,8 @@ class TravelTarget : AiObject
{ {
public: public:
TravelTarget(PlayerbotAI* botAI) : AiObject(botAI), m_status(TRAVEL_STATUS_NONE), startTime(getMSTime()){}; TravelTarget(PlayerbotAI* botAI) : AiObject(botAI), m_status(TRAVEL_STATUS_NONE), startTime(getMSTime()){};
TravelTarget(PlayerbotAI* botAI, TravelDestination* tDestination1, WorldPosition* wPosition1) : AiObject(botAI), m_status(TRAVEL_STATUS_NONE), startTime(getMSTime()) TravelTarget(PlayerbotAI* botAI, TravelDestination* tDestination1, WorldPosition* wPosition1)
: AiObject(botAI), m_status(TRAVEL_STATUS_NONE), startTime(getMSTime())
{ {
setTarget(tDestination1, wPosition1); setTarget(tDestination1, wPosition1);
} }
@ -779,10 +760,7 @@ class TravelTarget : AiObject
void setTarget(TravelDestination* tDestination1, WorldPosition* wPosition1, bool groupCopy1 = false); void setTarget(TravelDestination* tDestination1, WorldPosition* wPosition1, bool groupCopy1 = false);
void setStatus(TravelStatus status); void setStatus(TravelStatus status);
void setExpireIn(uint32 expireMs) void setExpireIn(uint32 expireMs) { statusTime = getExpiredTime() + expireMs; }
{
statusTime = getExpiredTime() + expireMs;
}
void incRetry(bool isMove) void incRetry(bool isMove)
{ {
@ -800,15 +778,9 @@ class TravelTarget : AiObject
extendRetryCount = newCount; extendRetryCount = newCount;
} }
void setForced(bool forced1) void setForced(bool forced1) { forced = forced1; }
{
forced = forced1;
}
void setRadius(float radius1) void setRadius(float radius1) { radius = radius1; }
{
radius = radius1;
}
void copyTarget(TravelTarget* target); void copyTarget(TravelTarget* target);
void addVisitors(); void addVisitors();
@ -827,52 +799,28 @@ class TravelTarget : AiObject
return tDestination->getEntry(); return tDestination->getEntry();
} }
PlayerbotAI* getAi() PlayerbotAI* getAi() { return botAI; }
{
return botAI;
}
uint32 getExpiredTime() uint32 getExpiredTime() { return getMSTime() - startTime; }
{
return getMSTime() - startTime;
}
uint32 getTimeLeft() uint32 getTimeLeft() { return statusTime - getExpiredTime(); }
{
return statusTime - getExpiredTime();
}
uint32 getMaxTravelTime(); uint32 getMaxTravelTime();
uint32 getRetryCount(bool isMove) uint32 getRetryCount(bool isMove) { return isMove ? moveRetryCount : extendRetryCount; }
{
return isMove ? moveRetryCount: extendRetryCount;
}
bool isTraveling(); bool isTraveling();
bool isActive(); bool isActive();
bool isWorking(); bool isWorking();
bool isPreparing(); bool isPreparing();
bool isMaxRetry(bool isMove) bool isMaxRetry(bool isMove) { return isMove ? (moveRetryCount > 5) : (extendRetryCount > 5); }
{
return isMove ? (moveRetryCount > 5) : (extendRetryCount > 5);
}
TravelStatus getStatus() TravelStatus getStatus() { return m_status; }
{
return m_status;
}
TravelState getTravelState(); TravelState getTravelState();
bool isGroupCopy() bool isGroupCopy() { return groupCopy; }
{
return groupCopy;
}
bool isForced() bool isForced() { return forced; }
{
return forced;
}
protected: protected:
TravelStatus m_status; TravelStatus m_status;
@ -925,16 +873,23 @@ class TravelMgr
} }
} }
std::vector<WorldPosition*> getNextPoint(WorldPosition* center, std::vector<WorldPosition*> points, uint32 amount = 1); std::vector<WorldPosition*> getNextPoint(WorldPosition* center, std::vector<WorldPosition*> points,
uint32 amount = 1);
std::vector<WorldPosition> getNextPoint(WorldPosition center, std::vector<WorldPosition> points, uint32 amount = 1); std::vector<WorldPosition> getNextPoint(WorldPosition center, std::vector<WorldPosition> points, uint32 amount = 1);
QuestStatusData* getQuestStatus(Player* bot, uint32 questId); QuestStatusData* getQuestStatus(Player* bot, uint32 questId);
bool getObjectiveStatus(Player* bot, Quest const* pQuest, uint32 objective); bool getObjectiveStatus(Player* bot, Quest const* pQuest, uint32 objective);
uint32 getDialogStatus(Player* pPlayer, int32 questgiver, Quest const* pQuest); uint32 getDialogStatus(Player* pPlayer, int32 questgiver, Quest const* pQuest);
std::vector<TravelDestination*> getQuestTravelDestinations(Player* bot, int32 questId = -1, bool ignoreFull = false, bool ignoreInactive = false, float maxDistance = 5000, bool ignoreObjectives = false); std::vector<TravelDestination*> getQuestTravelDestinations(Player* bot, int32 questId = -1, bool ignoreFull = false,
std::vector<TravelDestination*> getRpgTravelDestinations(Player* bot, bool ignoreFull = false, bool ignoreInactive = false, float maxDistance = 5000); bool ignoreInactive = false, float maxDistance = 5000,
std::vector<TravelDestination*> getExploreTravelDestinations(Player* bot, bool ignoreFull = false, bool ignoreInactive = false); bool ignoreObjectives = false);
std::vector<TravelDestination*> getGrindTravelDestinations(Player* bot, bool ignoreFull = false, bool ignoreInactive = false, float maxDistance = 5000); std::vector<TravelDestination*> getRpgTravelDestinations(Player* bot, bool ignoreFull = false,
std::vector<TravelDestination*> getBossTravelDestinations(Player* bot, bool ignoreFull = false, bool ignoreInactive = false, float maxDistance = 25000); bool ignoreInactive = false, float maxDistance = 5000);
std::vector<TravelDestination*> getExploreTravelDestinations(Player* bot, bool ignoreFull = false,
bool ignoreInactive = false);
std::vector<TravelDestination*> getGrindTravelDestinations(Player* bot, bool ignoreFull = false,
bool ignoreInactive = false, float maxDistance = 5000);
std::vector<TravelDestination*> getBossTravelDestinations(Player* bot, bool ignoreFull = false,
bool ignoreInactive = false, float maxDistance = 25000);
void setNullTravelTarget(Player* player); void setNullTravelTarget(Player* player);
@ -946,15 +901,9 @@ class TravelMgr
NullTravelDestination* nullTravelDestination = new NullTravelDestination(); NullTravelDestination* nullTravelDestination = new NullTravelDestination();
WorldPosition* nullWorldPosition = new WorldPosition(); WorldPosition* nullWorldPosition = new WorldPosition();
void addBadVmap(uint32 mapId, uint8 x, uint8 y) void addBadVmap(uint32 mapId, uint8 x, uint8 y) { badVmap.push_back(std::make_tuple(mapId, x, y)); }
{
badVmap.push_back(std::make_tuple(mapId, x, y));
}
void addBadMmap(uint32 mapId, uint8 x, uint8 y) void addBadMmap(uint32 mapId, uint8 x, uint8 y) { badMmap.push_back(std::make_tuple(mapId, x, y)); }
{
badMmap.push_back(std::make_tuple(mapId, x, y));
}
bool isBadVmap(uint32 mapId, uint8 x, uint8 y) bool isBadVmap(uint32 mapId, uint8 x, uint8 y)
{ {
@ -984,7 +933,8 @@ class TravelMgr
std::vector<std::tuple<uint32, uint8, uint8>> badVmap, badMmap; std::vector<std::tuple<uint32, uint8, uint8>> badVmap, badMmap;
std::unordered_map<std::pair<uint32, uint32>, std::vector<mapTransfer>, boost::hash<std::pair<uint32, uint32>>> mapTransfersMap; std::unordered_map<std::pair<uint32, uint32>, std::vector<mapTransfer>, boost::hash<std::pair<uint32, uint32>>>
mapTransfersMap;
}; };
#define sTravelMgr TravelMgr::instance() #define sTravelMgr TravelMgr::instance()

View File

@ -1,18 +1,22 @@
/* /*
* 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. * 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 "TravelNode.h" #include "TravelNode.h"
#include <iomanip>
#include <regex>
#include "BudgetValues.h" #include "BudgetValues.h"
#include "PathGenerator.h" #include "PathGenerator.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "ServerFacade.h" #include "ServerFacade.h"
#include "TransportMgr.h" #include "TransportMgr.h"
#include <iomanip> // TravelNodePath(float distance = 0.1f, float extraCost = 0, TravelNodePathType pathType = TravelNodePathType::walk,
#include <regex> // uint32 pathObject = 0, bool calculated = false, std::vector<uint8> maxLevelCreature = { 0,0,0 }, float swimDistance =
// 0)
// TravelNodePath(float distance = 0.1f, float extraCost = 0, TravelNodePathType pathType = TravelNodePathType::walk, uint32 pathObject = 0, bool calculated = false, std::vector<uint8> maxLevelCreature = { 0,0,0 }, float swimDistance = 0)
std::string const TravelNodePath::print() std::string const TravelNodePath::print()
{ {
std::ostringstream out; std::ostringstream out;
@ -22,7 +26,8 @@ std::string const TravelNodePath::print()
out << std::to_string(uint8(pathType)) << ","; out << std::to_string(uint8(pathType)) << ",";
out << pathObject << ","; out << pathObject << ",";
out << (calculated ? "true" : "false") << ","; out << (calculated ? "true" : "false") << ",";
out << std::to_string(maxLevelCreature[0]) << "," << std::to_string(maxLevelCreature[1]) << "," << std::to_string(maxLevelCreature[2]) << ","; out << std::to_string(maxLevelCreature[0]) << "," << std::to_string(maxLevelCreature[1]) << ","
<< std::to_string(maxLevelCreature[2]) << ",";
out << swimDistance << "f"; out << swimDistance << "f";
return out.str().c_str(); return out.str().c_str();
@ -55,11 +60,15 @@ void TravelNodePath::calculateCost(bool distanceOnly)
FactionTemplateEntry const* factionEntry = sFactionTemplateStore.LookupEntry(cInfo->faction); FactionTemplateEntry const* factionEntry = sFactionTemplateStore.LookupEntry(cInfo->faction);
if (aReact.find(factionEntry) == aReact.end()) if (aReact.find(factionEntry) == aReact.end())
aReact.insert(std::make_pair(factionEntry, Unit::GetFactionReactionTo(factionEntry, sFactionTemplateStore.LookupEntry(1)) > REP_NEUTRAL)); aReact.insert(std::make_pair(
factionEntry, Unit::GetFactionReactionTo(
factionEntry, sFactionTemplateStore.LookupEntry(1)) > REP_NEUTRAL));
aFriend = aReact.find(factionEntry)->second; aFriend = aReact.find(factionEntry)->second;
if (hReact.find(factionEntry) == hReact.end()) if (hReact.find(factionEntry) == hReact.end())
hReact.insert(std::make_pair(factionEntry, Unit::GetFactionReactionTo(factionEntry, sFactionTemplateStore.LookupEntry(2)) > REP_NEUTRAL)); hReact.insert(std::make_pair(
factionEntry, Unit::GetFactionReactionTo(
factionEntry, sFactionTemplateStore.LookupEntry(2)) > REP_NEUTRAL));
hFriend = hReact.find(factionEntry)->second; hFriend = hReact.find(factionEntry)->second;
if (maxLevelCreature[0] < cInfo->maxlevel && !aFriend && !hFriend) if (maxLevelCreature[0] < cInfo->maxlevel && !aFriend && !hFriend)
@ -116,7 +125,9 @@ float TravelNodePath::getCost(Player* bot, uint32 cGold)
TaxiNodesEntry const* startTaxiNode = sTaxiNodesStore.LookupEntry(taxiPath->from); TaxiNodesEntry const* startTaxiNode = sTaxiNodesStore.LookupEntry(taxiPath->from);
TaxiNodesEntry const* endTaxiNode = sTaxiNodesStore.LookupEntry(taxiPath->to); TaxiNodesEntry const* endTaxiNode = sTaxiNodesStore.LookupEntry(taxiPath->to);
if (!startTaxiNode || !endTaxiNode || !startTaxiNode->MountCreatureID[bot->GetTeamId() == TEAM_ALLIANCE ? 1 : 0] || !endTaxiNode->MountCreatureID[bot->GetTeamId() == TEAM_ALLIANCE ? 1 : 0]) if (!startTaxiNode || !endTaxiNode ||
!startTaxiNode->MountCreatureID[bot->GetTeamId() == TEAM_ALLIANCE ? 1 : 0] ||
!endTaxiNode->MountCreatureID[bot->GetTeamId() == TEAM_ALLIANCE ? 1 : 0])
return -1; return -1;
} }
@ -127,7 +138,8 @@ float TravelNodePath::getCost(Player* bot, uint32 cGold)
swimSpeed *= 1.5; swimSpeed *= 1.5;
uint32 level = bot->GetLevel(); uint32 level = bot->GetLevel();
bool isAlliance = Unit::GetFactionReactionTo(bot->GetFactionTemplateEntry(), sFactionTemplateStore.LookupEntry(1)) > REP_NEUTRAL; bool isAlliance = Unit::GetFactionReactionTo(bot->GetFactionTemplateEntry(),
sFactionTemplateStore.LookupEntry(1)) > REP_NEUTRAL;
int factionAnnoyance = 0; int factionAnnoyance = 0;
if (maxLevelCreature.size() > 0) if (maxLevelCreature.size() > 0)
@ -257,7 +269,9 @@ TravelNodePath* TravelNode::buildPath(TravelNode* endNode, Unit* bot, bool postP
if (isTransport() && path.size() > 1) if (isTransport() && path.size() > 1)
{ {
WorldPosition secondPos = *std::next(path.begin()); //This is to prevent bots from jumping in the water from a transport. Need to remove this when transports are properly handled. WorldPosition secondPos =
*std::next(path.begin()); // This is to prevent bots from jumping in the water from a transport. Need to
// remove this when transports are properly handled.
if (secondPos.getMap() && secondPos.isInWater()) if (secondPos.getMap() && secondPos.isInWater())
canPath = false; canPath = false;
} }
@ -292,7 +306,6 @@ TravelNodePath* TravelNode::buildPath(TravelNode* endNode, Unit* bot, bool postP
return returnNodePath; return returnNodePath;
} }
// Generic routine to remove references to nodes. // Generic routine to remove references to nodes.
void TravelNode::removeLinkTo(TravelNode* node, bool removePaths) void TravelNode::removeLinkTo(TravelNode* node, bool removePaths)
{ {
@ -341,7 +354,8 @@ std::vector<TravelNode*> TravelNode::getNodeMap(bool importantOnly, std::vector<
TravelNode* nextNode = nextPath.first; TravelNode* nextNode = nextPath.first;
if (std::find(openList.begin(), openList.end(), nextNode) == openList.end()) if (std::find(openList.begin(), openList.end(), nextNode) == openList.end())
{ {
if (ignoreNodes.empty() || std::find(ignoreNodes.begin(), ignoreNodes.end(), nextNode) == ignoreNodes.end()) if (ignoreNodes.empty() ||
std::find(ignoreNodes.begin(), ignoreNodes.end(), nextNode) == ignoreNodes.end())
openList.push_back(nextNode); openList.push_back(nextNode);
} }
} }
@ -377,7 +391,6 @@ bool TravelNode::isUselessLink(TravelNode* farNode)
// Is it quicker to go past second node to reach first node instead of going directly? // Is it quicker to go past second node to reach first node instead of going directly?
if (nearLength + nearNode->linkDistanceTo(farNode) < farLength * 1.1) if (nearLength + nearNode->linkDistanceTo(farNode) < farLength * 1.1)
return true; return true;
} }
else else
{ {
@ -465,8 +478,8 @@ bool TravelNode::cropUselessLinks()
if (firstNode == secondNode) if (firstNode == secondNode)
continue; continue;
if (std::find(toRemove.begin(), toRemove.end(), [firstNode, secondNode](std::pair<TravelNode*, TravelNode*> pair) {return pair.first == firstNode || pair.first == secondNode;}) != toRemove.end()) if (std::find(toRemove.begin(), toRemove.end(), [firstNode, secondNode](std::pair<TravelNode*, TravelNode*>
continue; pair) {return pair.first == firstNode || pair.first == secondNode;}) != toRemove.end()) continue;
if (firstNode->hasLinkTo(secondNode)) if (firstNode->hasLinkTo(secondNode))
{ {
@ -489,8 +502,8 @@ bool TravelNode::cropUselessLinks()
if (route.hasNode(this)) if (route.hasNode(this))
continue; continue;
//Is it quicker to go past first (and multiple) nodes to reach the second node instead of going directly? //Is it quicker to go past first (and multiple) nodes to reach the second node instead of going
if (firstLength + route.getLength() < secondLength * 1.1) directly? if (firstLength + route.getLength() < secondLength * 1.1)
{ {
if (secondNode->hasLinkTo(this) && !firstNode->hasLinkTo(this)) if (secondNode->hasLinkTo(this) && !firstNode->hasLinkTo(this))
continue; continue;
@ -513,8 +526,8 @@ bool TravelNode::cropUselessLinks()
if (this == secondNode) if (this == secondNode)
continue; continue;
if (std::find(toRemove.begin(), toRemove.end(), [firstNode, secondNode](std::pair<TravelNode*, TravelNode*> pair) {return pair.first == firstNode || pair.first == secondNode; }) != toRemove.end()) if (std::find(toRemove.begin(), toRemove.end(), [firstNode, secondNode](std::pair<TravelNode*,
continue; TravelNode*> pair) {return pair.first == firstNode || pair.first == secondNode; }) != toRemove.end()) continue;
if (firstNode->hasLinkTo(secondNode)) if (firstNode->hasLinkTo(secondNode))
{ {
@ -537,8 +550,8 @@ bool TravelNode::cropUselessLinks()
if (route.hasNode(this)) if (route.hasNode(this))
continue; continue;
//Is it quicker to go past first (and multiple) nodes to reach the second node instead of going directly? //Is it quicker to go past first (and multiple) nodes to reach the second node instead of going
if (firstLength + route.getLength() < secondLength * 1.1) directly? if (firstLength + route.getLength() < secondLength * 1.1)
{ {
if (secondNode->hasLinkTo(this) && !firstNode->hasLinkTo(this)) if (secondNode->hasLinkTo(this) && !firstNode->hasLinkTo(this))
continue; continue;
@ -679,7 +692,9 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
if (&p != &fullPath.front()) if (&p != &fullPath.front())
totalDist += p.point.sqDistance(std::prev(&p)->point); totalDist += p.point.sqDistance(std::prev(&p)->point);
if (curDist < sPlayerbotAIConfig->tooCloseDistance * sPlayerbotAIConfig->tooCloseDistance) // We are on the path. This is a good starting point if (curDist <
sPlayerbotAIConfig->tooCloseDistance *
sPlayerbotAIConfig->tooCloseDistance) // We are on the path. This is a good starting point
{ {
minDist = curDist; minDist = curDist;
totalDist = curDist; totalDist = curDist;
@ -691,7 +706,9 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
if (!firstNode) if (!firstNode)
firstNode = p.point; firstNode = p.point;
if (minDist == -1 || curDist < minDist || (curDist < maxDistSq && curDist < totalDist / 2)) //Start building from the last closest point or a point that is close but far on the path. if (minDist == -1 || curDist < minDist ||
(curDist < maxDistSq && curDist < totalDist / 2)) // Start building from the last closest point or
// a point that is close but far on the path.
{ {
minDist = curDist; minDist = curDist;
totalDist = curDist; totalDist = curDist;
@ -736,7 +753,9 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
return true; return true;
} }
bool TravelPath::shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathNodePoint>::iterator beg, std::vector<PathNodePoint>::iterator ed, std::vector<PathNodePoint>::iterator p, float& moveDist, float maxDist) bool TravelPath::shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathNodePoint>::iterator beg,
std::vector<PathNodePoint>::iterator ed, std::vector<PathNodePoint>::iterator p,
float& moveDist, float maxDist)
{ {
if (p == ed) // We are the end. Stop now. if (p == ed) // We are the end. Stop now.
return false; return false;
@ -764,7 +783,8 @@ bool TravelPath::shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathN
// We are moving to a transport node. // We are moving to a transport node.
if (p->type == NODE_TRANSPORT && p->entry) if (p->type == NODE_TRANSPORT && p->entry)
{ {
if (nextP->type != NODE_TRANSPORT && p != beg && std::prev(p)->type != NODE_TRANSPORT) //We are not using the transport. Skip it. if (nextP->type != NODE_TRANSPORT && p != beg &&
std::prev(p)->type != NODE_TRANSPORT) // We are not using the transport. Skip it.
return true; return true;
return false; // Teleport to exit of transport. return false; // Teleport to exit of transport.
@ -778,7 +798,8 @@ bool TravelPath::shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathN
float nextMove = p->point.distance(nextP->point); float nextMove = p->point.distance(nextP->point);
if (p->point.getMapId() != startPos.getMapId() || ((moveDist + nextMove > maxDist || startPos.distance(nextP->point) > maxDist) && moveDist > 0)) if (p->point.getMapId() != startPos.getMapId() ||
((moveDist + nextMove > maxDist || startPos.distance(nextP->point) > maxDist) && moveDist > 0))
{ {
return false; return false;
} }
@ -789,7 +810,8 @@ bool TravelPath::shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathN
} }
// Next position to move to // Next position to move to
WorldPosition TravelPath::getNextPoint(WorldPosition startPos, float maxDist, TravelNodePathType& pathType, uint32& entry) WorldPosition TravelPath::getNextPoint(WorldPosition startPos, float maxDist, TravelNodePathType& pathType,
uint32& entry)
{ {
if (getPath().empty()) if (getPath().empty())
return WorldPosition(); return WorldPosition();
@ -882,7 +904,8 @@ std::ostringstream const TravelPath::print()
std::ostringstream out; std::ostringstream out;
out << sPlayerbotAIConfig->GetTimestampStr(); out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00," << "1,"; out << "+00,"
<< "1,";
out << std::fixed; out << std::fixed;
WorldPosition().printWKT(getPointPath(), out, 1); WorldPosition().printWKT(getPointPath(), out, 1);
@ -901,7 +924,8 @@ float TravelNodeRoute::getTotalDistance()
return totalLength; return totalLength;
} }
TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, std::vector<WorldPosition> pathToEnd, [[maybe_unused]] Unit* bot) TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, std::vector<WorldPosition> pathToEnd,
[[maybe_unused]] Unit* bot)
{ {
TravelPath travelPath; TravelPath travelPath;
@ -921,7 +945,8 @@ TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, st
{ {
if (!prevNode->isTransport()) if (!prevNode->isTransport())
nodePath = prevNode->buildPath(node, nullptr); nodePath = prevNode->buildPath(node, nullptr);
else //For transports we have no proper path since the node is in air/water. Instead we build a reverse path and follow that. else // For transports we have no proper path since the node is in air/water. Instead we build a
// reverse path and follow that.
{ {
node->buildPath(prevNode, nullptr); // Reverse build to get proper path. node->buildPath(prevNode, nullptr); // Reverse build to get proper path.
nodePath = prevNode->getPathTo(node); nodePath = prevNode->getPathTo(node);
@ -930,9 +955,11 @@ TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, st
TravelNodePath returnNodePath; TravelNodePath returnNodePath;
if (!nodePath || !nodePath->getComplete()) //It looks like we can't properly path to our node. Make a temporary reverse path and see if that works instead. if (!nodePath || !nodePath->getComplete()) // It looks like we can't properly path to our node. Make a
// temporary reverse path and see if that works instead.
{ {
returnNodePath = *node->buildPath(prevNode, nullptr); //Build reverse path and save it to a temporary variable. returnNodePath =
*node->buildPath(prevNode, nullptr); // Build reverse path and save it to a temporary variable.
std::vector<WorldPosition> path = returnNodePath.getPath(); std::vector<WorldPosition> path = returnNodePath.getPath();
std::reverse(path.begin(), path.end()); // Reverse the path std::reverse(path.begin(), path.end()); // Reverse the path
returnNodePath.setPath(path); returnNodePath.setPath(path);
@ -953,12 +980,14 @@ TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, st
} }
else if (nodePath->getPathType() == TravelNodePathType::transport) // Move onto transport else if (nodePath->getPathType() == TravelNodePathType::transport) // Move onto transport
{ {
travelPath.addPoint(*prevNode->getPosition(), NODE_TRANSPORT, nodePath->getPathObject()); // Departure point travelPath.addPoint(*prevNode->getPosition(), NODE_TRANSPORT,
nodePath->getPathObject()); // Departure point
travelPath.addPoint(*node->getPosition(), NODE_TRANSPORT, nodePath->getPathObject()); // Arrival point travelPath.addPoint(*node->getPosition(), NODE_TRANSPORT, nodePath->getPathObject()); // Arrival point
} }
else if (nodePath->getPathType() == TravelNodePathType::flightPath) // Use the flightpath else if (nodePath->getPathType() == TravelNodePathType::flightPath) // Use the flightpath
{ {
travelPath.addPoint(*prevNode->getPosition(), NODE_FLIGHTPATH, nodePath->getPathObject()); // Departure point travelPath.addPoint(*prevNode->getPosition(), NODE_FLIGHTPATH,
nodePath->getPathObject()); // Departure point
travelPath.addPoint(*node->getPosition(), NODE_FLIGHTPATH, nodePath->getPathObject()); // Arrival point travelPath.addPoint(*node->getPosition(), NODE_FLIGHTPATH, nodePath->getPathObject()); // Arrival point
} }
else if (nodePath->getPathType() == TravelNodePathType::teleportSpell) else if (nodePath->getPathType() == TravelNodePathType::teleportSpell)
@ -970,13 +999,18 @@ TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, st
{ {
std::vector<WorldPosition> path = nodePath->getPath(); std::vector<WorldPosition> path = nodePath->getPath();
if (path.size() > 1 && node != nodes.back()) // Remove the last point since that will also be the start of the next path. if (path.size() > 1 &&
node != nodes.back()) // Remove the last point since that will also be the start of the next path.
path.pop_back(); path.pop_back();
if (path.size() > 1 && prevNode->isPortal() && nodePath->getPathType() != TravelNodePathType::portal) // Do not move to the area trigger if we don't plan to take the portal. if (path.size() > 1 && prevNode->isPortal() &&
nodePath->getPathType() != TravelNodePathType::portal) // Do not move to the area trigger if we
// don't plan to take the portal.
path.erase(path.begin()); path.erase(path.begin());
if (path.size() > 1 && prevNode->isTransport() && nodePath->getPathType() != TravelNodePathType::transport) // Do not move to the transport if we aren't going to take it. if (path.size() > 1 && prevNode->isTransport() &&
nodePath->getPathType() !=
TravelNodePathType::transport) // Do not move to the transport if we aren't going to take it.
path.erase(path.begin()); path.erase(path.begin());
travelPath.addPath(path, NODE_PATH); travelPath.addPath(path, NODE_PATH);
@ -996,7 +1030,9 @@ std::ostringstream const TravelNodeRoute::print()
std::ostringstream out; std::ostringstream out;
out << sPlayerbotAIConfig->GetTimestampStr(); out << sPlayerbotAIConfig->GetTimestampStr();
out << "+00" << ",0," << "\"LINESTRING("; out << "+00"
<< ",0,"
<< "\"LINESTRING(";
for (auto& node : nodes) for (auto& node : nodes)
{ {
@ -1036,7 +1072,9 @@ TravelNodeMap::TravelNodeMap(TravelNodeMap* baseMap)
baseMap->m_nMapMtx.unlock_shared(); baseMap->m_nMapMtx.unlock_shared();
} }
TravelNode* TravelNodeMap::addNode(WorldPosition pos, std::string const preferedName, bool isImportant, bool checkDuplicate, [[maybe_unused]] bool transport, [[maybe_unused]] uint32 transportId) TravelNode* TravelNodeMap::addNode(WorldPosition pos, std::string const preferedName, bool isImportant,
bool checkDuplicate, [[maybe_unused]] bool transport,
[[maybe_unused]] uint32 transportId)
{ {
TravelNode* newNode; TravelNode* newNode;
@ -1119,12 +1157,15 @@ std::vector<TravelNode*> TravelNodeMap::getNodes(WorldPosition pos, float range)
retVec.push_back(node); retVec.push_back(node);
} }
std::sort(retVec.begin(), retVec.end(), [pos](TravelNode* i, TravelNode* j) { return i->getPosition()->distance(pos) < j->getPosition()->distance(pos); }); std::sort(retVec.begin(), retVec.end(),
[pos](TravelNode* i, TravelNode* j)
{ return i->getPosition()->distance(pos) < j->getPosition()->distance(pos); });
return std::move(retVec); return std::move(retVec);
} }
TravelNode* TravelNodeMap::getNode(WorldPosition pos, [[maybe_unused]] std::vector<WorldPosition>& ppath, Unit* bot, float range) TravelNode* TravelNodeMap::getNode(WorldPosition pos, [[maybe_unused]] std::vector<WorldPosition>& ppath, Unit* bot,
float range)
{ {
float x = pos.getX(); float x = pos.getX();
float y = pos.getY(); float y = pos.getY();
@ -1210,7 +1251,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
// childNode->parent = startStub; // childNode->parent = startStub;
open.push_back(childNode); open.push_back(childNode);
std::push_heap(open.begin(), open.end(), [](TravelNodeStub* i, TravelNodeStub* j) {return i->m_f < j->m_f; }); std::push_heap(open.begin(), open.end(),
[](TravelNodeStub* i, TravelNodeStub* j) { return i->m_f < j->m_f; });
childNode->open = true; childNode->open = true;
} }
} }
@ -1238,7 +1280,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
currentNode->close = true; currentNode->close = true;
closed.push_back(currentNode); closed.push_back(currentNode);
if (currentNode->dataNode == goal || (currentNode->dataNode->getMapId() != start->getMapId() && currentNode->dataNode->isWalking())) if (currentNode->dataNode == goal ||
(currentNode->dataNode->getMapId() != start->getMapId() && currentNode->dataNode->isWalking()))
{ {
TravelNodeStub* parent = currentNode->parent; TravelNodeStub* parent = currentNode->parent;
@ -1266,7 +1309,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
childNode = &m_stubs.insert(std::make_pair(linkNode, TravelNodeStub(linkNode))).first->second; childNode = &m_stubs.insert(std::make_pair(linkNode, TravelNodeStub(linkNode))).first->second;
g = currentNode->m_g + linkCost; // stance from start + distance between the two nodes g = currentNode->m_g + linkCost; // stance from start + distance between the two nodes
if ((childNode->open || childNode->close) && childNode->m_g <= g) // n' is already in opend or closed with a lower cost g(n') if ((childNode->open || childNode->close) &&
childNode->m_g <= g) // n' is already in opend or closed with a lower cost g(n')
continue; // consider next successor continue; // consider next successor
h = childNode->dataNode->fDist(goal) / botSpeed; h = childNode->dataNode->fDist(goal) / botSpeed;
@ -1285,7 +1329,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
if (!childNode->open) if (!childNode->open)
{ {
open.push_back(childNode); open.push_back(childNode);
std::push_heap(open.begin(), open.end(), [](TravelNodeStub* i, TravelNodeStub* j) {return i->m_f < j->m_f; }); std::push_heap(open.begin(), open.end(),
[](TravelNodeStub* i, TravelNodeStub* j) { return i->m_f < j->m_f; });
childNode->open = true; childNode->open = true;
} }
} }
@ -1294,7 +1339,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
return TravelNodeRoute(); return TravelNodeRoute();
} }
TravelNodeRoute TravelNodeMap::getRoute(WorldPosition startPos, WorldPosition endPos, std::vector<WorldPosition>& startPath, Player* bot) TravelNodeRoute TravelNodeMap::getRoute(WorldPosition startPos, WorldPosition endPos,
std::vector<WorldPosition>& startPath, Player* bot)
{ {
if (m_nodes.empty()) if (m_nodes.empty())
return TravelNodeRoute(); return TravelNodeRoute();
@ -1303,15 +1349,11 @@ TravelNodeRoute TravelNodeMap::getRoute(WorldPosition startPos, WorldPosition en
std::vector<TravelNode*> startNodes = m_nodes, endNodes = m_nodes; std::vector<TravelNode*> startNodes = m_nodes, endNodes = m_nodes;
// Partial sort to get the closest 5 nodes at the begin of the array. // Partial sort to get the closest 5 nodes at the begin of the array.
std::partial_sort(startNodes.begin(), startNodes.begin() + 5, startNodes.end(), [startPos](TravelNode* i, TravelNode* j) std::partial_sort(startNodes.begin(), startNodes.begin() + 5, startNodes.end(),
{ [startPos](TravelNode* i, TravelNode* j) { return i->fDist(startPos) < j->fDist(startPos); });
return i->fDist(startPos) < j->fDist(startPos);
});
std::partial_sort(endNodes.begin(), endNodes.begin() + 5, endNodes.end(), [endPos](TravelNode* i, TravelNode* j) std::partial_sort(endNodes.begin(), endNodes.begin() + 5, endNodes.end(),
{ [endPos](TravelNode* i, TravelNode* j) { return i->fDist(endPos) < j->fDist(endPos); });
return i->fDist(endPos) < j->fDist(endPos);
});
// Cycle over the combinations of these 5 nodes. // Cycle over the combinations of these 5 nodes.
uint32 startI = 0, endI = 0; uint32 startI = 0, endI = 0;
@ -1332,7 +1374,8 @@ TravelNodeRoute TravelNodeMap::getRoute(WorldPosition startPos, WorldPosition en
// Check if the bot can actually walk to this start position. // Check if the bot can actually walk to this start position.
newStartPath = startPath; newStartPath = startPath;
if (startNodePosition.cropPathTo(newStartPath, maxStartDistance) || if (startNodePosition.cropPathTo(newStartPath, maxStartDistance) ||
startNode->getPosition()->isPathTo(newStartPath = startPos.getPathTo(startNodePosition, nullptr), maxStartDistance)) startNode->getPosition()->isPathTo(newStartPath = startPos.getPathTo(startNodePosition, nullptr),
maxStartDistance))
{ {
startPath = newStartPath; startPath = newStartPath;
return route; return route;
@ -1394,8 +1437,8 @@ TravelPath TravelNodeMap::getFullPath(WorldPosition startPos, WorldPosition endP
// Then bot has to move towards/along the route. // Then bot has to move towards/along the route.
sTravelNodeMap->m_nMapMtx.lock_shared(); sTravelNodeMap->m_nMapMtx.lock_shared();
//Find the route of nodes starting at a node closest to the start position and ending at a node closest to the endposition. // Find the route of nodes starting at a node closest to the start position and ending at a node closest to the
//Also returns longPath: The path from the start position to the first node in the route. // endposition. Also returns longPath: The path from the start position to the first node in the route.
TravelNodeRoute route = sTravelNodeMap->getRoute(startPos, endPos, beginPath, bot); TravelNodeRoute route = sTravelNodeMap->getRoute(startPos, endPos, beginPath, bot);
if (route.isEmpty()) if (route.isEmpty())
@ -1468,7 +1511,6 @@ TravelNode* TravelNodeMap::addZoneLinkNode(TravelNode* startNode)
zoneName = newZoneName; zoneName = newZoneName;
} }
} }
} }
@ -1518,7 +1560,6 @@ void TravelNodeMap::manageNodes(Unit* bot, bool mapFull)
if (m_nMapMtx.try_lock()) if (m_nMapMtx.try_lock())
{ {
TravelNode* startNode; TravelNode* startNode;
TravelNode* newNode; TravelNode* newNode;
@ -1552,7 +1593,6 @@ void TravelNodeMap::manageNodes(Unit* bot, bool mapFull)
rePrint = nodeDone || rePrint || newNode; rePrint = nodeDone || rePrint || newNode;
} }
} }
if (rePrint && (mapFull || !urand(0, 20))) if (rePrint && (mapFull || !urand(0, 20)))
@ -1575,13 +1615,15 @@ void TravelNodeMap::generateNpcNodes()
for (auto& creatureData : WorldPosition().getCreaturesNear()) for (auto& creatureData : WorldPosition().getCreaturesNear())
{ {
WorldPosition guidP(creatureData->mapid, creatureData->posX, creatureData->posY, creatureData->posZ, creatureData->orientation); WorldPosition guidP(creatureData->mapid, creatureData->posX, creatureData->posY, creatureData->posZ,
creatureData->orientation);
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureData->id1); CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureData->id1);
if (!cInfo) if (!cInfo)
continue; continue;
uint32 flagMask = UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_FLIGHTMASTER | UNIT_NPC_FLAG_SPIRITHEALER | UNIT_NPC_FLAG_SPIRITGUIDE; uint32 flagMask = UNIT_NPC_FLAG_INNKEEPER | UNIT_NPC_FLAG_FLIGHTMASTER | UNIT_NPC_FLAG_SPIRITHEALER |
UNIT_NPC_FLAG_SPIRITGUIDE;
if (cInfo->npcflag & flagMask) if (cInfo->npcflag & flagMask)
{ {
@ -1674,7 +1716,8 @@ void TravelNodeMap::generateAreaTriggerNodes()
continue; continue;
WorldPosition inPos = WorldPosition(at->map, at->x, at->y, at->z, at->orientation); WorldPosition inPos = WorldPosition(at->map, at->x, at->y, at->z, at->orientation);
WorldPosition outPos = WorldPosition(atEntry.target_mapId, atEntry.target_X, atEntry.target_Y, atEntry.target_Z, atEntry.target_Orientation); WorldPosition outPos = WorldPosition(atEntry.target_mapId, atEntry.target_X, atEntry.target_Y, atEntry.target_Z,
atEntry.target_Orientation);
std::string nodeName; std::string nodeName;
@ -1699,7 +1742,8 @@ void TravelNodeMap::generateAreaTriggerNodes()
continue; continue;
WorldPosition inPos = WorldPosition(at->map, at->x, at->y, at->z, at->orientation); WorldPosition inPos = WorldPosition(at->map, at->x, at->y, at->z, at->orientation);
WorldPosition outPos = WorldPosition(atEntry.target_mapId, atEntry.target_X, atEntry.target_Y, atEntry.target_Z, atEntry.target_Orientation); WorldPosition outPos = WorldPosition(atEntry.target_mapId, atEntry.target_X, atEntry.target_Y, atEntry.target_Z,
atEntry.target_Orientation);
std::string nodeName; std::string nodeName;
@ -1756,7 +1800,8 @@ void TravelNodeMap::generateTransportNodes()
for (auto& transport : WorldPosition().getGameObjectsNear(0, itr.first)) for (auto& transport : WorldPosition().getGameObjectsNear(0, itr.first))
{ {
prevNode = nullptr; prevNode = nullptr;
WorldPosition basePos(transport->mapid, transport->posX, transport->posY, transport->posZ, transport->orientation); WorldPosition basePos(transport->mapid, transport->posX, transport->posY, transport->posZ,
transport->orientation);
WorldPosition lPos = WorldPosition(); WorldPosition lPos = WorldPosition();
for (auto& p : aPath) for (auto& p : aPath)
@ -1764,7 +1809,9 @@ void TravelNodeMap::generateTransportNodes()
float dx = -1 * p.second->X; float dx = -1 * p.second->X;
float dy = -1 * p.second->Y; float dy = -1 * p.second->Y;
WorldPosition pos = WorldPosition(basePos.getMapId(), basePos.getX() + dx, basePos.getY() + dy, basePos.getZ() + p.second->Z, basePos.getO()); WorldPosition pos =
WorldPosition(basePos.getMapId(), basePos.getX() + dx, basePos.getY() + dy,
basePos.getZ() + p.second->Z, basePos.getO());
if (prevNode) if (prevNode)
{ {
@ -1773,7 +1820,8 @@ void TravelNodeMap::generateTransportNodes()
if (pos.distance(&lPos) == 0) if (pos.distance(&lPos) == 0)
{ {
TravelNode* node = sTravelNodeMap->addNode(pos, data->name, true, true, true, itr.first); TravelNode* node =
sTravelNodeMap->addNode(pos, data->name, true, true, true, itr.first);
if (!prevNode) if (!prevNode)
{ {
@ -1784,7 +1832,8 @@ void TravelNodeMap::generateTransportNodes()
{ {
float totalTime = (p.second->TimeSeg - timeStart) / 1000.0f; float totalTime = (p.second->TimeSeg - timeStart) / 1000.0f;
TravelNodePath travelPath(0.1f, totalTime, (uint8)TravelNodePathType::transport, itr.first, true); TravelNodePath travelPath(0.1f, totalTime, (uint8)TravelNodePathType::transport,
itr.first, true);
node->setPathTo(prevNode, travelPath); node->setPathTo(prevNode, travelPath);
ppath.clear(); ppath.clear();
ppath.push_back(pos); ppath.push_back(pos);
@ -1803,13 +1852,16 @@ void TravelNodeMap::generateTransportNodes()
{ {
float dx = -1 * p.second->X; float dx = -1 * p.second->X;
float dy = -1 * p.second->Y; float dy = -1 * p.second->Y;
WorldPosition pos = WorldPosition(basePos.getMapId(), basePos.getX() + dx, basePos.getY() + dy, basePos.getZ() + p.second->Z, basePos.getO()); WorldPosition pos =
WorldPosition(basePos.getMapId(), basePos.getX() + dx, basePos.getY() + dy,
basePos.getZ() + p.second->Z, basePos.getO());
ppath.push_back(pos); ppath.push_back(pos);
if (pos.distance(&lPos) == 0) if (pos.distance(&lPos) == 0)
{ {
TravelNode* node = sTravelNodeMap->addNode(pos, data->name, true, true, true, itr.first); TravelNode* node =
sTravelNodeMap->addNode(pos, data->name, true, true, true, itr.first);
if (node != prevNode) if (node != prevNode)
{ {
if (p.second->TimeSeg < timeStart) if (p.second->TimeSeg < timeStart)
@ -1817,7 +1869,8 @@ void TravelNodeMap::generateTransportNodes()
float totalTime = (p.second->TimeSeg - timeStart) / 1000.0f; float totalTime = (p.second->TimeSeg - timeStart) / 1000.0f;
TravelNodePath travelPath(0.1f, totalTime, (uint8)TravelNodePathType::transport, itr.first, true); TravelNodePath travelPath(0.1f, totalTime, (uint8)TravelNodePathType::transport,
itr.first, true);
travelPath.setPath(ppath); travelPath.setPath(ppath);
node->setPathTo(prevNode, travelPath); node->setPathTo(prevNode, travelPath);
ppath.clear(); ppath.clear();
@ -1892,7 +1945,8 @@ void TravelNodeMap::generateTransportNodes()
if (node != prevNode) if (node != prevNode)
{ {
TravelNodePath travelPath(0.1f, 0.0, (uint8)TravelNodePathType::transport, itr.first, true); TravelNodePath travelPath(0.1f, 0.0, (uint8)TravelNodePathType::transport, itr.first,
true);
travelPath.setPathAndCost(ppath, moveSpeed); travelPath.setPathAndCost(ppath, moveSpeed);
node->setPathTo(prevNode, travelPath); node->setPathTo(prevNode, travelPath);
@ -1952,7 +2006,6 @@ void TravelNodeMap::generateWalkPaths()
nodeMaps[startNode->getMapId()] = true; nodeMaps[startNode->getMapId()] = true;
} }
for (auto& map : nodeMaps) for (auto& map : nodeMaps)
{ {
for (auto& startNode : sTravelNodeMap->getNodes(WorldPosition(map.first, 1, 1))) for (auto& startNode : sTravelNodeMap->getNodes(WorldPosition(map.first, 1, 1)))
@ -2196,16 +2249,20 @@ void TravelNodeMap::printNodeStore()
std::string name = node->getName(); std::string name = node->getName();
name.erase(remove(name.begin(), name.end(), '\"'), name.end()); name.erase(remove(name.begin(), name.end(), '\"'), name.end());
// struct addNode {uint32 node; WorldPosition point; std::string const name; bool isPortal; bool isTransport; uint32 transportId; }; // struct addNode {uint32 node; WorldPosition point; std::string const name; bool isPortal; bool
// isTransport; uint32 transportId; };
out << std::fixed << std::setprecision(2) << " addNodes.push_back(addNode{" << i << ","; out << std::fixed << std::setprecision(2) << " addNodes.push_back(addNode{" << i << ",";
out << "WorldPosition(" << node->getMapId() << ", " << node->getX() << "f, " << node->getY() << "f, " << node->getZ() << "f, " << node->getO() << "f),"; out << "WorldPosition(" << node->getMapId() << ", " << node->getX() << "f, " << node->getY() << "f, "
<< node->getZ() << "f, " << node->getO() << "f),";
out << "\"" << name << "\""; out << "\"" << name << "\"";
if (node->isTransport()) if (node->isTransport())
out << "," << (node->isTransport() ? "true" : "false") << "," << node->getTransportId(); out << "," << (node->isTransport() ? "true" : "false") << "," << node->getTransportId();
out << "});"; out << "});";
/* /*
out << std::fixed << std::setprecision(2) << " nodes[" << i << "] = sTravelNodeMap->addNode(&WorldPosition(" << node->getMapId() << "," << node->getX() << "f," << node->getY() << "f," << node->getZ() << "f,"<< node->getO() <<"f), \"" out << std::fixed << std::setprecision(2) << " nodes[" << i << "] =
sTravelNodeMap->addNode(&WorldPosition(" << node->getMapId() << "," << node->getX() << "f," << node->getY()
<< "f," << node->getZ() << "f,"<< node->getO() <<"f), \""
<< name << "\", " << (node->isImportant() ? "true" : "false") << ", true"; << name << "\", " << (node->isImportant() ? "true" : "false") << ", true";
if (node->isTransport()) if (node->isTransport())
out << "," << (node->isTransport() ? "true" : "false") << "," << node->getTransportId(); out << "," << (node->isTransport() ? "true" : "false") << "," << node->getTransportId();
@ -2225,13 +2282,16 @@ void TravelNodeMap::printNodeStore()
{ {
std::ostringstream out; std::ostringstream out;
// struct linkNode { uint32 node1; uint32 node2; float distance; float extraCost; bool isPortal; bool isTransport; uint32 maxLevelMob; uint32 maxLevelAlliance; uint32 maxLevelHorde; float swimDistance; }; // struct linkNode { uint32 node1; uint32 node2; float distance; float extraCost; bool isPortal; bool
// isTransport; uint32 maxLevelMob; uint32 maxLevelAlliance; uint32 maxLevelHorde; float
// swimDistance; };
out << std::fixed << std::setprecision(2) << " linkNodes3.push_back(linkNode3{" << i << "," << saveNodes.find(Link.first)->second << ","; out << std::fixed << std::setprecision(2) << " linkNodes3.push_back(linkNode3{" << i << ","
<< saveNodes.find(Link.first)->second << ",";
out << Link.second->print() << "});"; out << Link.second->print() << "});";
//out << std::fixed << std::setprecision(1) << " nodes[" << i << "]->setPathTo(nodes[" << saveNodes.find(Link.first)->second << "],TravelNodePath("; // out << std::fixed << std::setprecision(1) << " nodes[" << i << "]->setPathTo(nodes[" <<
//out << Link.second->print() << "), true);"; // saveNodes.find(Link.first)->second << "],TravelNodePath("; out << Link.second->print() << "), true);";
sPlayerbotAIConfig->log(nodeStore, out.str().c_str()); sPlayerbotAIConfig->log(nodeStore, out.str().c_str());
} }
} }
@ -2291,7 +2351,8 @@ void TravelNodeMap::saveNodeStore()
{ {
TravelNodePath* path = link.second; TravelNodePath* path = link.second;
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_INS_TRAVELNODE_LINK); PlayerbotsDatabasePreparedStatement* stmt =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_INS_TRAVELNODE_LINK);
stmt->SetData(0, i); stmt->SetData(0, i);
stmt->SetData(1, saveNodes.find(link.first)->second); stmt->SetData(1, saveNodes.find(link.first)->second);
stmt->SetData(2, static_cast<uint8>(path->getPathType())); stmt->SetData(2, static_cast<uint8>(path->getPathType()));
@ -2313,7 +2374,8 @@ void TravelNodeMap::saveNodeStore()
{ {
WorldPosition point = ppath[j]; WorldPosition point = ppath[j];
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_INS_TRAVELNODE_PATH); PlayerbotsDatabasePreparedStatement* stmt =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_INS_TRAVELNODE_PATH);
stmt->SetData(0, i); stmt->SetData(0, i);
stmt->SetData(1, saveNodes.find(link.first)->second); stmt->SetData(1, saveNodes.find(link.first)->second);
stmt->SetData(2, j); stmt->SetData(2, j);
@ -2341,13 +2403,16 @@ void TravelNodeMap::loadNodeStore()
std::unordered_map<uint32, TravelNode*> saveNodes; std::unordered_map<uint32, TravelNode*> saveNodes;
{ {
if (PreparedQueryResult result = PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TRAVELNODE))) if (PreparedQueryResult result =
PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TRAVELNODE)))
{ {
do do
{ {
Field* fields = result->Fetch(); Field* fields = result->Fetch();
TravelNode* node = addNode(WorldPosition(fields[2].Get<uint32>(), fields[3].Get<float>(), fields[4].Get<float>(), fields[5].Get<float>()), fields[1].Get<std::string>(), true); TravelNode* node = addNode(WorldPosition(fields[2].Get<uint32>(), fields[3].Get<float>(),
fields[4].Get<float>(), fields[5].Get<float>()),
fields[1].Get<std::string>(), true);
if (fields[6].Get<bool>()) if (fields[6].Get<bool>())
node->setLinked(true); node->setLinked(true);
@ -2368,7 +2433,8 @@ void TravelNodeMap::loadNodeStore()
} }
{ {
if (PreparedQueryResult result = PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TRAVELNODE_LINK))) if (PreparedQueryResult result =
PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TRAVELNODE_LINK)))
{ {
do do
{ {
@ -2380,7 +2446,13 @@ void TravelNodeMap::loadNodeStore()
if (!startNode || !endNode) if (!startNode || !endNode)
continue; continue;
startNode->setPathTo(endNode, TravelNodePath(fields[4].Get<float>(), fields[6].Get<float>(), fields[2].Get<uint8>(), fields[3].Get<uint64>(), fields[7].Get<bool>(), { fields[8].Get<uint8>(),fields[9].Get<uint8>(),fields[10].Get<uint8>() }, fields[5].Get<float>()), true); startNode->setPathTo(
endNode,
TravelNodePath(fields[4].Get<float>(), fields[6].Get<float>(), fields[2].Get<uint8>(),
fields[3].Get<uint64>(), fields[7].Get<bool>(),
{fields[8].Get<uint8>(), fields[9].Get<uint8>(), fields[10].Get<uint8>()},
fields[5].Get<float>()),
true);
if (!fields[7].Get<bool>()) if (!fields[7].Get<bool>())
hasToGen = true; hasToGen = true;
@ -2396,7 +2468,8 @@ void TravelNodeMap::loadNodeStore()
} }
{ {
if (PreparedQueryResult result = PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TRAVELNODE_PATH))) if (PreparedQueryResult result =
PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TRAVELNODE_PATH)))
{ {
do do
{ {
@ -2411,7 +2484,8 @@ void TravelNodeMap::loadNodeStore()
TravelNodePath* path = startNode->getPathTo(endNode); TravelNodePath* path = startNode->getPathTo(endNode);
std::vector<WorldPosition> ppath = path->getPath(); std::vector<WorldPosition> ppath = path->getPath();
ppath.push_back(WorldPosition(fields[3].Get<uint32>(), fields[4].Get<float>(), fields[5].Get<float>(), fields[6].Get<float>())); ppath.push_back(WorldPosition(fields[3].Get<uint32>(), fields[4].Get<float>(), fields[5].Get<float>(),
fields[6].Get<float>()));
path->setPath(ppath); path->setPath(ppath);
@ -2481,7 +2555,8 @@ void TravelNodeMap::calcMapOffset()
//+X -> -Y //+X -> -Y
for (auto& mapId : mapIds) for (auto& mapId : mapIds)
{ {
mapOffsets.push_back(std::make_pair(mapId, WorldPosition(mapId, curPos.getX() - min[i].getX(), curPos.getY() - max[i].getY(),0, 0))); mapOffsets.push_back(std::make_pair(
mapId, WorldPosition(mapId, curPos.getX() - min[i].getX(), curPos.getY() - max[i].getY(), 0, 0)));
maxY = std::max(maxY, (max[i].getY() - min[i].getY() + 500)); maxY = std::max(maxY, (max[i].getY() - min[i].getY() + 500));
curPos.setX(curPos.getX() + (max[i].getX() - min[i].getX() + 500)); curPos.setX(curPos.getX() + (max[i].getX() - min[i].getX() + 500));

View File

@ -1,45 +1,51 @@
/* /*
* 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. * 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_TRAVELNODE_H #ifndef _PLAYERBOT_TRAVELNODE_H
#define _PLAYERBOT_TRAVELNODE_H #define _PLAYERBOT_TRAVELNODE_H
#include "TravelMgr.h"
#include <shared_mutex> #include <shared_mutex>
#include "TravelMgr.h"
// THEORY // THEORY
// //
// Pathfinding in (c)mangos is based on detour recast an opensource nashmesh creation and pathfinding codebase. // Pathfinding in (c)mangos is based on detour recast an opensource nashmesh creation and pathfinding codebase.
// This system is used for mob and npc pathfinding and in this codebase also for bots. // This system is used for mob and npc pathfinding and in this codebase also for bots.
// Because mobs and npc movement is based on following a player or a set path the PathGenerator is limited to 296y. // Because mobs and npc movement is based on following a player or a set path the PathGenerator is limited to 296y.
// This means that when trying to find a path from A to B distances beyond 296y will be a best guess often moving in a straight path. // This means that when trying to find a path from A to B distances beyond 296y will be a best guess often moving in a
// Bots would get stuck moving from Northshire to Stormwind because there is no 296y path that doesn't go (initially) the wrong direction. // straight path. Bots would get stuck moving from Northshire to Stormwind because there is no 296y path that doesn't
// go (initially) the wrong direction.
// //
// To remedy this limitation without altering the PathGenerator limits too much this node system was introduced. // To remedy this limitation without altering the PathGenerator limits too much this node system was introduced.
// //
// <S> ---> [N1] ---> [N2] ---> [N3] ---> <E> // <S> ---> [N1] ---> [N2] ---> [N3] ---> <E>
// //
// Bot at <S> wants to move to <E> // Bot at <S> wants to move to <E>
// [N1],[N2],[N3] are predefined nodes for wich we know we can move from [N1] to [N2] and from [N2] to [N3] but not from [N1] to [N3] // [N1],[N2],[N3] are predefined nodes for wich we know we can move from [N1] to [N2] and from [N2] to [N3] but not
// If we can move fom [S] to [N1] and from [N3] to [E] we have a complete route to travel. // from [N1] to [N3] If we can move fom [S] to [N1] and from [N3] to [E] we have a complete route to travel.
// //
// Termonology: // Termonology:
// Node: a location on a map for which we know bots are likely to want to travel to or need to travel past to reach other nodes. // Node: a location on a map for which we know bots are likely to want to travel to or need to travel past to reach
// Link: the connection between two nodes. A link signifies that the bot can travel from one node to another. A link is one-directional. // other nodes. Link: the connection between two nodes. A link signifies that the bot can travel from one node to
// Path: the waypointpath returned by the standard PathGenerator to move from one node (or position) to another. A path can be imcomplete or empty which means there is no link. // another. A link is one-directional. Path: the waypointpath returned by the standard PathGenerator to move from one
// Route: the list of nodes that give the shortest route from a node to a distant node. Routes are calculated using a standard A* search based on links. // node (or position) to another. A path can be imcomplete or empty which means there is no link. Route: the list of
// nodes that give the shortest route from a node to a distant node. Routes are calculated using a standard A* search
// based on links.
// //
// On server start saved nodes and links are loaded. Paths and routes are calculated on the fly but saved for future use. // On server start saved nodes and links are loaded. Paths and routes are calculated on the fly but saved for future
// Nodes can be added and removed realtime however because bots access the nodes from different threads this requires a locking mechanism. // use. Nodes can be added and removed realtime however because bots access the nodes from different threads this
// requires a locking mechanism.
// //
// Initially the current nodes have been made: // Initially the current nodes have been made:
// Flightmasters and Inns (Bots can use these to fast-travel so eventually they will be included in the route calculation) // Flightmasters and Inns (Bots can use these to fast-travel so eventually they will be included in the route
// WorldBosses and Unique bosses in instances (These are a logical places bots might want to go in instances) // calculation) WorldBosses and Unique bosses in instances (These are a logical places bots might want to go in
// Player start spawns (Obviously all lvl1 bots will spawn and move from here) // instances) Player start spawns (Obviously all lvl1 bots will spawn and move from here) Area triggers locations with
// Area triggers locations with teleport and their teleport destinations (These used to travel in or between maps) // teleport and their teleport destinations (These used to travel in or between maps) Transports including elevators
// Transports including elevators (Again used to travel in and in maps) // (Again used to travel in and in maps) (sub)Zone means (These are the center most point for each sub-zone which is
// (sub)Zone means (These are the center most point for each sub-zone which is good for global coverage) // good for global coverage)
// //
// To increase coverage/linking extra nodes can be automatically be created. // To increase coverage/linking extra nodes can be automatically be created.
// Current implentation places nodes on paths (including complete) at sub-zone transitions or randomly. // Current implentation places nodes on paths (including complete) at sub-zone transitions or randomly.
@ -61,12 +67,21 @@ class TravelNodePath
{ {
public: public:
// Legacy Constructor for travelnodestore // Legacy Constructor for travelnodestore
//TravelNodePath(float distance1, float extraCost1, bool portal1 = false, uint32 portalId1 = 0, bool transport1 = false, bool calculated = false, uint8 maxLevelMob1 = 0, uint8 maxLevelAlliance1 = 0, uint8 maxLevelHorde1 = 0, float swimDistance1 = 0, bool flightPath1 = false); // TravelNodePath(float distance1, float extraCost1, bool portal1 = false, uint32 portalId1 = 0, bool transport1 =
// false, bool calculated = false, uint8 maxLevelMob1 = 0, uint8 maxLevelAlliance1 = 0, uint8 maxLevelHorde1 = 0,
// float swimDistance1 = 0, bool flightPath1 = false);
// Constructor // Constructor
TravelNodePath(float distance = 0.1f, float extraCost = 0, uint8 pathType = (uint8)TravelNodePathType::walk, uint32 pathObject = 0, bool calculated = false, TravelNodePath(float distance = 0.1f, float extraCost = 0, uint8 pathType = (uint8)TravelNodePathType::walk,
std::vector<uint8> maxLevelCreature = { 0, 0, 0 }, float swimDistance = 0) uint32 pathObject = 0, bool calculated = false, std::vector<uint8> maxLevelCreature = {0, 0, 0},
: extraCost(extraCost), calculated(calculated), distance(distance), maxLevelCreature(maxLevelCreature), swimDistance(swimDistance), pathType(TravelNodePathType(pathType)), pathObject(pathObject) // reorder args - whipowill float swimDistance = 0)
: extraCost(extraCost),
calculated(calculated),
distance(distance),
maxLevelCreature(maxLevelCreature),
swimDistance(swimDistance),
pathType(TravelNodePathType(pathType)),
pathObject(pathObject) // reorder args - whipowill
{ {
if (pathType != (uint8)TravelNodePathType::walk) if (pathType != (uint8)TravelNodePathType::walk)
complete = true; complete = true;
@ -104,15 +119,9 @@ class TravelNodePath
std::string const print(); std::string const print();
// Setters // Setters
void setComplete(bool complete1) void setComplete(bool complete1) { complete = complete1; }
{
complete = complete1;
}
void setPath(std::vector<WorldPosition> path1) void setPath(std::vector<WorldPosition> path1) { path = path1; }
{
path = path1;
}
void setPathAndCost(std::vector<WorldPosition> path1, float speed) void setPathAndCost(std::vector<WorldPosition> path1, float speed)
{ {
@ -124,15 +133,9 @@ class TravelNodePath
// void setPortal(bool portal1, uint32 portalId1 = 0) { portal = portal1; portalId = portalId1; } // void setPortal(bool portal1, uint32 portalId1 = 0) { portal = portal1; portalId = portalId1; }
// void setTransport(bool transport1) { transport = transport1; } // void setTransport(bool transport1) { transport = transport1; }
void setPathType(TravelNodePathType pathType1) void setPathType(TravelNodePathType pathType1) { pathType = pathType1; }
{
pathType = pathType1;
}
void setPathObject(uint32 pathObject1) void setPathObject(uint32 pathObject1) { pathObject = pathObject1; }
{
pathObject = pathObject1;
}
void calculateCost(bool distanceOnly = false); void calculateCost(bool distanceOnly = false);
@ -388,9 +391,21 @@ class TravelPath
} }
void addPoint(PathNodePoint point) { fullPath.push_back(point); } void addPoint(PathNodePoint point) { fullPath.push_back(point); }
void addPoint(WorldPosition point, PathNodeType type = NODE_PATH, uint32 entry = 0) { fullPath.push_back(PathNodePoint{ point, type, entry }); } void addPoint(WorldPosition point, PathNodeType type = NODE_PATH, uint32 entry = 0)
void addPath(std::vector<WorldPosition> path, PathNodeType type = NODE_PATH, uint32 entry = 0) { for (auto& p : path) { fullPath.push_back(PathNodePoint{ p, type, entry }); }; } {
void addPath(std::vector<PathNodePoint> newPath) { fullPath.insert(fullPath.end(), newPath.begin(), newPath.end()); } fullPath.push_back(PathNodePoint{point, type, entry});
}
void addPath(std::vector<WorldPosition> path, PathNodeType type = NODE_PATH, uint32 entry = 0)
{
for (auto& p : path)
{
fullPath.push_back(PathNodePoint{p, type, entry});
};
}
void addPath(std::vector<PathNodePoint> newPath)
{
fullPath.insert(fullPath.end(), newPath.begin(), newPath.end());
}
void clear() { fullPath.clear(); } void clear() { fullPath.clear(); }
bool empty() { return fullPath.empty(); } bool empty() { return fullPath.empty(); }
@ -407,7 +422,9 @@ class TravelPath
}; };
bool makeShortCut(WorldPosition startPos, float maxDist); bool makeShortCut(WorldPosition startPos, float maxDist);
bool shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathNodePoint>::iterator beg, std::vector<PathNodePoint>::iterator ed, std::vector<PathNodePoint>::iterator p, float& moveDist, float maxDist); bool shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathNodePoint>::iterator beg,
std::vector<PathNodePoint>::iterator ed, std::vector<PathNodePoint>::iterator p,
float& moveDist, float maxDist);
WorldPosition getNextPoint(WorldPosition startPos, float maxDist, TravelNodePathType& pathType, uint32& entry); WorldPosition getNextPoint(WorldPosition startPos, float maxDist, TravelNodePathType& pathType, uint32& entry);
std::ostringstream const print(); std::ostringstream const print();
@ -430,12 +447,16 @@ class TravelNodeRoute
std::vector<TravelNode*> getNodes() { return nodes; } std::vector<TravelNode*> getNodes() { return nodes; }
TravelPath buildPath(std::vector<WorldPosition> pathToStart = {}, std::vector<WorldPosition> pathToEnd = {}, Unit* bot = nullptr); TravelPath buildPath(std::vector<WorldPosition> pathToStart = {}, std::vector<WorldPosition> pathToEnd = {},
Unit* bot = nullptr);
std::ostringstream const print(); std::ostringstream const print();
private: private:
std::vector<TravelNode*>::iterator findNode(TravelNode* node) { return std::find(nodes.begin(), nodes.end(), node); } std::vector<TravelNode*>::iterator findNode(TravelNode* node)
{
return std::find(nodes.begin(), nodes.end(), node);
}
std::vector<TravelNode*> nodes; std::vector<TravelNode*> nodes;
}; };
@ -465,7 +486,8 @@ class TravelNodeMap
return &instance; return &instance;
} }
TravelNode* addNode(WorldPosition pos, std::string const preferedName = "Travel Node", bool isImportant = false, bool checkDuplicate = true, bool transport = false, uint32 transportId = 0); TravelNode* addNode(WorldPosition pos, std::string const preferedName = "Travel Node", bool isImportant = false,
bool checkDuplicate = true, bool transport = false, uint32 transportId = 0);
void removeNode(TravelNode* node); void removeNode(TravelNode* node);
bool removeNodes() bool removeNodes()
{ {
@ -520,7 +542,8 @@ class TravelNodeMap
TravelNodeRoute getRoute(TravelNode* start, TravelNode* goal, Player* bot = nullptr); TravelNodeRoute getRoute(TravelNode* start, TravelNode* goal, Player* bot = nullptr);
// Find the best node between two positions // Find the best node between two positions
TravelNodeRoute getRoute(WorldPosition startPos, WorldPosition endPos, std::vector<WorldPosition>& startPath, Player* bot = nullptr); TravelNodeRoute getRoute(WorldPosition startPos, WorldPosition endPos, std::vector<WorldPosition>& startPath,
Player* bot = nullptr);
// Find the full path between those locations // Find the full path between those locations
static TravelPath getFullPath(WorldPosition startPos, WorldPosition endPos, Player* bot = nullptr); static TravelPath getFullPath(WorldPosition startPos, WorldPosition endPos, Player* bot = nullptr);

View File

@ -13,13 +13,13 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "BattleGroundTactics.h"
#include "Chat.h" #include "Chat.h"
#include "GuildTaskMgr.h" #include "GuildTaskMgr.h"
#include "PerformanceMonitor.h" #include "PerformanceMonitor.h"
#include "PlayerbotMgr.h" #include "PlayerbotMgr.h"
#include "RandomPlayerbotMgr.h" #include "RandomPlayerbotMgr.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "BattleGroundTactics.h"
using namespace Acore::ChatCommands; using namespace Acore::ChatCommands;
@ -30,12 +30,10 @@ public:
ChatCommandTable GetCommands() const override ChatCommandTable GetCommands() const override
{ {
static ChatCommandTable playerbotsDebugCommandTable = static ChatCommandTable playerbotsDebugCommandTable = {
{
{"bg", HandleDebugBGCommand, SEC_GAMEMASTER, Console::Yes}, {"bg", HandleDebugBGCommand, SEC_GAMEMASTER, Console::Yes},
}; };
static ChatCommandTable playerbotsCommandTable = static ChatCommandTable playerbotsCommandTable = {
{
{"bot", HandlePlayerbotCommand, SEC_PLAYER, Console::No}, {"bot", HandlePlayerbotCommand, SEC_PLAYER, Console::No},
{"gtask", HandleGuildTaskCommand, SEC_GAMEMASTER, Console::Yes}, {"gtask", HandleGuildTaskCommand, SEC_GAMEMASTER, Console::Yes},
{"pmon", HandlePerfMonCommand, SEC_GAMEMASTER, Console::Yes}, {"pmon", HandlePerfMonCommand, SEC_GAMEMASTER, Console::Yes},
@ -43,8 +41,7 @@ public:
{"debug", playerbotsDebugCommandTable}, {"debug", playerbotsDebugCommandTable},
}; };
static ChatCommandTable commandTable = static ChatCommandTable commandTable = {
{
{"playerbots", playerbotsCommandTable}, {"playerbots", playerbotsCommandTable},
}; };
@ -96,7 +93,4 @@ public:
} }
}; };
void AddSC_playerbots_commandscript() void AddSC_playerbots_commandscript() { new playerbots_commandscript(); }
{
new playerbots_commandscript();
}

View File

@ -19,7 +19,4 @@
void AddPlayerbotsScripts(); void AddPlayerbotsScripts();
// Add all // Add all
void Addmod_playerbotsScripts() void Addmod_playerbotsScripts() { AddPlayerbotsScripts(); }
{
AddPlayerbotsScripts();
}

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "Action.h" #include "Action.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Timer.h" #include "Timer.h"
@ -66,8 +68,7 @@ NextAction** NextAction::array(uint32 nil, ...)
{ {
cur = va_arg(vl, NextAction*); cur = va_arg(vl, NextAction*);
++size; ++size;
} } while (cur);
while (cur);
va_end(vl); va_end(vl);
@ -91,22 +92,13 @@ void NextAction::destroy(NextAction** actions)
delete[] actions; delete[] actions;
} }
Value<Unit*>* Action::GetTargetValue() Value<Unit*>* Action::GetTargetValue() { return context->GetValue<Unit*>(GetTargetName()); }
{
return context->GetValue<Unit*>(GetTargetName());
}
Unit* Action::GetTarget() Unit* Action::GetTarget() { return GetTargetValue()->Get(); }
{
return GetTargetValue()->Get();
}
ActionBasket::ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, Event event) : ActionBasket::ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, Event event)
action(action), relevance(relevance), skipPrerequisites(skipPrerequisites), event(event), created(getMSTime()) : action(action), relevance(relevance), skipPrerequisites(skipPrerequisites), event(event), created(getMSTime())
{ {
} }
bool ActionBasket::isExpired(uint32 msecs) bool ActionBasket::isExpired(uint32 msecs) { return getMSTime() - created >= msecs; }
{
return getMSTime() - created >= msecs;
}

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_ACTION_H #ifndef _PLAYERBOT_ACTION_H
@ -16,7 +17,8 @@ class Unit;
class NextAction class NextAction
{ {
public: public:
NextAction(std::string const name, float relevance = 0.0f) : relevance(relevance), name(name) { } // name after relevance - whipowill NextAction(std::string const name, float relevance = 0.0f)
: relevance(relevance), name(name) {} // name after relevance - whipowill
NextAction(NextAction const& o) : relevance(o.relevance), name(o.name) {} // name after relevance - whipowill NextAction(NextAction const& o) : relevance(o.relevance), name(o.name) {} // name after relevance - whipowill
std::string const getName() { return name; } std::string const getName() { return name; }
@ -43,7 +45,8 @@ class Action : public AiNamedObject
Aoe = 2 Aoe = 2
}; };
Action(PlayerbotAI* botAI, std::string const name = "action") : AiNamedObject(botAI, name), verbose(false) { } // verbose after ainamedobject - whipowill Action(PlayerbotAI* botAI, std::string const name = "action")
: AiNamedObject(botAI, name), verbose(false) {} // verbose after ainamedobject - whipowill
virtual ~Action(void) {} virtual ~Action(void) {}
virtual bool Execute([[maybe_unused]] Event event) { return true; } virtual bool Execute([[maybe_unused]] Event event) { return true; }
@ -70,8 +73,11 @@ class Action : public AiNamedObject
class ActionNode class ActionNode
{ {
public: public:
ActionNode(std::string const name, NextAction** prerequisites = nullptr, NextAction** alternatives = nullptr, NextAction** continuers = nullptr) : ActionNode(std::string const name, NextAction** prerequisites = nullptr, NextAction** alternatives = nullptr,
name(name), action(nullptr), continuers(continuers), alternatives(alternatives), prerequisites(prerequisites) { } // reorder arguments - whipowill NextAction** continuers = nullptr)
: name(name), action(nullptr), continuers(continuers), alternatives(alternatives), prerequisites(prerequisites)
{
} // reorder arguments - whipowill
virtual ~ActionNode() virtual ~ActionNode()
{ {
@ -85,8 +91,14 @@ class ActionNode
std::string const getName() { return name; } std::string const getName() { return name; }
NextAction** getContinuers() { return NextAction::merge(NextAction::clone(continuers), action->getContinuers()); } NextAction** getContinuers() { return NextAction::merge(NextAction::clone(continuers), action->getContinuers()); }
NextAction** getAlternatives() { return NextAction::merge(NextAction::clone(alternatives), action->getAlternatives()); } NextAction** getAlternatives()
NextAction** getPrerequisites() { return NextAction::merge(NextAction::clone(prerequisites), action->getPrerequisites()); } {
return NextAction::merge(NextAction::clone(alternatives), action->getAlternatives());
}
NextAction** getPrerequisites()
{
return NextAction::merge(NextAction::clone(prerequisites), action->getPrerequisites());
}
private: private:
std::string const name; std::string const name;

View File

@ -1,15 +1,15 @@
/* /*
* 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. * 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 "AiObject.h" #include "AiObject.h"
#include "Playerbots.h" #include "Playerbots.h"
AiObject::AiObject(PlayerbotAI* botAI) : PlayerbotAIAware(botAI), bot(botAI->GetBot()), context(botAI->GetAiObjectContext()), chat(botAI->GetChatHelper()) AiObject::AiObject(PlayerbotAI* botAI)
: PlayerbotAIAware(botAI), bot(botAI->GetBot()), context(botAI->GetAiObjectContext()), chat(botAI->GetChatHelper())
{ {
} }
Player* AiObject::GetMaster() Player* AiObject::GetMaster() { return botAI->GetMaster(); }
{
return botAI->GetMaster();
}

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_AIOBJECT_H #ifndef _PLAYERBOT_AIOBJECT_H
@ -49,10 +50,11 @@ class clazz : public super \
{ \ { \
public: \ public: \
clazz(PlayerbotAI* botAI) : super(botAI) {} \ clazz(PlayerbotAI* botAI) : super(botAI) {} \
bool IsActive() override; \ bool IsActive() override;
#define END_TRIGGER() \ #define END_TRIGGER() \
}; } \
;
#define BUFF_TRIGGER(clazz, spell) \ #define BUFF_TRIGGER(clazz, spell) \
class clazz : public BuffTrigger \ class clazz : public BuffTrigger \
@ -385,10 +387,7 @@ class clazz : public CastDebuffSpellAction \
class clazz : public CastDebuffSpellAction \ class clazz : public CastDebuffSpellAction \
{ \ { \
public: \ public: \
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) \ clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) { range = distance; } \
{ \
range = distance; \
} \
} }
#define DEBUFF_ENEMY_ACTION(clazz, spell) \ #define DEBUFF_ENEMY_ACTION(clazz, spell) \
@ -420,7 +419,6 @@ class clazz : public CastSpellOnEnemyHealerAction \
clazz(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, spell) {} \ clazz(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, spell) {} \
} }
#define SNARE_ACTION(clazz, spell) \ #define SNARE_ACTION(clazz, spell) \
class clazz : public CastSnareSpellAction \ class clazz : public CastSnareSpellAction \
{ \ { \
@ -443,37 +441,40 @@ class clazz : public CastProtectSpellAction \
} }
#define END_RANGED_SPELL_ACTION() \ #define END_RANGED_SPELL_ACTION() \
}; } \
;
#define BEGIN_SPELL_ACTION(clazz, name) \ #define BEGIN_SPELL_ACTION(clazz, name) \
class clazz : public CastSpellAction \ class clazz : public CastSpellAction \
{ \ { \
public: \ public: \
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, name) { } \ clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, name) {}
#define END_SPELL_ACTION() \ #define END_SPELL_ACTION() \
}; } \
;
#define BEGIN_DEBUFF_ACTION(clazz, name) \ #define BEGIN_DEBUFF_ACTION(clazz, name) \
class clazz : public CastDebuffSpellAction \ class clazz : public CastDebuffSpellAction \
{ \ { \
public: \ public: \
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, name) { } \ clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, name) {}
#define BEGIN_RANGED_SPELL_ACTION(clazz, name) \ #define BEGIN_RANGED_SPELL_ACTION(clazz, name) \
class clazz : public CastSpellAction \ class clazz : public CastSpellAction \
{ \ { \
public: \ public: \
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, name) { } \ clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, name) {}
#define BEGIN_MELEE_SPELL_ACTION(clazz, name) \ #define BEGIN_MELEE_SPELL_ACTION(clazz, name) \
class clazz : public CastMeleeSpellAction \ class clazz : public CastMeleeSpellAction \
{ \ { \
public: \ public: \
clazz(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, name) { } \ clazz(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, name) {}
#define END_RANGED_SPELL_ACTION() \ #define END_RANGED_SPELL_ACTION() \
}; } \
;
#define BEGIN_BUFF_ON_PARTY_ACTION(clazz, name) \ #define BEGIN_BUFF_ON_PARTY_ACTION(clazz, name) \
class clazz : public BuffOnPartyAction \ class clazz : public BuffOnPartyAction \
@ -489,9 +490,7 @@ class clazz : public BuffOnPartyAction \
#define ACTION_NODE_P(name, spell, pre) \ #define ACTION_NODE_P(name, spell, pre) \
static ActionNode* name(PlayerbotAI* botAI) \ static ActionNode* name(PlayerbotAI* botAI) \
{ \ { \
return new ActionNode(spell, \ return new ActionNode(spell, /*P*/ NextAction::array(0, new NextAction(pre), nullptr), /*A*/ nullptr, \
/*P*/ NextAction::array(0, new NextAction(pre), nullptr), \
/*A*/ nullptr, \
/*C*/ nullptr); \ /*C*/ nullptr); \
} }
@ -499,9 +498,7 @@ static ActionNode* name(PlayerbotAI* botAI) \
#define ACTION_NODE_A(name, spell, alt) \ #define ACTION_NODE_A(name, spell, alt) \
static ActionNode* name(PlayerbotAI* botAI) \ static ActionNode* name(PlayerbotAI* botAI) \
{ \ { \
return new ActionNode(spell, \ return new ActionNode(spell, /*P*/ nullptr, /*A*/ NextAction::array(0, new NextAction(alt), nullptr), \
/*P*/ nullptr, \
/*A*/ NextAction::array(0, new NextAction(alt), nullptr), \
/*C*/ nullptr); \ /*C*/ nullptr); \
} }
@ -509,9 +506,7 @@ static ActionNode* name(PlayerbotAI* botAI) \
#define ACTION_NODE_C(name, spell, con) \ #define ACTION_NODE_C(name, spell, con) \
static ActionNode* name(PlayerbotAI* botAI) \ static ActionNode* name(PlayerbotAI* botAI) \
{ \ { \
return new ActionNode(spell, \ return new ActionNode(spell, /*P*/ nullptr, /*A*/ nullptr, \
/*P*/ nullptr, \
/*A*/ nullptr, \
/*C*/ NextAction::array(0, new NextAction(con), nullptr)); \ /*C*/ NextAction::array(0, new NextAction(con), nullptr)); \
} }

View File

@ -1,21 +1,23 @@
/* /*
* 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. * 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 "AiObjectContext.h" #include "AiObjectContext.h"
#include "StrategyContext.h"
#include "ActionContext.h" #include "ActionContext.h"
#include "ChatActionContext.h" #include "ChatActionContext.h"
#include "WorldPacketActionContext.h"
#include "ChatTriggerContext.h" #include "ChatTriggerContext.h"
#include "TriggerContext.h"
#include "SharedValueContext.h"
#include "WorldPacketTriggerContext.h"
#include "ValueContext.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "raids/RaidTriggerContext.h" #include "SharedValueContext.h"
#include "StrategyContext.h"
#include "TriggerContext.h"
#include "ValueContext.h"
#include "WorldPacketActionContext.h"
#include "WorldPacketTriggerContext.h"
#include "raids/RaidActionContext.h" #include "raids/RaidActionContext.h"
#include "raids/RaidStrategyContext.h" #include "raids/RaidStrategyContext.h"
#include "raids/RaidTriggerContext.h"
#include "raids/naxxramas/RaidNaxxActionContext.h" #include "raids/naxxramas/RaidNaxxActionContext.h"
#include "raids/naxxramas/RaidNaxxTriggerContext.h" #include "raids/naxxramas/RaidNaxxTriggerContext.h"
@ -116,35 +118,20 @@ std::set<std::string> AiObjectContext::GetSiblingStrategy(std::string const name
return strategyContexts.GetSiblings(name); return strategyContexts.GetSiblings(name);
} }
Trigger* AiObjectContext::GetTrigger(std::string const name) Trigger* AiObjectContext::GetTrigger(std::string const name) { return triggerContexts.GetContextObject(name, botAI); }
{
return triggerContexts.GetContextObject(name, botAI);
}
Action* AiObjectContext::GetAction(std::string const name) Action* AiObjectContext::GetAction(std::string const name) { return actionContexts.GetContextObject(name, botAI); }
{
return actionContexts.GetContextObject(name, botAI);
}
UntypedValue* AiObjectContext::GetUntypedValue(std::string const name) UntypedValue* AiObjectContext::GetUntypedValue(std::string const name)
{ {
return valueContexts.GetContextObject(name, botAI); return valueContexts.GetContextObject(name, botAI);
} }
std::set<std::string> AiObjectContext::GetValues() std::set<std::string> AiObjectContext::GetValues() { return valueContexts.GetCreated(); }
{
return valueContexts.GetCreated();
}
std::set<std::string> AiObjectContext::GetSupportedStrategies() std::set<std::string> AiObjectContext::GetSupportedStrategies() { return strategyContexts.supports(); }
{
return strategyContexts.supports();
}
std::set<std::string> AiObjectContext::GetSupportedActions() std::set<std::string> AiObjectContext::GetSupportedActions() { return actionContexts.supports(); }
{
return actionContexts.supports();
}
std::string const AiObjectContext::FormatValues() std::string const AiObjectContext::FormatValues()
{ {
@ -166,7 +153,4 @@ std::string const AiObjectContext::FormatValues()
return out.str(); return out.str();
} }
void AiObjectContext::AddShared(NamedObjectContext<UntypedValue>* sharedValues) void AiObjectContext::AddShared(NamedObjectContext<UntypedValue>* sharedValues) { valueContexts.Add(sharedValues); }
{
valueContexts.Add(sharedValues);
}

View File

@ -1,10 +1,14 @@
/* /*
* 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. * 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_AIOBJECTCONTEXT_H #ifndef _PLAYERBOT_AIOBJECTCONTEXT_H
#define _PLAYERBOT_AIOBJECTCONTEXT_H #define _PLAYERBOT_AIOBJECTCONTEXT_H
#include <sstream>
#include <string>
#include "Common.h" #include "Common.h"
#include "NamedObjectContext.h" #include "NamedObjectContext.h"
#include "PlayerbotAIAware.h" #include "PlayerbotAIAware.h"
@ -12,9 +16,6 @@
#include "Trigger.h" #include "Trigger.h"
#include "Value.h" #include "Value.h"
#include <sstream>
#include <string>
class PlayerbotAI; class PlayerbotAI;
class AiObjectContext : public PlayerbotAIAware class AiObjectContext : public PlayerbotAIAware

View File

@ -1,12 +1,14 @@
/* /*
* 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. * 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 "CustomStrategy.h" #include "CustomStrategy.h"
#include "Playerbots.h"
#include <regex> #include <regex>
#include "Playerbots.h"
std::map<std::string, std::string> CustomStrategy::actionLinesCache; std::map<std::string, std::string> CustomStrategy::actionLinesCache;
NextAction* toNextAction(std::string const action) NextAction* toNextAction(std::string const action)
@ -47,9 +49,7 @@ TriggerNode* toTriggerNode(std::string const actionLine)
return nullptr; return nullptr;
} }
CustomStrategy::CustomStrategy(PlayerbotAI* botAI) : Strategy(botAI), Qualified() CustomStrategy::CustomStrategy(PlayerbotAI* botAI) : Strategy(botAI), Qualified() {}
{
}
void CustomStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) void CustomStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{ {
@ -68,7 +68,8 @@ void CustomStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
for (std::vector<std::string>::iterator i = tokens.begin(); i != tokens.end(); ++i) for (std::vector<std::string>::iterator i = tokens.begin(); i != tokens.end(); ++i)
{ {
std::string const line = *i; std::string const line = *i;
for (std::sregex_iterator j = std::sregex_iterator(line.begin(), line.end(), tpl); j != std::sregex_iterator(); ++j) for (std::sregex_iterator j = std::sregex_iterator(line.begin(), line.end(), tpl);
j != std::sregex_iterator(); ++j)
{ {
std::smatch match = *j; std::smatch match = *j;
std::string const actionLine = match[1].str(); std::string const actionLine = match[1].str();
@ -88,7 +89,8 @@ void CustomStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
void CustomStrategy::LoadActionLines(uint32 owner) void CustomStrategy::LoadActionLines(uint32 owner)
{ {
PlayerbotsDatabasePreparedStatement* stmt = PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_CUSTOM_STRATEGY_BY_OWNER_AND_NAME); PlayerbotsDatabasePreparedStatement* stmt =
PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_CUSTOM_STRATEGY_BY_OWNER_AND_NAME);
stmt->SetData(0, owner); stmt->SetData(0, owner);
stmt->SetData(1, qualifier); stmt->SetData(1, qualifier);
PreparedQueryResult result = PlayerbotsDatabase.Query(stmt); PreparedQueryResult result = PlayerbotsDatabase.Query(stmt);
@ -99,8 +101,7 @@ void CustomStrategy::LoadActionLines(uint32 owner)
Field* fields = result->Fetch(); Field* fields = result->Fetch();
std::string const action = fields[1].Get<std::string>(); std::string const action = fields[1].Get<std::string>();
actionLines.push_back(action); actionLines.push_back(action);
} } while (result->NextRow());
while (result->NextRow());
} }
} }

View File

@ -1,14 +1,15 @@
/* /*
* 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. * 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_CUSTOMSTRATEGY_H #ifndef _PLAYERBOT_CUSTOMSTRATEGY_H
#define _PLAYERBOT_CUSTOMSTRATEGY_H #define _PLAYERBOT_CUSTOMSTRATEGY_H
#include "Strategy.h"
#include <map> #include <map>
#include "Strategy.h"
class PlayerbotAI; class PlayerbotAI;
class CustomStrategy : public Strategy, public Qualified class CustomStrategy : public Strategy, public Qualified

View File

@ -1,13 +1,15 @@
/* /*
* 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. * 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 "Engine.h" #include "Engine.h"
#include "Action.h" #include "Action.h"
#include "Event.h" #include "Event.h"
#include "Queue.h"
#include "PerformanceMonitor.h" #include "PerformanceMonitor.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Queue.h"
#include "Strategy.h" #include "Strategy.h"
Engine::Engine(PlayerbotAI* botAI, AiObjectContext* factory) : PlayerbotAIAware(botAI), aiObjectContext(factory) Engine::Engine(PlayerbotAI* botAI, AiObjectContext* factory) : PlayerbotAIAware(botAI), aiObjectContext(factory)
@ -172,7 +174,8 @@ 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()); // 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())
@ -185,7 +188,8 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
if (!relevance) if (!relevance)
{ {
LogAction("Multiplier %s made action %s useless", multiplier->getName().c_str(), action->getName().c_str()); LogAction("Multiplier %s made action %s useless", multiplier->getName().c_str(),
action->getName().c_str());
break; break;
} }
} }
@ -203,7 +207,8 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
} }
} }
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_ACTION, action->getName(), &aiObjectContext->performanceStack); PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_ACTION, action->getName(),
&aiObjectContext->performanceStack);
actionExecuted = ListenAndExecute(action, event); actionExecuted = ListenAndExecute(action, event);
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
@ -264,8 +269,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
delete actionNode; delete actionNode;
} }
} } while (basket && ++iterations <= iterationsPerTick);
while (basket && ++iterations <= iterationsPerTick);
// if (!basket) // if (!basket)
// { // {
@ -318,7 +322,8 @@ ActionNode* Engine::CreateActionNode(std::string const name)
/*C*/ nullptr); /*C*/ nullptr);
} }
bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event, char const* pushType) bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event,
char const* pushType)
{ {
bool pushed = false; bool pushed = false;
if (actions) if (actions)
@ -432,8 +437,7 @@ void Engine::addStrategies(std::string first, ...)
cur = va_arg(vl, const char*); cur = va_arg(vl, const char*);
if (cur) if (cur)
addStrategy(cur); addStrategy(cur);
} } while (cur);
while (cur);
va_end(vl); va_end(vl);
} }
@ -463,10 +467,7 @@ void Engine::toggleStrategy(std::string const name)
addStrategy(name); addStrategy(name);
} }
bool Engine::HasStrategy(std::string const name) bool Engine::HasStrategy(std::string const name) { return strategies.find(name) != strategies.end(); }
{
return strategies.find(name) != strategies.end();
}
void Engine::ProcessTriggers(bool minimal) void Engine::ProcessTriggers(bool minimal)
{ {
@ -495,7 +496,8 @@ void Engine::ProcessTriggers(bool minimal)
if (minimal && node->getFirstRelevance() < 100) if (minimal && node->getFirstRelevance() < 100)
continue; continue;
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_TRIGGER, trigger->getName(), &aiObjectContext->performanceStack); PerformanceMonitorOperation* pmo =
sPerformanceMonitor->start(PERF_MON_TRIGGER, trigger->getName(), &aiObjectContext->performanceStack);
Event event = trigger->Check(); Event event = trigger->Check();
if (pmo) if (pmo)
pmo->finish(); pmo->finish();

View File

@ -1,18 +1,19 @@
/* /*
* 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. * 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_ENGINE_H #ifndef _PLAYERBOT_ENGINE_H
#define _PLAYERBOT_ENGINE_H #define _PLAYERBOT_ENGINE_H
#include <map>
#include "Multiplier.h" #include "Multiplier.h"
#include "Queue.h"
#include "PlayerbotAIAware.h" #include "PlayerbotAIAware.h"
#include "Queue.h"
#include "Strategy.h" #include "Strategy.h"
#include "Trigger.h" #include "Trigger.h"
#include <map>
class Action; class Action;
class ActionNode; class ActionNode;
class AiObjectContext; class AiObjectContext;
@ -50,15 +51,9 @@ class ActionExecutionListeners : public ActionExecutionListener
void After(Action* action, bool executed, Event event) override; void After(Action* action, bool executed, Event event) override;
bool OverrideResult(Action* action, bool executed, Event event) override; bool OverrideResult(Action* action, bool executed, Event event) override;
void Add(ActionExecutionListener* listener) void Add(ActionExecutionListener* listener) { listeners.push_back(listener); }
{
listeners.push_back(listener);
}
void Remove(ActionExecutionListener* listener) void Remove(ActionExecutionListener* listener) { listeners.remove(listener); }
{
listeners.remove(listener);
}
private: private:
std::list<ActionExecutionListener*> listeners; std::list<ActionExecutionListener*> listeners;
@ -85,22 +80,17 @@ class Engine : public PlayerbotAIAware
virtual bool DoNextAction(Unit*, uint32 depth = 0, bool minimal = false); virtual bool DoNextAction(Unit*, uint32 depth = 0, bool minimal = false);
ActionResult ExecuteAction(std::string const name, Event event = Event(), std::string const qualifier = ""); ActionResult ExecuteAction(std::string const name, Event event = Event(), std::string const qualifier = "");
void AddActionExecutionListener(ActionExecutionListener* listener) void AddActionExecutionListener(ActionExecutionListener* listener) { actionExecutionListeners.Add(listener); }
{
actionExecutionListeners.Add(listener);
}
void removeActionExecutionListener(ActionExecutionListener* listener) void removeActionExecutionListener(ActionExecutionListener* listener) { actionExecutionListeners.Remove(listener); }
{
actionExecutionListeners.Remove(listener);
}
virtual ~Engine(void); virtual ~Engine(void);
bool testMode; bool testMode;
private: private:
bool MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event, const char* pushType); bool MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event,
const char* pushType);
void Reset(); void Reset();
void ProcessTriggers(bool minimal); void ProcessTriggers(bool minimal);
void PushDefaultActions(); void PushDefaultActions();

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "Event.h" #include "Event.h"
#include "Playerbots.h" #include "Playerbots.h"
Event::Event(std::string const source, ObjectGuid object, Player* owner) : source(source), owner(owner) Event::Event(std::string const source, ObjectGuid object, Player* owner) : source(source), owner(owner)

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_EVENT_H #ifndef _PLAYERBOT_EVENT_H
@ -16,8 +17,14 @@ class Event
Event(Event const& other) : source(other.source), param(other.param), packet(other.packet), owner(other.owner) {} Event(Event const& other) : source(other.source), param(other.param), packet(other.packet), owner(other.owner) {}
Event() {} Event() {}
Event(std::string const source) : source(source) {} Event(std::string const source) : source(source) {}
Event(std::string const source, std::string const param, Player* owner = nullptr) : source(source), param(param), owner(owner) { } Event(std::string const source, std::string const param, Player* owner = nullptr)
Event(std::string const source, WorldPacket& packet, Player* owner = nullptr) : source(source), packet(packet), owner(owner) { } : source(source), param(param), owner(owner)
{
}
Event(std::string const source, WorldPacket& packet, Player* owner = nullptr)
: source(source), packet(packet), owner(owner)
{
}
Event(std::string const source, ObjectGuid object, Player* owner = nullptr); Event(std::string const source, ObjectGuid object, Player* owner = nullptr);
virtual ~Event() {} virtual ~Event() {}

View File

@ -1,11 +1,13 @@
/* /*
* 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. * 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 "ExternalEventHelper.h" #include "ExternalEventHelper.h"
#include "Trigger.h"
#include "ChatHelper.h" #include "ChatHelper.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Trigger.h"
bool ExternalEventHelper::ParseChatCommand(std::string const command, Player* owner) bool ExternalEventHelper::ParseChatCommand(std::string const command, Player* owner)
{ {
@ -37,7 +39,8 @@ bool ExternalEventHelper::ParseChatCommand(std::string const command, Player* ow
return true; return true;
} }
void ExternalEventHelper::HandlePacket(std::map<uint16, std::string>& handlers, WorldPacket const& packet, Player* owner) void ExternalEventHelper::HandlePacket(std::map<uint16, std::string>& handlers, WorldPacket const& packet,
Player* owner)
{ {
uint16 opcode = packet.GetOpcode(); uint16 opcode = packet.GetOpcode();
std::string const name = handlers[opcode]; std::string const name = handlers[opcode];

View File

@ -1,14 +1,15 @@
/* /*
* 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. * 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_EXTERNALEVENTHELPER_H #ifndef _PLAYERBOT_EXTERNALEVENTHELPER_H
#define _PLAYERBOT_EXTERNALEVENTHELPER_H #define _PLAYERBOT_EXTERNALEVENTHELPER_H
#include "Common.h"
#include <map> #include <map>
#include "Common.h"
class AiObjectContext; class AiObjectContext;
class Player; class Player;
class WorldPacket; class WorldPacket;

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "ItemVisitors.h" #include "ItemVisitors.h"
#include "Playerbots.h" #include "Playerbots.h"
bool FindUsableItemVisitor::Visit(Item* item) bool FindUsableItemVisitor::Visit(Item* item)
@ -15,7 +17,8 @@ bool FindUsableItemVisitor::Visit(Item* item)
bool FindPotionVisitor::Accept(ItemTemplate const* proto) bool FindPotionVisitor::Accept(ItemTemplate const* proto)
{ {
if (proto->Class == ITEM_CLASS_CONSUMABLE && (proto->SubClass == ITEM_SUBCLASS_POTION || proto->SubClass == ITEM_SUBCLASS_FLASK)) if (proto->Class == ITEM_CLASS_CONSUMABLE &&
(proto->SubClass == ITEM_SUBCLASS_POTION || proto->SubClass == ITEM_SUBCLASS_FLASK))
{ {
for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; j++) for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; j++)
{ {

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_ITEMVISITORS_H #ifndef _PLAYERBOT_ITEMVISITORS_H
@ -82,10 +83,7 @@ class FindItemsByQualityVisitor : public IterateItemsVisitor
return true; return true;
} }
std::vector<Item*>& GetResult() std::vector<Item*>& GetResult() { return result; }
{
return result;
}
private: private:
uint32 quality; uint32 quality;
@ -111,7 +109,9 @@ class FindItemsToTradeByClassVisitor : public IterateItemsVisitor
{ {
public: public:
FindItemsToTradeByClassVisitor(uint32 itemClass, uint32 itemSubClass, uint32 count) FindItemsToTradeByClassVisitor(uint32 itemClass, uint32 itemSubClass, uint32 count)
: IterateItemsVisitor(), itemClass(itemClass), itemSubClass(itemSubClass), count(count) { } // reorder args - whipowill : IterateItemsVisitor(), itemClass(itemClass), itemSubClass(itemSubClass), count(count)
{
} // reorder args - whipowill
bool Visit(Item* item) override bool Visit(Item* item) override
{ {
@ -128,10 +128,7 @@ class FindItemsToTradeByClassVisitor : public IterateItemsVisitor
return true; return true;
} }
std::vector<Item*>& GetResult() std::vector<Item*>& GetResult() { return result; }
{
return result;
}
private: private:
uint32 itemClass; uint32 itemClass;
@ -197,10 +194,7 @@ class FindItemByIdVisitor : public FindItemVisitor
public: public:
FindItemByIdVisitor(uint32 id) : FindItemVisitor(), id(id) {} FindItemByIdVisitor(uint32 id) : FindItemVisitor(), id(id) {}
bool Accept(ItemTemplate const* proto) override bool Accept(ItemTemplate const* proto) override { return proto->ItemId == id; }
{
return proto->ItemId == id;
}
private: private:
uint32 id; uint32 id;
@ -211,10 +205,7 @@ class FindItemByIdsVisitor : public FindItemVisitor
public: public:
FindItemByIdsVisitor(ItemIds ids) : FindItemVisitor(), ids(ids) {} FindItemByIdsVisitor(ItemIds ids) : FindItemVisitor(), ids(ids) {}
bool Accept(ItemTemplate const* proto) override bool Accept(ItemTemplate const* proto) override { return ids.find(proto->ItemId) != ids.end(); }
{
return ids.find(proto->ItemId) != ids.end();
}
private: private:
ItemIds ids; ItemIds ids;
@ -274,12 +265,15 @@ class FindPotionVisitor : public FindUsableItemVisitor
class FindFoodVisitor : public FindUsableItemVisitor class FindFoodVisitor : public FindUsableItemVisitor
{ {
public: public:
FindFoodVisitor(Player* bot, uint32 spellCategory, bool conjured = false) : FindUsableItemVisitor(bot), FindFoodVisitor(Player* bot, uint32 spellCategory, bool conjured = false)
spellCategory(spellCategory), conjured(conjured) { } : FindUsableItemVisitor(bot), spellCategory(spellCategory), conjured(conjured)
{
}
bool Accept(ItemTemplate const* proto) override bool Accept(ItemTemplate const* proto) override
{ {
return proto->Class == ITEM_CLASS_CONSUMABLE && (proto->SubClass == ITEM_SUBCLASS_CONSUMABLE || proto->SubClass == ITEM_SUBCLASS_FOOD) && return proto->Class == ITEM_CLASS_CONSUMABLE &&
(proto->SubClass == ITEM_SUBCLASS_CONSUMABLE || proto->SubClass == ITEM_SUBCLASS_FOOD) &&
proto->Spells[0].SpellCategory == spellCategory && (!conjured || proto->IsConjuredConsumable()); proto->Spells[0].SpellCategory == spellCategory && (!conjured || proto->IsConjuredConsumable());
} }
@ -417,6 +411,7 @@ class FindUsableNamedItemVisitor : public FindUsableItemVisitor
FindUsableNamedItemVisitor(Player* bot, std::string name) : FindUsableItemVisitor(bot), name(name) {} FindUsableNamedItemVisitor(Player* bot, std::string name) : FindUsableItemVisitor(bot), name(name) {}
bool Accept(ItemTemplate const* proto) override; bool Accept(ItemTemplate const* proto) override;
private: private:
std::string name; std::string name;
}; };

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_MULTIPLIER_H #ifndef _PLAYERBOT_MULTIPLIER_H

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "NamedObjectContext.h" #include "NamedObjectContext.h"
#include "Playerbots.h" #include "Playerbots.h"
void Qualified::Qualify(int qual) void Qualified::Qualify(int qual)

View File

@ -1,18 +1,19 @@
/* /*
* 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. * 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_NAMEDOBJECTCONEXT_H #ifndef _PLAYERBOT_NAMEDOBJECTCONEXT_H
#define _PLAYERBOT_NAMEDOBJECTCONEXT_H #define _PLAYERBOT_NAMEDOBJECTCONEXT_H
#include "Common.h"
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <list> #include <list>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector> #include <vector>
#include "Common.h"
class PlayerbotAI; class PlayerbotAI;
class Qualified class Qualified
@ -20,17 +21,11 @@ class Qualified
public: public:
Qualified(){}; Qualified(){};
Qualified(std::string const qualifier) : qualifier(qualifier) {} Qualified(std::string const qualifier) : qualifier(qualifier) {}
Qualified(int32 qualifier1) Qualified(int32 qualifier1) { Qualify(qualifier1); }
{
Qualify(qualifier1);
}
virtual void Qualify(int qual); virtual void Qualify(int qual);
virtual void Qualify(std::string const qual) virtual void Qualify(std::string const qual) { qualifier = qual; }
{
qualifier = qual;
}
std::string const getQualifier() { return qualifier; } std::string const getQualifier() { return qualifier; }
@ -78,7 +73,8 @@ class NamedObjectFactory
std::set<std::string> supports() std::set<std::string> supports()
{ {
std::set<std::string> keys; std::set<std::string> keys;
for (typename std::unordered_map<std::string, ActionCreator>::iterator it = creators.begin(); it != creators.end(); it++) for (typename std::unordered_map<std::string, ActionCreator>::iterator it = creators.begin();
it != creators.end(); it++)
keys.insert(it->first); keys.insert(it->first);
return keys; return keys;
@ -89,14 +85,13 @@ template <class T>
class NamedObjectContext : public NamedObjectFactory<T> class NamedObjectContext : public NamedObjectFactory<T>
{ {
public: public:
NamedObjectContext(bool shared = false, bool supportsSiblings = false) : NamedObjectContext(bool shared = false, bool supportsSiblings = false)
NamedObjectFactory<T>(), shared(shared), supportsSiblings(supportsSiblings) { } : NamedObjectFactory<T>(), shared(shared), supportsSiblings(supportsSiblings)
virtual ~NamedObjectContext()
{ {
Clear();
} }
virtual ~NamedObjectContext() { Clear(); }
T* create(std::string const name, PlayerbotAI* botAI) T* create(std::string const name, PlayerbotAI* botAI)
{ {
if (created.find(name) == created.end()) if (created.find(name) == created.end())
@ -166,10 +161,7 @@ class NamedObjectContextList
} }
} }
void Add(NamedObjectContext<T>* context) void Add(NamedObjectContext<T>* context) { contexts.push_back(context); }
{
contexts.push_back(context);
}
T* GetContextObject(std::string const name, PlayerbotAI* botAI) T* GetContextObject(std::string const name, PlayerbotAI* botAI)
{ {
@ -260,10 +252,7 @@ class NamedObjectFactoryList
delete *i; delete *i;
} }
void Add(NamedObjectFactory<T>* context) void Add(NamedObjectFactory<T>* context) { factories.push_front(context); }
{
factories.push_front(context);
}
T* GetContextObject(std::string const& name, PlayerbotAI* botAI) T* GetContextObject(std::string const& name, PlayerbotAI* botAI)
{ {

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "PassiveMultiplier.h" #include "PassiveMultiplier.h"
#include "Action.h" #include "Action.h"
#include "AiObjectContext.h" #include "AiObjectContext.h"

View File

@ -1,14 +1,15 @@
/* /*
* 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. * 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_PASSIVEMULTIPLIER_H #ifndef _PLAYERBOT_PASSIVEMULTIPLIER_H
#define _PLAYERBOT_PASSIVEMULTIPLIER_H #define _PLAYERBOT_PASSIVEMULTIPLIER_H
#include "Multiplier.h"
#include <vector> #include <vector>
#include "Multiplier.h"
class Action; class Action;
class PlayerbotAI; class PlayerbotAI;

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "Queue.h" #include "Queue.h"
#include "AiObjectContext.h" #include "AiObjectContext.h"
#include "Log.h" #include "Log.h"
#include "PlayerbotAIConfig.h" #include "PlayerbotAIConfig.h"
@ -75,10 +77,7 @@ ActionBasket* Queue::Peek()
return selection; return selection;
} }
uint32 Queue::Size() uint32 Queue::Size() { return actions.size(); }
{
return actions.size();
}
void Queue::RemoveExpired() void Queue::RemoveExpired()
{ {

View File

@ -1,12 +1,13 @@
/* /*
* 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. * 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_QUEUE_H #ifndef _PLAYERBOT_QUEUE_H
#define _PLAYERBOT_QUEUE_H #define _PLAYERBOT_QUEUE_H
#include "Common.h"
#include "Action.h" #include "Action.h"
#include "Common.h"
class Queue class Queue
{ {

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "Strategy.h" #include "Strategy.h"
#include "Playerbots.h" #include "Playerbots.h"
class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode> class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
@ -118,8 +120,4 @@ Strategy::Strategy(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
actionNodeFactories.Add(new ActionNodeFactoryInternal()); actionNodeFactories.Add(new ActionNodeFactoryInternal());
} }
ActionNode* Strategy::GetAction(std::string const name) ActionNode* Strategy::GetAction(std::string const name) { return actionNodeFactories.GetContextObject(name, botAI); }
{
return actionNodeFactories.GetContextObject(name, botAI);
}

View File

@ -1,15 +1,16 @@
/* /*
* 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. * 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_STRATEGY_H #ifndef _PLAYERBOT_STRATEGY_H
#define _PLAYERBOT_STRATEGY_H #define _PLAYERBOT_STRATEGY_H
#include "Action.h" #include "Action.h"
#include "NamedObjectContext.h"
#include "Multiplier.h" #include "Multiplier.h"
#include "Trigger.h" #include "NamedObjectContext.h"
#include "PlayerbotAIAware.h" #include "PlayerbotAIAware.h"
#include "Trigger.h"
enum StrategyType : uint32 enum StrategyType : uint32
{ {

View File

@ -1,17 +1,17 @@
/* /*
* 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. * 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_STRATEGYCONTEXT_H #ifndef _PLAYERBOT_STRATEGYCONTEXT_H
#define _PLAYERBOT_STRATEGYCONTEXT_H #define _PLAYERBOT_STRATEGYCONTEXT_H
#include "CustomStrategy.h"
#include "NamedObjectContext.h"
#include "AttackEnemyPlayersStrategy.h" #include "AttackEnemyPlayersStrategy.h"
#include "BattlegroundStrategy.h" #include "BattlegroundStrategy.h"
#include "CastTimeStrategy.h" #include "CastTimeStrategy.h"
#include "ChatCommandHandlerStrategy.h" #include "ChatCommandHandlerStrategy.h"
#include "ConserveManaStrategy.h" #include "ConserveManaStrategy.h"
#include "CustomStrategy.h"
#include "DeadStrategy.h" #include "DeadStrategy.h"
#include "DebugStrategy.h" #include "DebugStrategy.h"
#include "DpsAssistStrategy.h" #include "DpsAssistStrategy.h"
@ -29,15 +29,16 @@
#include "MaintenanceStrategy.h" #include "MaintenanceStrategy.h"
#include "MarkRtiStrategy.h" #include "MarkRtiStrategy.h"
#include "MeleeCombatStrategy.h" #include "MeleeCombatStrategy.h"
#include "NamedObjectContext.h"
#include "NonCombatStrategy.h" #include "NonCombatStrategy.h"
#include "QuestStrategies.h"
#include "PassiveStrategy.h" #include "PassiveStrategy.h"
#include "PullStrategy.h" #include "PullStrategy.h"
#include "QuestStrategies.h"
#include "RTSCStrategy.h"
#include "RacialsStrategy.h" #include "RacialsStrategy.h"
#include "RangedCombatStrategy.h" #include "RangedCombatStrategy.h"
#include "ReturnStrategy.h" #include "ReturnStrategy.h"
#include "RpgStrategy.h" #include "RpgStrategy.h"
#include "RTSCStrategy.h"
#include "RunawayStrategy.h" #include "RunawayStrategy.h"
#include "StayStrategy.h" #include "StayStrategy.h"
#include "TankAssistStrategy.h" #include "TankAssistStrategy.h"
@ -228,6 +229,4 @@ class QuestStrategyContext : public NamedObjectContext<Strategy>
static Strategy* accept_all_quests(PlayerbotAI* botAI) { return new AcceptAllQuestsStrategy(botAI); } static Strategy* accept_all_quests(PlayerbotAI* botAI) { return new AcceptAllQuestsStrategy(botAI); }
}; };
#endif #endif

View File

@ -1,14 +1,18 @@
/* /*
* 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. * 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 "Trigger.h" #include "Trigger.h"
#include "Event.h" #include "Event.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Timer.h" #include "Timer.h"
Trigger::Trigger(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : Trigger::Trigger(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
AiNamedObject(botAI, name), checkInterval(checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)), lastCheckTime(0) : AiNamedObject(botAI, name),
checkInterval(checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)),
lastCheckTime(0)
{ {
} }
@ -24,15 +28,9 @@ Event Trigger::Check()
return event; return event;
} }
Value<Unit*>* Trigger::GetTargetValue() Value<Unit*>* Trigger::GetTargetValue() { return context->GetValue<Unit*>(GetTargetName()); }
{
return context->GetValue<Unit*>(GetTargetName());
}
Unit* Trigger::GetTarget() Unit* Trigger::GetTarget() { return GetTargetValue()->Get(); }
{
return GetTargetValue()->Get();
}
bool Trigger::needCheck() bool Trigger::needCheck()
{ {

View File

@ -1,12 +1,13 @@
/* /*
* 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. * 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_TRIGGER_H #ifndef _PLAYERBOT_TRIGGER_H
#define _PLAYERBOT_TRIGGER_H #define _PLAYERBOT_TRIGGER_H
#include "Common.h"
#include "Action.h" #include "Action.h"
#include "Common.h"
class PlayerbotAI; class PlayerbotAI;
class Unit; class Unit;
@ -39,26 +40,20 @@ class Trigger : public AiNamedObject
class TriggerNode class TriggerNode
{ {
public: public:
TriggerNode(std::string const name, NextAction** handlers = nullptr) : trigger(nullptr), handlers(handlers), name(name) { } // reorder args - whipowill TriggerNode(std::string const name, NextAction** handlers = nullptr)
: trigger(nullptr), handlers(handlers), name(name)
virtual ~TriggerNode()
{ {
NextAction::destroy(handlers); } // reorder args - whipowill
}
virtual ~TriggerNode() { NextAction::destroy(handlers); }
Trigger* getTrigger() { return trigger; } Trigger* getTrigger() { return trigger; }
void setTrigger(Trigger* trigger) { this->trigger = trigger; } void setTrigger(Trigger* trigger) { this->trigger = trigger; }
std::string const getName() { return name; } std::string const getName() { return name; }
NextAction** getHandlers() NextAction** getHandlers() { return NextAction::merge(NextAction::clone(handlers), trigger->getHandlers()); }
{
return NextAction::merge(NextAction::clone(handlers), trigger->getHandlers());
}
float getFirstRelevance() float getFirstRelevance() { return handlers[0] ? handlers[0]->getRelevance() : -1; }
{
return handlers[0] ? handlers[0]->getRelevance() : -1;
}
private: private:
Trigger* trigger; Trigger* trigger;

View File

@ -1,13 +1,16 @@
/* /*
* 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. * 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 "Value.h" #include "Value.h"
#include "PerformanceMonitor.h" #include "PerformanceMonitor.h"
#include "Playerbots.h" #include "Playerbots.h"
#include "Timer.h" #include "Timer.h"
UnitCalculatedValue::UnitCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : CalculatedValue<Unit*>(botAI, name, checkInterval) UnitCalculatedValue::UnitCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
: CalculatedValue<Unit*>(botAI, name, checkInterval)
{ {
} }
@ -44,8 +47,8 @@ std::string const FloatCalculatedValue::Format()
return out.str(); return out.str();
} }
CDPairCalculatedValue::CDPairCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : CDPairCalculatedValue::CDPairCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
CalculatedValue<CreatureData const*>(botAI, name, checkInterval) : CalculatedValue<CreatureData const*>(botAI, name, checkInterval)
{ {
// lastCheckTime = getMSTime() - checkInterval / 2; // lastCheckTime = getMSTime() - checkInterval / 2;
} }
@ -62,15 +65,16 @@ std::string const CDPairCalculatedValue::Format()
return "<none>"; return "<none>";
} }
CDPairListCalculatedValue::CDPairListCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : CDPairListCalculatedValue::CDPairListCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
CalculatedValue<std::vector<CreatureData const*>>(botAI, name, checkInterval) : CalculatedValue<std::vector<CreatureData const*>>(botAI, name, checkInterval)
{ {
// lastCheckTime = time(nullptr) - checkInterval / 2; // lastCheckTime = time(nullptr) - checkInterval / 2;
} }
std::string const CDPairListCalculatedValue::Format() std::string const CDPairListCalculatedValue::Format()
{ {
std::ostringstream out; out << "{"; std::ostringstream out;
out << "{";
std::vector<CreatureData const*> cdPairs = Calculate(); std::vector<CreatureData const*> cdPairs = Calculate();
for (CreatureData const* cdPair : cdPairs) for (CreatureData const* cdPair : cdPairs)
{ {
@ -81,8 +85,8 @@ std::string const CDPairListCalculatedValue::Format()
return out.str(); return out.str();
} }
ObjectGuidCalculatedValue::ObjectGuidCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : ObjectGuidCalculatedValue::ObjectGuidCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
CalculatedValue<ObjectGuid>(botAI, name, checkInterval) : CalculatedValue<ObjectGuid>(botAI, name, checkInterval)
{ {
// lastCheckTime = time(nullptr) - checkInterval / 2; // lastCheckTime = time(nullptr) - checkInterval / 2;
} }
@ -93,8 +97,9 @@ std::string const ObjectGuidCalculatedValue::Format()
return guid ? std::to_string(guid.GetRawValue()) : "<none>"; return guid ? std::to_string(guid.GetRawValue()) : "<none>";
} }
ObjectGuidListCalculatedValue::ObjectGuidListCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) : ObjectGuidListCalculatedValue::ObjectGuidListCalculatedValue(PlayerbotAI* botAI, std::string const name,
CalculatedValue<GuidVector>(botAI, name, checkInterval) int32 checkInterval)
: CalculatedValue<GuidVector>(botAI, name, checkInterval)
{ {
} }
@ -116,17 +121,22 @@ std::string const ObjectGuidListCalculatedValue::Format()
Unit* UnitCalculatedValue::Get() Unit* UnitCalculatedValue::Get()
{ {
if (checkInterval < 2) { if (checkInterval < 2)
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); {
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(
PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr);
value = Calculate(); value = Calculate();
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
} else { }
else
{
time_t now = getMSTime(); time_t now = getMSTime();
if (!lastCheckTime || now - lastCheckTime >= checkInterval) if (!lastCheckTime || now - lastCheckTime >= checkInterval)
{ {
lastCheckTime = now; lastCheckTime = now;
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(
PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr);
value = Calculate(); value = Calculate();
if (pmo) if (pmo)
pmo->finish(); pmo->finish();

View File

@ -1,18 +1,19 @@
/* /*
* 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. * 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_VALUE_H #ifndef _PLAYERBOT_VALUE_H
#define _PLAYERBOT_VALUE_H #define _PLAYERBOT_VALUE_H
#include <time.h>
#include "AiObject.h" #include "AiObject.h"
#include "ObjectGuid.h" #include "ObjectGuid.h"
#include "PerformanceMonitor.h" #include "PerformanceMonitor.h"
#include "Timer.h" #include "Timer.h"
#include "Unit.h" #include "Unit.h"
#include <time.h>
class PlayerbotAI; class PlayerbotAI;
class Unit; class Unit;
@ -57,24 +58,34 @@ template<class T>
class CalculatedValue : public UntypedValue, public Value<T> class CalculatedValue : public UntypedValue, public Value<T>
{ {
public: public:
CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1) : UntypedValue(botAI, name), CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1)
checkInterval(checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)) /*turn s -> ms?*/, lastCheckTime(0) { } : UntypedValue(botAI, name),
checkInterval(
checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)) /*turn s -> ms?*/,
lastCheckTime(0)
{
}
virtual ~CalculatedValue() {} virtual ~CalculatedValue() {}
T Get() override T Get() override
{ {
if (checkInterval < 2) { if (checkInterval < 2)
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); {
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(),
// this->context ? &this->context->performanceStack : nullptr);
value = Calculate(); value = Calculate();
// if (pmo) // if (pmo)
// pmo->finish(); // pmo->finish();
} else { }
else
{
time_t now = getMSTime(); time_t now = getMSTime();
if (!lastCheckTime || now - lastCheckTime >= checkInterval) if (!lastCheckTime || now - lastCheckTime >= checkInterval)
{ {
lastCheckTime = now; lastCheckTime = now;
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); // PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(),
// this->context ? &this->context->performanceStack : nullptr);
value = Calculate(); value = Calculate();
// if (pmo) // if (pmo)
// pmo->finish(); // pmo->finish();
@ -92,17 +103,22 @@ class CalculatedValue : public UntypedValue, public Value<T>
} }
T& RefGet() override T& RefGet() override
{ {
if (checkInterval < 2) { if (checkInterval < 2)
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); {
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(),
// this->context ? &this->context->performanceStack : nullptr);
value = Calculate(); value = Calculate();
// if (pmo) // if (pmo)
// pmo->finish(); // pmo->finish();
} else { }
else
{
time_t now = getMSTime(); time_t now = getMSTime();
if (!lastCheckTime || now - lastCheckTime >= checkInterval) if (!lastCheckTime || now - lastCheckTime >= checkInterval)
{ {
lastCheckTime = now; lastCheckTime = now;
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); // PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(),
// this->context ? &this->context->performanceStack : nullptr);
value = Calculate(); value = Calculate();
// if (pmo) // if (pmo)
// pmo->finish(); // pmo->finish();
@ -138,7 +154,8 @@ class SingleCalculatedValue : public CalculatedValue<T>
{ {
this->lastCheckTime = now; this->lastCheckTime = now;
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr); PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(
PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr);
this->value = this->Calculate(); this->value = this->Calculate();
if (pmo) if (pmo)
pmo->finish(); pmo->finish();
@ -152,16 +169,14 @@ template<class T>
class MemoryCalculatedValue : public CalculatedValue<T> class MemoryCalculatedValue : public CalculatedValue<T>
{ {
public: public:
MemoryCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1) : CalculatedValue<T>(botAI, name, checkInterval) MemoryCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1)
: CalculatedValue<T>(botAI, name, checkInterval)
{ {
lastChangeTime = time(0); lastChangeTime = time(0);
} }
virtual bool EqualToLast(T value) = 0; virtual bool EqualToLast(T value) = 0;
virtual bool CanCheckChange() virtual bool CanCheckChange() { return time(0) - lastChangeTime < minChangeInterval || EqualToLast(this->value); }
{
return time(0) - lastChangeTime < minChangeInterval || EqualToLast(this->value);
}
virtual bool UpdateChange() virtual bool UpdateChange()
{ {
@ -186,10 +201,7 @@ class MemoryCalculatedValue : public CalculatedValue<T>
return this->value; return this->value;
} }
T LazyGet() override T LazyGet() override { return this->value; }
{
return this->value;
}
time_t LastChangeOn() time_t LastChangeOn()
{ {
@ -216,7 +228,10 @@ template<class T>
class LogCalculatedValue : public MemoryCalculatedValue<T> class LogCalculatedValue : public MemoryCalculatedValue<T>
{ {
public: public:
LogCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1) : MemoryCalculatedValue<T>(botAI, name, checkInterval) { } LogCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1)
: MemoryCalculatedValue<T>(botAI, name, checkInterval)
{
}
bool UpdateChange() override bool UpdateChange() override
{ {
@ -246,8 +261,10 @@ class LogCalculatedValue : public MemoryCalculatedValue<T>
class Uint8CalculatedValue : public CalculatedValue<uint8> class Uint8CalculatedValue : public CalculatedValue<uint8>
{ {
public: public:
Uint8CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1) : Uint8CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1)
CalculatedValue<uint8>(botAI, name, checkInterval) { } : CalculatedValue<uint8>(botAI, name, checkInterval)
{
}
std::string const Format() override; std::string const Format() override;
}; };
@ -255,8 +272,10 @@ class Uint8CalculatedValue : public CalculatedValue<uint8>
class Uint32CalculatedValue : public CalculatedValue<uint32> class Uint32CalculatedValue : public CalculatedValue<uint32>
{ {
public: public:
Uint32CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1) : Uint32CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1)
CalculatedValue<uint32>(botAI, name, checkInterval) { } : CalculatedValue<uint32>(botAI, name, checkInterval)
{
}
std::string const Format() override; std::string const Format() override;
}; };
@ -264,8 +283,10 @@ class Uint32CalculatedValue : public CalculatedValue<uint32>
class FloatCalculatedValue : public CalculatedValue<float> class FloatCalculatedValue : public CalculatedValue<float>
{ {
public: public:
FloatCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1) : FloatCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1)
CalculatedValue<float>(botAI, name, checkInterval) { } : CalculatedValue<float>(botAI, name, checkInterval)
{
}
std::string const Format() override; std::string const Format() override;
}; };
@ -273,13 +294,12 @@ class FloatCalculatedValue : public CalculatedValue<float>
class BoolCalculatedValue : public CalculatedValue<bool> class BoolCalculatedValue : public CalculatedValue<bool>
{ {
public: public:
BoolCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1) : BoolCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1)
CalculatedValue<bool>(botAI, name, checkInterval) { } : CalculatedValue<bool>(botAI, name, checkInterval)
std::string const Format() override
{ {
return Calculate() ? "true" : "false";
} }
std::string const Format() override { return Calculate() ? "true" : "false"; }
}; };
class UnitCalculatedValue : public CalculatedValue<Unit*> class UnitCalculatedValue : public CalculatedValue<Unit*>
@ -327,8 +347,10 @@ template<class T>
class ManualSetValue : public UntypedValue, public Value<T> class ManualSetValue : public UntypedValue, public Value<T>
{ {
public: public:
ManualSetValue(PlayerbotAI* botAI, T defaultValue, std::string const name = "value") : ManualSetValue(PlayerbotAI* botAI, T defaultValue, std::string const name = "value")
UntypedValue(botAI, name), value(defaultValue), defaultValue(defaultValue) { } : UntypedValue(botAI, name), value(defaultValue), defaultValue(defaultValue)
{
}
virtual ~ManualSetValue() {} virtual ~ManualSetValue() {}
@ -337,10 +359,7 @@ class ManualSetValue : public UntypedValue, public Value<T>
T& RefGet() override { return value; } T& RefGet() override { return value; }
void Set(T val) override { value = val; } void Set(T val) override { value = val; }
void Update() override {} void Update() override {}
void Reset() override void Reset() override { value = defaultValue; }
{
value = defaultValue;
}
protected: protected:
T value; T value;
@ -350,8 +369,10 @@ class ManualSetValue : public UntypedValue, public Value<T>
class UnitManualSetValue : public ManualSetValue<Unit*> class UnitManualSetValue : public ManualSetValue<Unit*>
{ {
public: public:
UnitManualSetValue(PlayerbotAI* botAI, Unit* defaultValue, std::string const name = "value") : UnitManualSetValue(PlayerbotAI* botAI, Unit* defaultValue, std::string const name = "value")
ManualSetValue<Unit*>(botAI, defaultValue, name) { } : ManualSetValue<Unit*>(botAI, defaultValue, name)
{
}
std::string const Format() override; std::string const Format() override;
Unit* Get() override; Unit* Get() override;
@ -360,29 +381,38 @@ class UnitManualSetValue : public ManualSetValue<Unit*>
class DisperseDistanceValue : public ManualSetValue<float> class DisperseDistanceValue : public ManualSetValue<float>
{ {
public: public:
DisperseDistanceValue(PlayerbotAI* botAI, float defaultValue = -1.0f, std::string const name = "disperse distance") : DisperseDistanceValue(PlayerbotAI* botAI, float defaultValue = -1.0f, std::string const name = "disperse distance")
ManualSetValue<float>(botAI, defaultValue, name) { } : ManualSetValue<float>(botAI, defaultValue, name)
{
}
}; };
class LastFleeAngleValue : public ManualSetValue<float> class LastFleeAngleValue : public ManualSetValue<float>
{ {
public: public:
LastFleeAngleValue(PlayerbotAI* botAI, float defaultValue = 0.0f, std::string const name = "last flee angle") : LastFleeAngleValue(PlayerbotAI* botAI, float defaultValue = 0.0f, std::string const name = "last flee angle")
ManualSetValue<float>(botAI, defaultValue, name) { } : ManualSetValue<float>(botAI, defaultValue, name)
{
}
}; };
class LastFleeTimestampValue : public ManualSetValue<uint32> class LastFleeTimestampValue : public ManualSetValue<uint32>
{ {
public: public:
LastFleeTimestampValue(PlayerbotAI* botAI, uint32 defaultValue = 0, std::string const name = "last flee timestamp") : LastFleeTimestampValue(PlayerbotAI* botAI, uint32 defaultValue = 0, std::string const name = "last flee timestamp")
ManualSetValue<uint32>(botAI, defaultValue, name) { } : ManualSetValue<uint32>(botAI, defaultValue, name)
{
}
}; };
class RecentlyFleeInfo : public ManualSetValue<std::list<FleeInfo>> class RecentlyFleeInfo : public ManualSetValue<std::list<FleeInfo>>
{ {
public: public:
RecentlyFleeInfo(PlayerbotAI* botAI, std::list<FleeInfo> defaultValue = {}, std::string const name = "recently flee info") : RecentlyFleeInfo(PlayerbotAI* botAI, std::list<FleeInfo> defaultValue = {},
ManualSetValue<std::list<FleeInfo>>(botAI, defaultValue, name) { } std::string const name = "recently flee info")
: ManualSetValue<std::list<FleeInfo>>(botAI, defaultValue, name)
{
}
}; };
#endif #endif

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "AcceptBattlegroundInvitationAction.h" #include "AcceptBattlegroundInvitationAction.h"
#include "Event.h" #include "Event.h"
#include "Playerbots.h" #include "Playerbots.h"

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_ACCEPTBATTLEGROUNDINVITATIONACTION_H #ifndef _PLAYERBOT_ACCEPTBATTLEGROUNDINVITATIONACTION_H

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "AcceptDuelAction.h" #include "AcceptDuelAction.h"
#include "Event.h" #include "Event.h"
#include "Playerbots.h" #include "Playerbots.h"
@ -16,7 +18,8 @@ bool AcceptDuelAction::Execute(Event event)
p >> playerGuid; p >> playerGuid;
// do not auto duel with low hp // do not auto duel with low hp
if ((!botAI->HasRealPlayerMaster() || (botAI->GetMaster() && botAI->GetMaster()->GetGUID() != playerGuid)) && AI_VALUE2(uint8, "health", "self target") < 90) if ((!botAI->HasRealPlayerMaster() || (botAI->GetMaster() && botAI->GetMaster()->GetGUID() != playerGuid)) &&
AI_VALUE2(uint8, "health", "self target") < 90)
{ {
WorldPacket packet(CMSG_DUEL_CANCELLED, 8); WorldPacket packet(CMSG_DUEL_CANCELLED, 8);
packet << flagGuid; packet << flagGuid;

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_ACCEPTDUELACTION_H #ifndef _PLAYERBOT_ACCEPTDUELACTION_H

View File

@ -1,13 +1,15 @@
/* /*
* 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. * 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 "AcceptInvitationAction.h" #include "AcceptInvitationAction.h"
#include "Event.h" #include "Event.h"
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
#include "PlayerbotAIConfig.h" #include "PlayerbotAIConfig.h"
#include "Playerbots.h"
#include "PlayerbotSecurity.h" #include "PlayerbotSecurity.h"
#include "Playerbots.h"
#include "WorldPacket.h" #include "WorldPacket.h"
bool AcceptInvitationAction::Execute(Event event) bool AcceptInvitationAction::Execute(Event event)
@ -50,7 +52,8 @@ bool AcceptInvitationAction::Execute(Event event)
botAI->TellMaster("Hello"); botAI->TellMaster("Hello");
if (sPlayerbotAIConfig->summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig->sightDistance) { if (sPlayerbotAIConfig->summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig->sightDistance)
{
Teleport(inviter, bot); Teleport(inviter, bot);
} }
return true; return true;

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_ACCEPTINVITATIONACTION_H #ifndef _PLAYERBOT_ACCEPTINVITATIONACTION_H

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "AcceptQuestAction.h" #include "AcceptQuestAction.h"
#include "Event.h" #include "Event.h"
#include "Playerbots.h" #include "Playerbots.h"

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_ACCEPTQUESTACTION_H #ifndef _PLAYERBOT_ACCEPTQUESTACTION_H
@ -14,7 +15,9 @@ class WorldObject;
class AcceptAllQuestsAction : public QuestAction class AcceptAllQuestsAction : public QuestAction
{ {
public: public:
AcceptAllQuestsAction(PlayerbotAI* botAI, std::string const name = "accept all quests") : QuestAction(botAI, name) { } AcceptAllQuestsAction(PlayerbotAI* botAI, std::string const name = "accept all quests") : QuestAction(botAI, name)
{
}
protected: protected:
void ProcessQuest(Quest const* quest, Object* questGiver) override; void ProcessQuest(Quest const* quest, Object* questGiver) override;

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "AcceptResurrectAction.h" #include "AcceptResurrectAction.h"
#include "Event.h" #include "Event.h"
#include "Playerbots.h" #include "Playerbots.h"

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_ACCEPTRESURRECTACTION_H #ifndef _PLAYERBOT_ACCEPTRESURRECTACTION_H

View File

@ -1,5 +1,6 @@
/* /*
* 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. * 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_ACTIONCONTEXT_H #ifndef _PLAYERBOT_ACTIONCONTEXT_H
@ -8,21 +9,23 @@
#include "AddLootAction.h" #include "AddLootAction.h"
#include "AttackAction.h" #include "AttackAction.h"
#include "AutoLearnSpellAction.h" #include "AutoLearnSpellAction.h"
#include "BattleGroundTactics.h" #include "AutoTeleportForLevelAction.h"
#include "BattleGroundJoinAction.h" #include "BattleGroundJoinAction.h"
#include "BattleGroundTactics.h"
#include "BuyAction.h" #include "BuyAction.h"
#include "CastCustomSpellAction.h" #include "CastCustomSpellAction.h"
#include "ChangeStrategyAction.h" #include "ChangeStrategyAction.h"
#include "ChangeTalentsAction.h" #include "ChangeTalentsAction.h"
#include "CheckMailAction.h" #include "CheckMailAction.h"
#include "CheckValuesAction.h" #include "CheckValuesAction.h"
#include "ChooseRpgTargetAction.h"
#include "ChooseTargetActions.h" #include "ChooseTargetActions.h"
#include "ChooseTravelTargetAction.h" #include "ChooseTravelTargetAction.h"
#include "ChooseRpgTargetAction.h"
#include "CombatActions.h" #include "CombatActions.h"
#include "DelayAction.h" #include "DelayAction.h"
#include "DestroyItemAction.h" #include "DestroyItemAction.h"
#include "EmoteAction.h" #include "EmoteAction.h"
#include "FollowActions.h"
#include "GenericActions.h" #include "GenericActions.h"
#include "GenericSpellActions.h" #include "GenericSpellActions.h"
#include "GiveItemAction.h" #include "GiveItemAction.h"
@ -33,14 +36,14 @@
#include "ImbueAction.h" #include "ImbueAction.h"
#include "InviteToGroupAction.h" #include "InviteToGroupAction.h"
#include "LeaveGroupAction.h" #include "LeaveGroupAction.h"
#include "FollowActions.h"
#include "LootAction.h" #include "LootAction.h"
#include "MovementActions.h"
#include "MoveToRpgTargetAction.h" #include "MoveToRpgTargetAction.h"
#include "MoveToTravelTargetAction.h" #include "MoveToTravelTargetAction.h"
#include "MovementActions.h"
#include "NonCombatActions.h" #include "NonCombatActions.h"
#include "OutfitAction.h" #include "OutfitAction.h"
#include "PositionAction.h" #include "PositionAction.h"
#include "RaidNaxxActions.h"
#include "RandomBotUpdateAction.h" #include "RandomBotUpdateAction.h"
#include "ReachTargetActions.h" #include "ReachTargetActions.h"
#include "ReleaseSpiritAction.h" #include "ReleaseSpiritAction.h"
@ -54,11 +57,9 @@
#include "StayActions.h" #include "StayActions.h"
#include "SuggestWhatToDoAction.h" #include "SuggestWhatToDoAction.h"
#include "TravelAction.h" #include "TravelAction.h"
#include "XpGainAction.h"
#include "VehicleActions.h" #include "VehicleActions.h"
#include "WorldBuffAction.h" #include "WorldBuffAction.h"
#include "RaidNaxxActions.h" #include "XpGainAction.h"
#include "AutoTeleportForLevelAction.h"
class PlayerbotAI; class PlayerbotAI;
@ -231,7 +232,6 @@ class ActionContext : public NamedObjectContext<Action>
creators["toggle pet spell"] = &ActionContext::toggle_pet_spell; creators["toggle pet spell"] = &ActionContext::toggle_pet_spell;
creators["pet attack"] = &ActionContext::pet_attack; creators["pet attack"] = &ActionContext::pet_attack;
} }
private: private:
@ -265,7 +265,10 @@ class ActionContext : public NamedObjectContext<Action>
static Action* ReachSpell(PlayerbotAI* botAI) { return new ReachSpellAction(botAI); } static Action* ReachSpell(PlayerbotAI* botAI) { return new ReachSpellAction(botAI); }
static Action* ReachMelee(PlayerbotAI* botAI) { return new ReachMeleeAction(botAI); } static Action* ReachMelee(PlayerbotAI* botAI) { return new ReachMeleeAction(botAI); }
static Action* reach_party_member_to_heal(PlayerbotAI* botAI) { return new ReachPartyMemberToHealAction(botAI); } static Action* reach_party_member_to_heal(PlayerbotAI* botAI) { return new ReachPartyMemberToHealAction(botAI); }
static Action* reach_party_member_to_resurrect(PlayerbotAI* botAI) { return new ReachPartyMemberToResurrectAction(botAI); } static Action* reach_party_member_to_resurrect(PlayerbotAI* botAI)
{
return new ReachPartyMemberToResurrectAction(botAI);
}
static Action* flee(PlayerbotAI* botAI) { return new FleeAction(botAI); } static Action* flee(PlayerbotAI* botAI) { return new FleeAction(botAI); }
static Action* flee_with_pet(PlayerbotAI* botAI) { return new FleeWithPetAction(botAI); } static Action* flee_with_pet(PlayerbotAI* botAI) { return new FleeWithPetAction(botAI); }
static Action* avoid_aoe(PlayerbotAI* botAI) { return new AvoidAoeAction(botAI); } static Action* avoid_aoe(PlayerbotAI* botAI) { return new AvoidAoeAction(botAI); }
@ -401,7 +404,6 @@ class ActionContext : public NamedObjectContext<Action>
static Action* toggle_pet_spell(PlayerbotAI* ai) { return new TogglePetSpellAutoCastAction(ai); } static Action* toggle_pet_spell(PlayerbotAI* ai) { return new TogglePetSpellAutoCastAction(ai); }
static Action* pet_attack(PlayerbotAI* ai) { return new PetAttackAction(ai); } static Action* pet_attack(PlayerbotAI* ai) { return new PetAttackAction(ai); }
}; };
#endif #endif

View File

@ -1,8 +1,10 @@
/* /*
* 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. * 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 "AddLootAction.h" #include "AddLootAction.h"
#include "CellImpl.h" #include "CellImpl.h"
#include "Event.h" #include "Event.h"
#include "GridNotifiers.h" #include "GridNotifiers.h"
@ -35,20 +37,11 @@ bool AddAllLootAction::Execute(Event event)
return added; return added;
} }
bool AddLootAction::isUseful() bool AddLootAction::isUseful() { return true; }
{
return true;
}
bool AddAllLootAction::isUseful() bool AddAllLootAction::isUseful() { return true; }
{
return true;
}
bool AddAllLootAction::AddLoot(ObjectGuid guid) bool AddAllLootAction::AddLoot(ObjectGuid guid) { return AI_VALUE(LootObjectStack*, "available loot")->Add(guid); }
{
return AI_VALUE(LootObjectStack*, "available loot")->Add(guid);
}
bool AddGatheringLootAction::AddLoot(ObjectGuid guid) bool AddGatheringLootAction::AddLoot(ObjectGuid guid)
{ {

Some files were not shown because too many files have changed in this diff Show More