mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-02-20 18:10:02 +01:00
Run clang-format
This commit is contained in:
parent
44da167492
commit
53611c9040
@ -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 "BattlegroundMgr.h"
|
||||
#include "DKAiObjectContext.h"
|
||||
#include "DruidAiObjectContext.h"
|
||||
#include "Engine.h"
|
||||
#include "Group.h"
|
||||
#include "HunterAiObjectContext.h"
|
||||
#include "Item.h"
|
||||
#include "MageAiObjectContext.h"
|
||||
#include "PaladinAiObjectContext.h"
|
||||
#include "PlayerbotAI.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Engine.h"
|
||||
#include "Group.h"
|
||||
#include "DKAiObjectContext.h"
|
||||
#include "PriestAiObjectContext.h"
|
||||
#include "MageAiObjectContext.h"
|
||||
#include "RogueAiObjectContext.h"
|
||||
#include "ShamanAiObjectContext.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "WarlockAiObjectContext.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)
|
||||
{
|
||||
@ -100,7 +102,8 @@ std::map<uint8, uint32> AiFactory::GetPlayerSpecTabs(Player* bot)
|
||||
for (PlayerTalentMap::const_iterator i = talentMap.begin(); i != talentMap.end(); ++i)
|
||||
{
|
||||
uint32 spellId = i->first;
|
||||
if ((bot->GetActiveSpecMask() & i->second->specMask) == 0) {
|
||||
if ((bot->GetActiveSpecMask() & i->second->specMask) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
TalentSpellPos const* talentPos = GetTalentSpellPos(spellId);
|
||||
@ -186,7 +189,8 @@ std::string AiFactory::GetPlayerSpecName(Player* player)
|
||||
specName = "holy";
|
||||
else
|
||||
specName = "disc";
|
||||
; break;
|
||||
;
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
if (tab == 2)
|
||||
specName = "resto";
|
||||
@ -286,11 +290,16 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
switch (player->getClass())
|
||||
{
|
||||
case CLASS_PRIEST:
|
||||
if (tab == 2) {
|
||||
if (tab == 2)
|
||||
{
|
||||
engine->addStrategies("dps", "shadow debuff", "shadow aoe", nullptr);
|
||||
} else if (tab == PRIEST_TAB_DISIPLINE) {
|
||||
}
|
||||
else if (tab == PRIEST_TAB_DISIPLINE)
|
||||
{
|
||||
engine->addStrategies("heal", nullptr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
engine->addStrategies("holy heal", nullptr);
|
||||
}
|
||||
|
||||
@ -343,9 +352,12 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
engine->addStrategies("heal", "cure", "dps assist", nullptr);
|
||||
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);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
engine->addStrategies("bear", "tank assist", nullptr);
|
||||
}
|
||||
}
|
||||
@ -355,9 +367,12 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
engine->addStrategy("dps debuff");
|
||||
break;
|
||||
case CLASS_ROGUE:
|
||||
if (tab == ROGUE_TAB_ASSASSINATION) {
|
||||
if (tab == ROGUE_TAB_ASSASSINATION)
|
||||
{
|
||||
engine->addStrategies("melee", "dps assist", "aoe", /*"behind",*/ nullptr);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
engine->addStrategies("dps", "dps assist", "aoe", /*"behind",*/ nullptr);
|
||||
}
|
||||
break;
|
||||
@ -384,28 +399,37 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
engine->addStrategy("dps assist");
|
||||
engine->removeStrategy("threat");
|
||||
// engine-
|
||||
switch (player->getClass()) {
|
||||
case CLASS_PRIEST: {
|
||||
if (tab != PRIEST_TAB_SHADOW) {
|
||||
switch (player->getClass())
|
||||
{
|
||||
case CLASS_PRIEST:
|
||||
{
|
||||
if (tab != PRIEST_TAB_SHADOW)
|
||||
{
|
||||
engine->addStrategies("holy dps", "shadow debuff", "shadow aoe", nullptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLASS_DRUID: {
|
||||
if (tab == DRUID_TAB_RESTORATION) {
|
||||
case CLASS_DRUID:
|
||||
{
|
||||
if (tab == DRUID_TAB_RESTORATION)
|
||||
{
|
||||
engine->addStrategies("caster", "caster aoe", nullptr);
|
||||
engine->addStrategy("caster debuff");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLASS_SHAMAN: {
|
||||
if (tab == SHAMAN_TAB_RESTORATION) {
|
||||
case CLASS_SHAMAN:
|
||||
{
|
||||
if (tab == SHAMAN_TAB_RESTORATION)
|
||||
{
|
||||
engine->addStrategies("caster", "caster aoe", "bmana", nullptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLASS_PALADIN: {
|
||||
if (tab == PALADIN_TAB_HOLY) {
|
||||
case CLASS_PALADIN:
|
||||
{
|
||||
if (tab == PALADIN_TAB_HOLY)
|
||||
{
|
||||
engine->addStrategies("dps", "dps assist", "baoe", nullptr);
|
||||
}
|
||||
break;
|
||||
@ -447,7 +471,8 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
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("flee");
|
||||
engine->removeStrategy("threat");
|
||||
@ -481,11 +506,15 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
if (tab == 1) {
|
||||
if (tab == 1)
|
||||
{
|
||||
nonCombatEngine->addStrategies("bthreat", "tank assist", "barmor", nullptr);
|
||||
if (player->GetLevel() >= 20) {
|
||||
if (player->GetLevel() >= 20)
|
||||
{
|
||||
nonCombatEngine->addStrategy("bstats");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
nonCombatEngine->addStrategy("bdps");
|
||||
}
|
||||
}
|
||||
@ -516,10 +545,14 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
nonCombatEngine->addStrategies("dps assist", "cure", nullptr);
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
if (tab == 1) {
|
||||
if (player->GetLevel() >= 20 && !player->HasAura(16931)/*thick hide*/) {
|
||||
if (tab == 1)
|
||||
{
|
||||
if (player->GetLevel() >= 20 && !player->HasAura(16931) /*thick hide*/)
|
||||
{
|
||||
nonCombatEngine->addStrategy("dps assist");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
nonCombatEngine->addStrategy("tank assist");
|
||||
}
|
||||
}
|
||||
@ -533,11 +566,16 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
nonCombatEngine->addStrategy("dps assist");
|
||||
break;
|
||||
case CLASS_WARLOCK:
|
||||
if (tab == WARLOCK_TAB_AFFLICATION) {
|
||||
if (tab == WARLOCK_TAB_AFFLICATION)
|
||||
{
|
||||
nonCombatEngine->addStrategies("bmana", nullptr);
|
||||
} else if (tab == WARLOCK_TAB_DEMONOLOGY) {
|
||||
}
|
||||
else if (tab == WARLOCK_TAB_DEMONOLOGY)
|
||||
{
|
||||
nonCombatEngine->addStrategies("bdps", nullptr);
|
||||
} else if (tab == WARLOCK_TAB_DESTRUCTION) {
|
||||
}
|
||||
else if (tab == WARLOCK_TAB_DESTRUCTION)
|
||||
{
|
||||
nonCombatEngine->addStrategies("bhealth", nullptr);
|
||||
}
|
||||
nonCombatEngine->addStrategies("dps assist", nullptr);
|
||||
@ -555,10 +593,11 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
|
||||
if (!player->InBattleground())
|
||||
{
|
||||
nonCombatEngine->addStrategies("nc", "food", "chat", "follow",
|
||||
"default", "quest", "loot", "gather", "duel", "buff", "mount", "emote", nullptr);
|
||||
nonCombatEngine->addStrategies("nc", "food", "chat", "follow", "default", "quest", "loot", "gather", "duel",
|
||||
"buff", "mount", "emote", nullptr);
|
||||
}
|
||||
if (sPlayerbotAIConfig->autoSaveMana) {
|
||||
if (sPlayerbotAIConfig->autoSaveMana)
|
||||
{
|
||||
nonCombatEngine->addStrategy("auto save mana");
|
||||
}
|
||||
if ((sRandomPlayerbotMgr->IsRandomBot(player)) && !player->InBattleground())
|
||||
@ -588,7 +627,9 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
{
|
||||
// nonCombatEngine->addStrategy("travel");
|
||||
nonCombatEngine->addStrategy("rpg");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
nonCombatEngine->addStrategy("move random");
|
||||
}
|
||||
|
||||
@ -627,7 +668,8 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
|
||||
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->randomBotNonCombatStrategies);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
nonCombatEngine->addStrategy("pvp");
|
||||
nonCombatEngine->ChangeStrategy(sPlayerbotAIConfig->nonCombatStrategies);
|
||||
}
|
||||
@ -644,7 +686,8 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
// Battleground switch
|
||||
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("travel");
|
||||
nonCombatEngine->removeStrategy("rpg");
|
||||
@ -654,7 +697,8 @@ void AiFactory::AddDefaultNonCombatStrategies(Player* player, PlayerbotAI* const
|
||||
if (bgType == BATTLEGROUND_RB)
|
||||
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");
|
||||
|
||||
if (bgType == BATTLEGROUND_WS)
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_AIFACTORY_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
class AiObjectContext;
|
||||
class Engine;
|
||||
class Player;
|
||||
|
||||
@ -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 "Group.h"
|
||||
#include "Playerbots.h"
|
||||
#include "RtiTargetValue.h"
|
||||
@ -295,4 +297,3 @@ std::string const CompositeChatFilter::Filter(std::string& message)
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_CHATFILTER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
#include "PlayerbotAIAware.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class ChatFilter : public PlayerbotAIAware
|
||||
|
||||
@ -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 "AiFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SpellInfo.h"
|
||||
@ -281,22 +283,27 @@ ItemIds ChatHelper::parseItems(std::string const text)
|
||||
std::string const ChatHelper::FormatQuest(Quest const* quest)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
std::string const ChatHelper::FormatGameobject(GameObject* go)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
std::string const ChatHelper::FormatWorldobject(WorldObject* wo)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "|cFFFFFF00|Hfound:" << wo->GetGUID().GetRawValue() << ":" << wo->GetEntry() << ":" << "|h[";
|
||||
out << (wo->ToGameObject() ? ((GameObject*)wo)->GetNameForLocaleIdx(LOCALE_enUS) : wo->GetNameForLocaleIdx(LOCALE_enUS)) << "]|h|r";
|
||||
out << "|cFFFFFF00|Hfound:" << wo->GetGUID().GetRawValue() << ":" << wo->GetEntry() << ":"
|
||||
<< "|h[";
|
||||
out << (wo->ToGameObject() ? ((GameObject*)wo)->GetNameForLocaleIdx(LOCALE_enUS)
|
||||
: wo->GetNameForLocaleIdx(LOCALE_enUS))
|
||||
<< "]|h|r";
|
||||
return out.str();
|
||||
}
|
||||
|
||||
@ -311,7 +318,8 @@ std::string const ChatHelper::FormatWorldEntry(int32 entry)
|
||||
gInfo = sObjectMgr->GetGameObjectTemplate(entry * -1);
|
||||
|
||||
std::ostringstream out;
|
||||
out << "|cFFFFFF00|Hentry:" << abs(entry) << ":" << "|h[";
|
||||
out << "|cFFFFFF00|Hentry:" << abs(entry) << ":"
|
||||
<< "|h[";
|
||||
|
||||
if (entry < 0 && gInfo)
|
||||
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];
|
||||
|
||||
std::ostringstream out;
|
||||
out << "|c" << color << "|Hitem:" << proto->ItemId
|
||||
<< ":0:0:0:0:0:0:0" << "|h[" << proto->Name1
|
||||
<< "]|h|r";
|
||||
out << "|c" << color << "|Hitem:" << proto->ItemId << ":0:0:0:0:0:0:0"
|
||||
<< "|h[" << proto->Name1 << "]|h|r";
|
||||
|
||||
if (count > 1)
|
||||
out << "x" << count;
|
||||
@ -392,7 +399,6 @@ std::string const ChatHelper::FormatChat(ChatMsg chat)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
|
||||
uint32 ChatHelper::parseSpell(std::string const text)
|
||||
{
|
||||
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::ostringstream out;
|
||||
out << "|cFFFFFFFF" << name << (available >= required ? "|c0000FF00: " : "|c00FF0000: ")
|
||||
<< available << "/" << required << "|r";
|
||||
out << "|cFFFFFFFF" << name << (available >= required ? "|c0000FF00: " : "|c00FF0000: ") << available << "/"
|
||||
<< required << "|r";
|
||||
|
||||
return out.str();
|
||||
}
|
||||
@ -501,9 +507,11 @@ uint32 ChatHelper::parseSlot(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) ||
|
||||
substrContainsInMap<uint32>(text, tradeSubClasses) || substrContainsInMap<uint32>(text, itemQualities) || substrContainsInMap<uint32>(text, slots) ||
|
||||
substrContainsInMap<ChatMsg>(text, chats) || substrContainsInMap<uint32>(text, skills) || parseMoney(text) > 0;
|
||||
return text.find("|H") != std::string::npos || text == "questitem" || text == "ammo" ||
|
||||
substrContainsInMap<uint32>(text, consumableSubClasses) ||
|
||||
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)
|
||||
@ -526,15 +534,9 @@ std::string const ChatHelper::FormatClass(Player* player, int8 spec)
|
||||
return out.str();
|
||||
}
|
||||
|
||||
std::string const ChatHelper::FormatClass(uint8 cls)
|
||||
{
|
||||
return classes[cls];
|
||||
}
|
||||
std::string const ChatHelper::FormatClass(uint8 cls) { return classes[cls]; }
|
||||
|
||||
std::string const ChatHelper::FormatRace(uint8 race)
|
||||
{
|
||||
return races[race];
|
||||
}
|
||||
std::string const ChatHelper::FormatRace(uint8 race) { return races[race]; }
|
||||
|
||||
uint32 ChatHelper::parseSkill(std::string const text)
|
||||
{
|
||||
@ -555,10 +557,7 @@ std::string const ChatHelper::FormatSkill(uint32 skill)
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string const ChatHelper::FormatBoolean(bool flag)
|
||||
{
|
||||
return flag ? "|cff00ff00ON|r" : "|cffffff00OFF|r";
|
||||
}
|
||||
std::string const ChatHelper::FormatBoolean(bool flag) { return flag ? "|cff00ff00ON|r" : "|cffffff00OFF|r"; }
|
||||
|
||||
void ChatHelper::eraseAllSubStr(std::string& mainStr, std::string const toErase)
|
||||
{
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_CHATHELPER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Common.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "PlayerbotAIAware.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class GameObject;
|
||||
class Quest;
|
||||
class Player;
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
|
||||
FleeManager::FleeManager(Player* bot, float maxAllowedDistance, float followAngle, bool forceMaxDistance, WorldPosition startPosition) :
|
||||
bot(bot), maxAllowedDistance(maxAllowedDistance), followAngle(followAngle), forceMaxDistance(forceMaxDistance), startPosition(startPosition ? startPosition : WorldPosition(bot))
|
||||
FleeManager::FleeManager(Player* bot, float maxAllowedDistance, float followAngle, bool forceMaxDistance,
|
||||
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->sumDistance = 0.0f;
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
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)
|
||||
{
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Unit* target = *botAI->GetAiObjectContext()->GetValue<Unit*>("current target");
|
||||
@ -72,19 +81,24 @@ void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*> &points)
|
||||
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)
|
||||
{
|
||||
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 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))
|
||||
continue;
|
||||
|
||||
float x = botPosX + cos(angle) * maxAllowedDistance, y = botPosY + sin(angle) * maxAllowedDistance, z = botPosZ + CONTACT_DISTANCE;
|
||||
if (forceMaxDistance && sServerFacade->IsDistanceLessThan(sServerFacade->GetDistance2d(bot, x, y), maxAllowedDistance - sPlayerbotAIConfig->tooCloseDistance))
|
||||
float x = botPosX + cos(angle) * maxAllowedDistance, y = botPosY + sin(angle) * maxAllowedDistance,
|
||||
z = botPosZ + CONTACT_DISTANCE;
|
||||
if (forceMaxDistance &&
|
||||
sServerFacade->IsDistanceLessThan(sServerFacade->GetDistance2d(bot, x, y),
|
||||
maxAllowedDistance - sPlayerbotAIConfig->tooCloseDistance))
|
||||
continue;
|
||||
|
||||
bot->UpdateAllowedPositionZ(x, y, z);
|
||||
@ -99,7 +113,8 @@ void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*> &points)
|
||||
FleePoint* point = new FleePoint(botAI, x, y, z);
|
||||
calculateDistanceToCreatures(point);
|
||||
|
||||
if (sServerFacade->IsDistanceGreaterOrEqualThan(point->minDistance - start.minDistance, sPlayerbotAIConfig->followDistance))
|
||||
if (sServerFacade->IsDistanceGreaterOrEqualThan(point->minDistance - start.minDistance,
|
||||
sPlayerbotAIConfig->followDistance))
|
||||
points.push_back(point);
|
||||
else
|
||||
delete point;
|
||||
@ -159,7 +174,8 @@ bool FleeManager::CalculateDestination(float* rx, float* ry, float* rz)
|
||||
bool FleeManager::isUseful()
|
||||
{
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GuidVector units = *botAI->GetAiObjectContext()->GetValue<GuidVector>("possible targets no los");
|
||||
@ -169,7 +185,8 @@ bool FleeManager::isUseful()
|
||||
if (!creature)
|
||||
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;
|
||||
|
||||
// float d = sServerFacade->GetDistance2d(unit, bot);
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_FLEEMANAGER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
#include "TravelMgr.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Player;
|
||||
class PlayerbotAI;
|
||||
|
||||
class FleePoint
|
||||
{
|
||||
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 y;
|
||||
@ -32,7 +36,8 @@ class FleePoint
|
||||
class FleeManager
|
||||
{
|
||||
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 isUseful();
|
||||
|
||||
@ -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 "ChatHelper.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "Group.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "Mail.h"
|
||||
#include "MapMgr.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "RandomItemMgr.h"
|
||||
#include "ServerFacade.h"
|
||||
|
||||
@ -46,9 +48,11 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
|
||||
|
||||
DenyReason reason = PLAYERBOT_DENY_NONE;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -72,14 +76,18 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -92,11 +100,14 @@ void GuildTaskMgr::Update(Player* player, Player* guildMaster)
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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, "itemTask", itemId, sPlayerbotAIConfig->maxGuildTaskChangeTime);
|
||||
SetTaskValue(player->GetGUID().GetCounter(), guildId, "itemCount", count,
|
||||
sPlayerbotAIConfig->maxGuildTaskChangeTime);
|
||||
SetTaskValue(player->GetGUID().GetCounter(), guildId, "itemTask", itemId,
|
||||
sPlayerbotAIConfig->maxGuildTaskChangeTime);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -204,8 +221,10 @@ bool GuildTaskMgr::CreateKillTask(Player* player, uint32 guildId)
|
||||
std::vector<uint32> ids;
|
||||
|
||||
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 "
|
||||
"JOIN creature c ON ct.Entry = c.id1 WHERE ct.MaxLevel < {} AND ct.MinLevel > {} AND ct.Rank = {} ", level + 4, level - 3, rank);
|
||||
QueryResult results = WorldDatabase.Query(
|
||||
"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)
|
||||
{
|
||||
do
|
||||
@ -231,16 +250,19 @@ bool GuildTaskMgr::CreateKillTask(Player* player, uint32 guildId)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint32 index = urand(0, ids.size() - 1);
|
||||
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;
|
||||
}
|
||||
@ -283,7 +305,8 @@ std::string const formatTime(uint32 secs)
|
||||
else if (secs < 3600 * 24)
|
||||
{
|
||||
out << secs / 3600 << " hr";
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
out << secs / 3600 / 24 << " days";
|
||||
}
|
||||
@ -318,7 +341,8 @@ std::string const GetHelloText(uint32 owner)
|
||||
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);
|
||||
Player* leader = ObjectAccessor::FindPlayer(guild->GetLeaderGUID());
|
||||
@ -352,7 +376,8 @@ bool GuildTaskMgr::SendItemAdvertisement(CharacterDatabaseTransaction& trans, ui
|
||||
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);
|
||||
Player* leader = ObjectAccessor::FindPlayer(guild->GetLeaderGUID());
|
||||
@ -361,7 +386,8 @@ bool GuildTaskMgr::SendKillAdvertisement(CharacterDatabaseTransaction& trans, ui
|
||||
if (!proto)
|
||||
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)
|
||||
return false;
|
||||
|
||||
@ -387,7 +413,8 @@ bool GuildTaskMgr::SendKillAdvertisement(CharacterDatabaseTransaction& trans, ui
|
||||
|
||||
std::ostringstream body;
|
||||
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";
|
||||
if (!location.empty())
|
||||
body << proto->Name << "'s the last known location was " << location << ".\n";
|
||||
@ -399,7 +426,8 @@ bool GuildTaskMgr::SendKillAdvertisement(CharacterDatabaseTransaction& trans, ui
|
||||
|
||||
std::ostringstream subject;
|
||||
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 << proto->Name;
|
||||
if (!location.empty())
|
||||
@ -441,9 +469,7 @@ bool GuildTaskMgr::SendThanks(CharacterDatabaseTransaction& trans, uint32 owner,
|
||||
body << guild->GetName() << "\n";
|
||||
body << leader->GetName() << "\n";
|
||||
|
||||
MailDraft("Thank You", body.str()).
|
||||
AddMoney(payment).
|
||||
SendMailTo(trans, MailReceiver(owner), MailSender(leader));
|
||||
MailDraft("Thank You", body.str()).AddMoney(payment).SendMailTo(trans, MailReceiver(owner), MailSender(leader));
|
||||
|
||||
Player* player = ObjectAccessor::FindPlayer(ObjectGuid::Create<HighGuid::Player>(owner));
|
||||
if (player)
|
||||
@ -501,7 +527,8 @@ bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
|
||||
{
|
||||
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(1, guildId);
|
||||
stmt->SetData(2, "itemTask");
|
||||
@ -518,11 +545,13 @@ bool GuildTaskMgr::IsGuildTaskItem(uint32 itemId, uint32 guildId)
|
||||
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;
|
||||
|
||||
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(1, type);
|
||||
if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt))
|
||||
@ -549,7 +578,8 @@ uint32 GuildTaskMgr::GetTaskValue(uint32 owner, uint32 guildId, std::string cons
|
||||
{
|
||||
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(1, guildId);
|
||||
stmt->SetData(2, type);
|
||||
@ -633,7 +663,8 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* handler, char const* args)
|
||||
|
||||
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(1, "activeTask");
|
||||
if (PreparedQueryResult result = PlayerbotsDatabase.Query(stmt))
|
||||
@ -731,11 +762,10 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* handler, char const* args)
|
||||
if (payment && paymentValidIn < validIn)
|
||||
name << " payment " << ChatHelper::formatMoney(payment) << " in " << formatTime(paymentValidIn);
|
||||
|
||||
LOG_INFO("playerbots", "{}: {} valid in {} [{}]",
|
||||
charName.c_str(), name.str().c_str(), formatTime(validIn).c_str(), guild->GetName().c_str());
|
||||
LOG_INFO("playerbots", "{}: {} valid in {} [{}]", charName.c_str(), name.str().c_str(),
|
||||
formatTime(validIn).c_str(), guild->GetName().c_str());
|
||||
|
||||
}
|
||||
while (result->NextRow());
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -780,7 +810,8 @@ bool GuildTaskMgr::HandleConsoleCommand(ChatHandler* handler, char const* args)
|
||||
|
||||
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);
|
||||
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");
|
||||
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)
|
||||
SendCompletionMessage(ownerPlayer, "made a mistake with");
|
||||
@ -857,7 +889,8 @@ bool GuildTaskMgr::CheckItemTask(uint32 itemId, uint32 obtained, Player* ownerPl
|
||||
|
||||
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, "itemCount", 0, 0);
|
||||
SetTaskValue(owner, guildId, "thanks", 0, 0);
|
||||
@ -865,7 +898,8 @@ bool GuildTaskMgr::CheckItemTask(uint32 itemId, uint32 obtained, Player* ownerPl
|
||||
}
|
||||
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, "thanks", 1, rewardTime - 30);
|
||||
SendCompletionMessage(ownerPlayer, "made a progress with");
|
||||
@ -904,12 +938,14 @@ bool GuildTaskMgr::Reward(CharacterDatabaseTransaction& trans, uint32 owner, uin
|
||||
if (!proto)
|
||||
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 << "Many thanks,\n";
|
||||
body << guild->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);
|
||||
}
|
||||
else if (killTask)
|
||||
@ -918,12 +954,14 @@ bool GuildTaskMgr::Reward(CharacterDatabaseTransaction& trans, uint32 owner, uin
|
||||
if (!proto)
|
||||
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 << "Many thanks,\n";
|
||||
body << guild->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);
|
||||
if (itemId)
|
||||
{
|
||||
@ -1032,7 +1070,8 @@ void GuildTaskMgr::CheckKillTaskInternal(Player* player, Unit* victim)
|
||||
continue;
|
||||
|
||||
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");
|
||||
}
|
||||
@ -1041,7 +1080,8 @@ void GuildTaskMgr::CheckKillTaskInternal(Player* player, Unit* victim)
|
||||
void GuildTaskMgr::CleanupAdverts()
|
||||
{
|
||||
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)
|
||||
return;
|
||||
|
||||
@ -1059,7 +1099,8 @@ void GuildTaskMgr::CleanupAdverts()
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -1067,8 +1108,12 @@ void GuildTaskMgr::CleanupAdverts()
|
||||
void GuildTaskMgr::RemoveDuplicatedAdverts()
|
||||
{
|
||||
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%%' "
|
||||
"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);
|
||||
QueryResult result = CharacterDatabase.Query(
|
||||
"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)
|
||||
return;
|
||||
@ -1103,7 +1148,6 @@ void GuildTaskMgr::RemoveDuplicatedAdverts()
|
||||
DeleteMail(buffer);
|
||||
LOG_INFO("playerbots", "{} duplicated gtask adverts removed", count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GuildTaskMgr::DeleteMail(std::vector<uint32> buffer)
|
||||
@ -1147,7 +1191,8 @@ bool GuildTaskMgr::CheckTaskTransfer(std::string const text, Player* ownerPlayer
|
||||
if (text.empty())
|
||||
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();
|
||||
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_GUILDTASKMGR_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Transaction.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class ChatHandler;
|
||||
class Player;
|
||||
class Unit;
|
||||
@ -41,8 +42,10 @@ class GuildTaskMgr
|
||||
uint32 SetTaskValue(uint32 owner, uint32 guildId, std::string const type, uint32 value, uint32 validIn);
|
||||
uint32 CreateTask(Player* owner, uint32 guildId);
|
||||
bool SendAdvertisement(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId);
|
||||
bool SendItemAdvertisement(CharacterDatabaseTransaction& trans, uint32 itemId, uint32 owner, uint32 guildId, uint32 validIn);
|
||||
bool SendKillAdvertisement(CharacterDatabaseTransaction& trans, uint32 creatureId, uint32 owner, uint32 guildId, uint32 validIn);
|
||||
bool SendItemAdvertisement(CharacterDatabaseTransaction& trans, uint32 itemId, uint32 owner, uint32 guildId,
|
||||
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 Reward(CharacterDatabaseTransaction& trans, uint32 owner, uint32 guildId);
|
||||
bool CreateItemTask(Player* owner, uint32 guildId);
|
||||
|
||||
@ -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"
|
||||
@ -46,7 +47,4 @@ std::string& rtrim(std::string& s)
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string& trim(std::string& s)
|
||||
{
|
||||
return ltrim(rtrim(s));
|
||||
}
|
||||
std::string& trim(std::string& s) { return ltrim(rtrim(s)); }
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_HELPERS_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
||||
@ -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
|
||||
@ -12,10 +13,7 @@ class LazyCalculatedValue
|
||||
typedef TValue (TOwner::*Calculator)();
|
||||
|
||||
public:
|
||||
LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner) { Reset(); }
|
||||
|
||||
public:
|
||||
TValue GetValue()
|
||||
@ -29,10 +27,7 @@ class LazyCalculatedValue
|
||||
return value;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
calculated = false;
|
||||
}
|
||||
void Reset() { calculated = false; }
|
||||
|
||||
protected:
|
||||
Calculator calculator;
|
||||
|
||||
@ -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 "LootMgr.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Unit.h"
|
||||
|
||||
#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)
|
||||
{
|
||||
@ -30,10 +30,7 @@ LootTarget& LootTarget::operator=(LootTarget const& other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool LootTarget::operator<(LootTarget const& other) const
|
||||
{
|
||||
return guid < other.guid;
|
||||
}
|
||||
bool LootTarget::operator<(LootTarget const& other) const { return guid < other.guid; }
|
||||
|
||||
void LootTargetList::shrink(time_t fromTime)
|
||||
{
|
||||
@ -59,7 +56,8 @@ void LootObject::Refresh(Player* bot, ObjectGuid lootGUID)
|
||||
guid.Clear();
|
||||
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Creature* creature = botAI->GetCreature(lootGUID);
|
||||
@ -83,7 +81,6 @@ void LootObject::Refresh(Player* bot, ObjectGuid lootGUID)
|
||||
GameObject* go = botAI->GetGameObject(lootGUID);
|
||||
if (go && go->isSpawned() && go->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
|
||||
bool isQuestItemOnly = false;
|
||||
|
||||
GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(go->GetEntry());
|
||||
@ -178,7 +175,8 @@ WorldObject* LootObject::GetWorldObject(Player* bot)
|
||||
Refresh(bot, guid);
|
||||
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
Creature* creature = botAI->GetCreature(guid);
|
||||
@ -206,7 +204,8 @@ bool LootObject::IsLootPossible(Player* bot)
|
||||
return false;
|
||||
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (reqItem && !bot->HasItemCount(reqItem, 1))
|
||||
@ -249,11 +248,13 @@ bool LootObject::IsLootPossible(Player* bot)
|
||||
|
||||
bool LootObjectStack::Add(ObjectGuid guid)
|
||||
{
|
||||
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) {
|
||||
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT)
|
||||
{
|
||||
availableLoot.shrink(time(nullptr) - 30);
|
||||
}
|
||||
|
||||
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT) {
|
||||
if (availableLoot.size() >= MAX_LOOT_OBJECT_COUNT)
|
||||
{
|
||||
availableLoot.clear();
|
||||
}
|
||||
|
||||
@ -270,10 +271,7 @@ void LootObjectStack::Remove(ObjectGuid guid)
|
||||
availableLoot.erase(i);
|
||||
}
|
||||
|
||||
void LootObjectStack::Clear()
|
||||
{
|
||||
availableLoot.clear();
|
||||
}
|
||||
void LootObjectStack::Clear() { availableLoot.clear(); }
|
||||
|
||||
bool LootObjectStack::CanLoot(float maxDistance)
|
||||
{
|
||||
@ -311,4 +309,3 @@ std::vector<LootObject> LootObjectStack::OrderByDistance(float maxDistance)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 "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)
|
||||
return nullptr;
|
||||
@ -50,7 +53,6 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
if (data.empty())
|
||||
return;
|
||||
|
||||
|
||||
if (!perTick)
|
||||
{
|
||||
float updateAITotalTime = 0;
|
||||
@ -58,11 +60,17 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
if (map.first.find("PlayerbotAI::UpdateAIInternal") != std::string::npos)
|
||||
updateAITotalTime += map.second->totalTime;
|
||||
|
||||
LOG_INFO("playerbots", "--------------------------------------[TOTAL BOT]------------------------------------------------------");
|
||||
LOG_INFO("playerbots", "percentage time | min .. max ( avg of count) - type : name");
|
||||
LOG_INFO("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;
|
||||
|
||||
@ -99,10 +107,9 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
names.push_back(j->first);
|
||||
}
|
||||
|
||||
std::sort(names.begin(), names.end(), [pdMap](std::string const i, std::string const j)
|
||||
{
|
||||
return pdMap.at(i)->totalTime < pdMap.at(j)->totalTime;
|
||||
});
|
||||
std::sort(names.begin(), names.end(),
|
||||
[pdMap](std::string const i, std::string const j)
|
||||
{ return pdMap.at(i)->totalTime < pdMap.at(j)->totalTime; });
|
||||
|
||||
uint64 typeTotalTime = 0;
|
||||
uint64 typeMinTime = 0xffffffffu;
|
||||
@ -128,15 +135,9 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
|
||||
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} : {}"
|
||||
, perc
|
||||
, time
|
||||
, minTime
|
||||
, maxTime
|
||||
, avg
|
||||
, pd->count
|
||||
, key.c_str()
|
||||
, disName.c_str());
|
||||
LOG_INFO("playerbots",
|
||||
"{:7.3f}% {:10.3f}s | {:7.1f} .. {:7.1f} ({:10.3f} of {:10d}) - {:6} : {}", perc, time,
|
||||
minTime, maxTime, avg, pd->count, key.c_str(), disName.c_str());
|
||||
}
|
||||
}
|
||||
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 tMaxTime = (float)typeMaxTime / 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} : {}"
|
||||
, tPerc
|
||||
, tTime
|
||||
, tMinTime
|
||||
, tMaxTime
|
||||
, tAvg
|
||||
, typeCount
|
||||
, key.c_str()
|
||||
, "Total");
|
||||
LOG_INFO("playerbots", "{:7.3f}% {:10.3f}s | {:7.1f} .. {:7.1f} ({:10.3f} of {:10d}) - {:6} : {}", tPerc,
|
||||
tTime, tMinTime, tMaxTime, tAvg, typeCount, key.c_str(), "Total");
|
||||
LOG_INFO("playerbots", " ");
|
||||
}
|
||||
}
|
||||
@ -161,11 +155,17 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
float fullTickCount = data[PERF_MON_TOTAL]["RandomPlayerbotMgr::FullTick"]->count;
|
||||
float fullTickTotalTime = data[PERF_MON_TOTAL]["RandomPlayerbotMgr::FullTick"]->totalTime;
|
||||
|
||||
LOG_INFO("playerbots", "---------------------------------------[PER TICK]------------------------------------------------------");
|
||||
LOG_INFO("playerbots", "percentage time | min .. max ( avg of count) - type : name");
|
||||
LOG_INFO("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;
|
||||
|
||||
@ -198,10 +198,9 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
names.push_back(j->first);
|
||||
}
|
||||
|
||||
std::sort(names.begin(), names.end(), [pdMap](std::string const i, std::string const j)
|
||||
{
|
||||
return pdMap.at(i)->totalTime < pdMap.at(j)->totalTime;
|
||||
});
|
||||
std::sort(names.begin(), names.end(),
|
||||
[pdMap](std::string const i, std::string const j)
|
||||
{ return pdMap.at(i)->totalTime < pdMap.at(j)->totalTime; });
|
||||
|
||||
uint64 typeTotalTime = 0;
|
||||
uint64 typeMinTime = 0xffffffffu;
|
||||
@ -227,15 +226,9 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
disName = disName.substr(0, disName.find("|")) + "]";
|
||||
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} : {}"
|
||||
, perc
|
||||
, time
|
||||
, minTime
|
||||
, maxTime
|
||||
, avg
|
||||
, amount
|
||||
, key.c_str()
|
||||
, disName.c_str());
|
||||
LOG_INFO("playerbots",
|
||||
"{:7.3f}% {:9.3f}ms | {:7.1f} .. {:7.1f} ({:10.3f} of {:10.2f}) - {:6} : {}", perc,
|
||||
time, minTime, maxTime, avg, amount, key.c_str(), disName.c_str());
|
||||
}
|
||||
}
|
||||
if (PERF_MON_TOTAL != i->first)
|
||||
@ -246,15 +239,8 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
float tMaxTime = (float)typeMaxTime / 1000.0f;
|
||||
float tAvg = (float)typeTotalTime / (float)typeCount / 1000.0f;
|
||||
float tAmount = (float)typeCount / fullTickCount;
|
||||
LOG_INFO("playerbots", "{:7.3f}% {:9.3f}ms | {:7.1f} .. {:7.1f} ({:10.3f} of {:10.2f}) - {:6} : {}"
|
||||
, tPerc
|
||||
, tTime
|
||||
, tMinTime
|
||||
, tMaxTime
|
||||
, tAvg
|
||||
, tAmount
|
||||
, key.c_str()
|
||||
, "Total");
|
||||
LOG_INFO("playerbots", "{:7.3f}% {:9.3f}ms | {:7.1f} .. {:7.1f} ({:10.3f} of {:10.2f}) - {:6} : {}",
|
||||
tPerc, tTime, tMinTime, tMaxTime, tAvg, tAmount, key.c_str(), "Total");
|
||||
}
|
||||
LOG_INFO("playerbots", " ");
|
||||
}
|
||||
@ -263,7 +249,8 @@ void PerformanceMonitor::PrintStats(bool perTick, bool fullStack)
|
||||
|
||||
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;
|
||||
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()
|
||||
{
|
||||
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();
|
||||
|
||||
std::lock_guard<std::mutex> guard(data->lock);
|
||||
@ -309,4 +301,3 @@ void PerformanceMonitorOperation::finish()
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PERFORMANCEMONITOR_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
typedef std::vector<std::string> PerformanceStack;
|
||||
|
||||
struct PerformanceData
|
||||
@ -58,7 +59,8 @@ class PerformanceMonitor
|
||||
}
|
||||
|
||||
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 Reset();
|
||||
|
||||
|
||||
@ -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 "AiFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Util.h"
|
||||
|
||||
void PlaceholderHelper::MapDungeon(
|
||||
PlaceholderMap& placeholders,
|
||||
DungeonSuggestion const* dungeonSuggestion,
|
||||
Player* bot
|
||||
)
|
||||
void PlaceholderHelper::MapDungeon(PlaceholderMap& placeholders, DungeonSuggestion const* dungeonSuggestion,
|
||||
Player* bot)
|
||||
{
|
||||
std::ostringstream out;
|
||||
Insertion insertion = {out, dungeonSuggestion};
|
||||
@ -23,7 +22,6 @@ void PlaceholderHelper::MapDungeon(
|
||||
placeholders["%dungeon"] = out.str();
|
||||
}
|
||||
|
||||
|
||||
void PlaceholderHelper::MapRole(PlaceholderMap& placeholders, Player* bot)
|
||||
{
|
||||
BotRoles const role = AiFactory::GetPlayerRoles(bot);
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PLACEHOLDERHELPER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerbotDungeonSuggestionMgr.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
typedef std::map<std::string, std::string> PlaceholderMap;
|
||||
|
||||
class PlaceholderHelper
|
||||
{
|
||||
public:
|
||||
static void MapRole(PlaceholderMap& placeholders, Player* bot);
|
||||
static void MapDungeon(
|
||||
PlaceholderMap& placeholders,
|
||||
DungeonSuggestion const* dungeonSuggestion,
|
||||
Player* bot
|
||||
);
|
||||
static void MapDungeon(PlaceholderMap& placeholders, DungeonSuggestion const* dungeonSuggestion, Player* bot);
|
||||
|
||||
private:
|
||||
struct Insertion
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
#define _PLAYERBOT_PLAYERbotAI_H
|
||||
|
||||
#include <queue>
|
||||
#include <stack>
|
||||
|
||||
#include "Chat.h"
|
||||
#include "ChatHelper.h"
|
||||
#include "ChatFilter.h"
|
||||
#include "ChatHelper.h"
|
||||
#include "Common.h"
|
||||
#include "Event.h"
|
||||
#include "Item.h"
|
||||
#include "PlayerbotAIBase.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "PlayerbotSecurity.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "PlayerbotTextMgr.h"
|
||||
|
||||
#include <stack>
|
||||
#include <queue>
|
||||
|
||||
class AiObjectContext;
|
||||
class Creature;
|
||||
@ -120,7 +121,8 @@ enum SharpeningStoneDisplayId
|
||||
HEAVY_SHARPENING_DISPLAYID = 24675,
|
||||
SOLID_SHARPENING_DISPLAYID = 24676,
|
||||
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,
|
||||
FEL_SHARPENING_DISPLAYID = 39192,
|
||||
ADAMANTITE_SHARPENING_DISPLAYID = 39193
|
||||
@ -210,61 +212,71 @@ enum BotRoles : uint8
|
||||
BOT_ROLE_DPS = 0x04
|
||||
};
|
||||
|
||||
enum HUNTER_TABS {
|
||||
enum HUNTER_TABS
|
||||
{
|
||||
HUNTER_TAB_BEASTMASTER,
|
||||
HUNTER_TAB_MARKSMANSHIP,
|
||||
HUNTER_TAB_SURVIVAL,
|
||||
};
|
||||
|
||||
enum ROGUE_TABS {
|
||||
enum ROGUE_TABS
|
||||
{
|
||||
ROGUE_TAB_ASSASSINATION,
|
||||
ROGUE_TAB_COMBAT,
|
||||
ROGUE_TAB_SUBTLETY
|
||||
};
|
||||
|
||||
enum PRIEST_TABS {
|
||||
enum PRIEST_TABS
|
||||
{
|
||||
PRIEST_TAB_DISIPLINE,
|
||||
PRIEST_TAB_HOLY,
|
||||
PRIEST_TAB_SHADOW,
|
||||
};
|
||||
|
||||
enum DEATHKNIGT_TABS {
|
||||
enum DEATHKNIGT_TABS
|
||||
{
|
||||
DEATHKNIGT_TAB_BLOOD,
|
||||
DEATHKNIGT_TAB_FROST,
|
||||
DEATHKNIGT_TAB_UNHOLY,
|
||||
};
|
||||
|
||||
enum DRUID_TABS {
|
||||
enum DRUID_TABS
|
||||
{
|
||||
DRUID_TAB_BALANCE,
|
||||
DRUID_TAB_FERAL,
|
||||
DRUID_TAB_RESTORATION,
|
||||
};
|
||||
|
||||
enum MAGE_TABS {
|
||||
enum MAGE_TABS
|
||||
{
|
||||
MAGE_TAB_ARCANE,
|
||||
MAGE_TAB_FIRE,
|
||||
MAGE_TAB_FROST,
|
||||
};
|
||||
|
||||
enum SHAMAN_TABS {
|
||||
enum SHAMAN_TABS
|
||||
{
|
||||
SHAMAN_TAB_ELEMENTAL,
|
||||
SHAMAN_TAB_ENHANCEMENT,
|
||||
SHAMAN_TAB_RESTORATION,
|
||||
};
|
||||
|
||||
enum PALADIN_TABS {
|
||||
enum PALADIN_TABS
|
||||
{
|
||||
PALADIN_TAB_HOLY,
|
||||
PALADIN_TAB_PROTECTION,
|
||||
PALADIN_TAB_RETRIBUTION,
|
||||
};
|
||||
|
||||
enum WARLOCK_TABS {
|
||||
enum WARLOCK_TABS
|
||||
{
|
||||
WARLOCK_TAB_AFFLICATION,
|
||||
WARLOCK_TAB_DEMONOLOGY,
|
||||
WARLOCK_TAB_DESTRUCTION,
|
||||
};
|
||||
|
||||
enum WARRIOR_TABS {
|
||||
enum WARRIOR_TABS
|
||||
{
|
||||
WARRIOR_TAB_ARMS,
|
||||
WARRIOR_TAB_FURY,
|
||||
WARRIOR_TAB_PROTECTION,
|
||||
@ -285,8 +297,15 @@ class PacketHandlingHelper
|
||||
class ChatCommandHolder
|
||||
{
|
||||
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(ChatCommandHolder const& other) : command(other.command), owner(other.owner), type(other.type), time(other.time) { }
|
||||
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(ChatCommandHolder const& other)
|
||||
: command(other.command), owner(other.owner), type(other.type), time(other.time)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const GetCommand() { return command; }
|
||||
Player* GetOwner() { return owner; }
|
||||
@ -312,14 +331,16 @@ class PlayerbotAI : public PlayerbotAIBase
|
||||
|
||||
std::string const HandleRemoteCommand(std::string const command);
|
||||
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 HandleMasterIncomingPacket(WorldPacket const& packet);
|
||||
void HandleMasterOutgoingPacket(WorldPacket const& packet);
|
||||
void HandleTeleportAck();
|
||||
void ChangeEngine(BotState type);
|
||||
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 ClearStrategies(BotState type);
|
||||
std::vector<std::string> GetStrategies(BotState type);
|
||||
@ -358,8 +379,10 @@ class PlayerbotAI : public PlayerbotAIBase
|
||||
WorldObject* GetWorldObject(ObjectGuid guid);
|
||||
bool TellMaster(std::ostringstream& stream, 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::string const text, PlayerbotSecurityLevel securityLevel = PLAYERBOT_SECURITY_ALLOW_ALL);
|
||||
bool TellMasterNoFacing(std::ostringstream& stream,
|
||||
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);
|
||||
void SpellInterrupted(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 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 IsInterruptableSpellCasting(Unit* player, std::string const spell);
|
||||
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, 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);
|
||||
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, float x, float y, float z, Item* itemTarget = nullptr);
|
||||
bool canDispel(SpellInfo const* spellInfo, uint32 dispelType);
|
||||
@ -402,7 +429,8 @@ class PlayerbotAI : public PlayerbotAIBase
|
||||
bool CanCastVehicleSpell(uint32 spellid, Unit* target);
|
||||
bool CastVehicleSpell(uint32 spellId, Unit* target);
|
||||
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);
|
||||
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 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; }
|
||||
void SetCheat(BotCheatMask mask) { cheatMask = mask; }
|
||||
|
||||
@ -454,9 +486,12 @@ class PlayerbotAI : public PlayerbotAIBase
|
||||
bool EqualLowercaseName(std::string s1, std::string s2);
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
protected:
|
||||
Player* bot;
|
||||
Player* master;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 "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)
|
||||
{
|
||||
@ -42,10 +42,7 @@ void PlayerbotAIBase::IncreaseNextCheckDelay(uint32 delay)
|
||||
// LOG_DEBUG("playerbots", "increase next check delay: {}", nextAICheckDelay);
|
||||
}
|
||||
|
||||
bool PlayerbotAIBase::CanUpdateAI()
|
||||
{
|
||||
return nextAICheckDelay == 0;
|
||||
}
|
||||
bool PlayerbotAIBase::CanUpdateAI() { return nextAICheckDelay == 0; }
|
||||
|
||||
void PlayerbotAIBase::YieldThread(bool delay)
|
||||
{
|
||||
@ -53,12 +50,6 @@ void PlayerbotAIBase::YieldThread(bool delay)
|
||||
nextAICheckDelay = delay ? sPlayerbotAIConfig->reactDelay * 10 : sPlayerbotAIConfig->reactDelay;
|
||||
}
|
||||
|
||||
bool PlayerbotAIBase::IsActive()
|
||||
{
|
||||
return nextAICheckDelay < sPlayerbotAIConfig->maxWaitForMove;
|
||||
}
|
||||
bool PlayerbotAIBase::IsActive() { return nextAICheckDelay < sPlayerbotAIConfig->maxWaitForMove; }
|
||||
|
||||
bool PlayerbotAIBase::IsBotAI() const
|
||||
{
|
||||
return _isBotAI;
|
||||
}
|
||||
bool PlayerbotAIBase::IsBotAI() const { return _isBotAI; }
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 <iostream>
|
||||
|
||||
#include "Config.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotDungeonSuggestionMgr.h"
|
||||
#include "PlayerbotFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "RandomItemMgr.h"
|
||||
#include "RandomPlayerbotFactory.h"
|
||||
#include "Talentspec.h"
|
||||
#include "PlayerbotDungeonSuggestionMgr.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <class T>
|
||||
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");
|
||||
LoadList<std::vector<uint32>>(randomBotMapsAsString, randomBotMaps);
|
||||
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>>(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.RandomBotQuestItems",
|
||||
"6948,5175,5176,5177,5178,16309,12382,13704,11000"),
|
||||
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);
|
||||
randomBotAutologin = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutologin", true);
|
||||
minRandomBots = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBots", 50);
|
||||
maxRandomBots = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBots", 200);
|
||||
randomBotUpdateInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotUpdateInterval", MINUTE);
|
||||
randomBotCountChangeMinInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotCountChangeMinInterval", 30 * MINUTE);
|
||||
randomBotCountChangeMaxInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotCountChangeMaxInterval", 2 * HOUR);
|
||||
randomBotCountChangeMinInterval =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotCountChangeMinInterval", 30 * MINUTE);
|
||||
randomBotCountChangeMaxInterval =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotCountChangeMaxInterval", 2 * HOUR);
|
||||
minRandomBotInWorldTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotInWorldTime", 2 * HOUR);
|
||||
maxRandomBotInWorldTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotInWorldTime", 12 * HOUR);
|
||||
minRandomBotRandomizeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotRandomizeTime", 2 * HOUR);
|
||||
maxRandomBotRandomizeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotRandomizeTime", 14 * 24 * HOUR);
|
||||
minRandomBotChangeStrategyTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotChangeStrategyTime", 30 * MINUTE);
|
||||
maxRandomBotChangeStrategyTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotChangeStrategyTime", 2 * HOUR);
|
||||
minRandomBotChangeStrategyTime =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotChangeStrategyTime", 30 * MINUTE);
|
||||
maxRandomBotChangeStrategyTime =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotChangeStrategyTime", 2 * HOUR);
|
||||
minRandomBotReviveTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotReviveTime", MINUTE);
|
||||
maxRandomBotReviveTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotReviveTime", 5 * MINUTE);
|
||||
minRandomBotTeleportInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotTeleportInterval", 1 * 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);
|
||||
randomBotsPerInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotsPerInterval", MINUTE);
|
||||
minRandomBotsPriceChangeInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotsPriceChangeInterval", 2 * HOUR);
|
||||
maxRandomBotsPriceChangeInterval = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR);
|
||||
minRandomBotsPriceChangeInterval =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.MinRandomBotsPriceChangeInterval", 2 * HOUR);
|
||||
maxRandomBotsPriceChangeInterval =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR);
|
||||
randomBotJoinLfg = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinLfg", true);
|
||||
randomBotTalk = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotTalk", false);
|
||||
randomBotEmote = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotEmote", false);
|
||||
randomBotSuggestDungeons = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotSuggestDungeons", true);
|
||||
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);
|
||||
randomBotAutoJoinBG = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotAutoJoinBG", false);
|
||||
randomBotAutoJoinWarsongBracket = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinWarsongBracket", 14);
|
||||
randomBotAutoJoinArenaBracket = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinArenaBracket", 7);
|
||||
randomBotAutoJoinBGWarsongCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGWarsongCount", 0);
|
||||
randomBotAutoJoinBGRatedArena2v2Count = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena2v2Count", 0);
|
||||
randomBotAutoJoinBGRatedArena3v3Count = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena3v3Count", 0);
|
||||
randomBotAutoJoinBGRatedArena5v5Count = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena5v5Count", 0);
|
||||
randomBotAutoJoinBGRatedArena2v2Count =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena2v2Count", 0);
|
||||
randomBotAutoJoinBGRatedArena3v3Count =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena3v3Count", 0);
|
||||
randomBotAutoJoinBGRatedArena5v5Count =
|
||||
sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAutoJoinBGRatedArena5v5Count", 0);
|
||||
logInGroupOnly = sConfigMgr->GetOption<bool>("AiPlayerbot.LogInGroupOnly", true);
|
||||
logValuesPerTick = sConfigMgr->GetOption<bool>("AiPlayerbot.LogValuesPerTick", false);
|
||||
fleeingEnabled = sConfigMgr->GetOption<bool>("AiPlayerbot.FleeingEnabled", true);
|
||||
@ -183,7 +207,8 @@ bool PlayerbotAIConfig::Initialize()
|
||||
|
||||
for (uint32 cls = 1; cls < MAX_CLASSES; ++cls)
|
||||
{
|
||||
if (cls == 10) {
|
||||
if (cls == 10)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (uint32 spec = 0; spec < MAX_SPECNO; ++spec)
|
||||
@ -196,12 +221,15 @@ bool PlayerbotAIConfig::Initialize()
|
||||
os << "AiPlayerbot.PremadeSpecGlyph." << cls << "." << spec;
|
||||
premadeSpecGlyph[cls][spec] = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
|
||||
std::vector<std::string> splitSpecGlyph = split(premadeSpecGlyph[cls][spec], ',');
|
||||
for (std::string &split : splitSpecGlyph) {
|
||||
if (split.size() != 0) {
|
||||
for (std::string& split : splitSpecGlyph)
|
||||
{
|
||||
if (split.size() != 0)
|
||||
{
|
||||
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;
|
||||
os << "AiPlayerbot.PremadeSpecLink." << cls << "." << spec << "." << level;
|
||||
premadeSpecLink[cls][spec][level] = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
|
||||
@ -221,7 +249,8 @@ bool PlayerbotAIConfig::Initialize()
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -236,7 +265,8 @@ bool PlayerbotAIConfig::Initialize()
|
||||
if (std::find(botCheats.begin(), botCheats.end(), "power") != botCheats.end())
|
||||
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();
|
||||
|
||||
@ -264,7 +294,8 @@ bool PlayerbotAIConfig::Initialize()
|
||||
minGuildTaskChangeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MinGuildTaskChangeTime", 3 * 24 * 3600);
|
||||
maxGuildTaskChangeTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxGuildTaskChangeTime", 4 * 24 * 3600);
|
||||
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);
|
||||
maxGuildTaskRewardTime = sConfigMgr->GetOption<int32>("AiPlayerbot.MaxGuildTaskRewardTime", 3600);
|
||||
guildTaskAdvertCleanupTime = sConfigMgr->GetOption<int32>("AiPlayerbot.GuildTaskAdvertCleanupTime", 300);
|
||||
@ -352,7 +383,8 @@ bool PlayerbotAIConfig::Initialize()
|
||||
selfBotLevel = sConfigMgr->GetOption<int32>("AiPlayerbot.SelfBotLevel", 1);
|
||||
|
||||
RandomPlayerbotFactory::CreateRandomBots();
|
||||
if (World::IsStopped()) {
|
||||
if (World::IsStopped())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
PlayerbotFactory::Init();
|
||||
@ -418,7 +450,8 @@ std::string const PlayerbotAIConfig::GetTimestampStr()
|
||||
// MM minutes (2 digits 00-59)
|
||||
// SS seconds (2 digits 00-59)
|
||||
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);
|
||||
}
|
||||
|
||||
@ -447,7 +480,6 @@ bool PlayerbotAIConfig::openLog(std::string const fileName, char const* mode)
|
||||
m_logsDir.append("/");
|
||||
}
|
||||
|
||||
|
||||
file = fopen((m_logsDir + fileName).c_str(), mode);
|
||||
fileOpen = true;
|
||||
|
||||
@ -572,7 +604,8 @@ static std::vector<std::string> split(const std::string &str, const std::string
|
||||
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
|
||||
uint32 classMask = 1 << (cls - 1);
|
||||
std::vector<std::vector<uint32>> res;
|
||||
@ -594,27 +627,31 @@ std::vector<std::vector<uint32>> PlayerbotAIConfig::ParseTempTalentsOrder(uint32
|
||||
|
||||
spells[talentTabInfo->tabpage].push_back(talentInfo);
|
||||
}
|
||||
for (int tab = 0; tab < 3; tab++) {
|
||||
if (tab_links.size() <= tab) {
|
||||
for (int tab = 0; tab < 3; tab++)
|
||||
{
|
||||
if (tab_links.size() <= tab)
|
||||
{
|
||||
break;
|
||||
}
|
||||
std::sort(spells[tab].begin(), spells[tab].end(), [&](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++) {
|
||||
if (i >= spells[tab].size()) {
|
||||
std::sort(spells[tab].begin(), spells[tab].end(),
|
||||
[&](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++)
|
||||
{
|
||||
if (i >= spells[tab].size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
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});
|
||||
}
|
||||
}
|
||||
// sort by talent tab size
|
||||
std::sort(orders.begin(), orders.end(), [&](auto &lhs, auto &rhs) {
|
||||
return lhs.size() > rhs.size();
|
||||
});
|
||||
for (auto &order : orders) {
|
||||
std::sort(orders.begin(), orders.end(), [&](auto& lhs, auto& rhs) { return lhs.size() > rhs.size(); });
|
||||
for (auto& order : orders)
|
||||
{
|
||||
res.insert(res.end(), order.begin(), order.end());
|
||||
}
|
||||
return res;
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PLAYERbotAICONFIG_H
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "Common.h"
|
||||
#include "DBCEnums.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Talentspec.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
enum class BotCheatMask : uint32
|
||||
{
|
||||
none = 0,
|
||||
@ -54,12 +55,11 @@ class PlayerbotAIConfig
|
||||
|
||||
bool enabled;
|
||||
bool allowGuildBots, allowPlayerBots;
|
||||
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime,
|
||||
expireActionTime, dispelAuraDuration, passiveDelay, repeatDelay,
|
||||
errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
|
||||
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance,
|
||||
fleeDistance, tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance,
|
||||
aoeRadius, rpgDistance, targetPosRecalcDistance, farDistance, healDistance, aggroDistance;
|
||||
uint32 globalCoolDown, reactDelay, maxWaitForMove, disableMoveSplinePath, maxMovementSearchTime, expireActionTime,
|
||||
dispelAuraDuration, passiveDelay, repeatDelay, errorDelay, rpgDelay, sitDelay, returnDelay, lootDelay;
|
||||
float sightDistance, spellDistance, reactDistance, grindDistance, lootDistance, shootDistance, fleeDistance,
|
||||
tooCloseDistance, meleeDistance, followDistance, whisperDistance, contactDistance, aoeRadius, rpgDistance,
|
||||
targetPosRecalcDistance, farDistance, healDistance, aggroDistance;
|
||||
uint32 criticalHealth, lowHealth, mediumHealth, almostFullHealth;
|
||||
uint32 lowMana, mediumMana;
|
||||
bool autoSaveMana;
|
||||
@ -118,7 +118,6 @@ class PlayerbotAIConfig
|
||||
uint32 randomBotMinLevel, randomBotMaxLevel;
|
||||
float randomChangeMultiplier;
|
||||
|
||||
|
||||
// std::string premadeLevelSpec[MAX_CLASSES][10][91]; //lvl 10 - 100
|
||||
// ClassSpecs classSpecs[MAX_CLASSES];
|
||||
|
||||
@ -244,9 +243,16 @@ class PlayerbotAIConfig
|
||||
int32 autoGearCommand, autoGearQualityLimit, autoGearScoreLimit;
|
||||
|
||||
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 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 loadWorldBuf(uint32 factionId, uint32 classId, uint32 minLevel, uint32 maxLevel);
|
||||
|
||||
@ -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 "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 <iostream>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/smart_ptr.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include "IoContext.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
typedef boost::shared_ptr<tcp::socket> socket_ptr;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
void PlayerbotDbStore::Load(PlayerbotAI* botAI)
|
||||
{
|
||||
ObjectGuid::LowType guid = botAI->GetBot()->GetGUID().GetCounter();
|
||||
@ -35,8 +37,7 @@ void PlayerbotDbStore::Load(PlayerbotAI* botAI)
|
||||
botAI->ChangeStrategy(value, BOT_STATE_NON_COMBAT);
|
||||
else if (key == "dead")
|
||||
botAI->ChangeStrategy(value, BOT_STATE_DEAD);
|
||||
}
|
||||
while (result->NextRow());
|
||||
} while (result->NextRow());
|
||||
|
||||
botAI->GetAiObjectContext()->Load(values);
|
||||
}
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PLAYERBOTDBSTORE_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class PlayerbotDbStore
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
|
||||
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 strategy = fields[5].Get<std::string>();
|
||||
|
||||
DungeonSuggestion const row =
|
||||
{
|
||||
name,
|
||||
static_cast<Difficulty>(difficulty),
|
||||
min_level,
|
||||
max_level,
|
||||
abbrevation,
|
||||
strategy
|
||||
};
|
||||
DungeonSuggestion const row = {
|
||||
name, static_cast<Difficulty>(difficulty), min_level, max_level, abbrevation, strategy};
|
||||
|
||||
m_dungeonSuggestions.push_back(row);
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
LOG_INFO("server.loading", "{} playerbots dungeon suggestions loaded in {} ms",
|
||||
count, GetMSTimeDiffToNow(oldMSTime));
|
||||
LOG_INFO("server.loading", "{} playerbots dungeon suggestions loaded in {} ms", count,
|
||||
GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PLAYERBOTDUNGEONSUGGESTIONMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "DBCEnums.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
#include "DBCEnums.h"
|
||||
|
||||
struct DungeonSuggestion
|
||||
{
|
||||
std::string name;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -137,6 +138,7 @@ class PlayerbotFactory
|
||||
void ApplyEnchantAndGemsNew(bool destoryOld = true);
|
||||
void InitInstanceQuests();
|
||||
void UnbindInstance();
|
||||
|
||||
private:
|
||||
void Prepare();
|
||||
// void InitSecondEquipmentSet();
|
||||
@ -194,6 +196,7 @@ class PlayerbotFactory
|
||||
std::vector<uint32> trainerIdCache;
|
||||
static std::vector<uint32> enchantSpellIdCache;
|
||||
static std::vector<uint32> enchantGemIdCache;
|
||||
|
||||
protected:
|
||||
EnchantContainer m_EnchantContainer;
|
||||
Player* bot;
|
||||
|
||||
@ -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 "CharacterPackets.h"
|
||||
#include "Common.h"
|
||||
@ -11,22 +20,14 @@
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "PlayerbotMgr.h"
|
||||
#include "PlayerbotSecurity.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotDbStore.h"
|
||||
#include "PlayerbotFactory.h"
|
||||
#include "PlayerbotSecurity.h"
|
||||
#include "Playerbots.h"
|
||||
#include "SharedDefines.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
|
||||
{
|
||||
@ -36,7 +37,9 @@ class PlayerbotLoginQueryHolder : public LoginQueryHolder
|
||||
|
||||
public:
|
||||
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; }
|
||||
PlayerbotHolder* GetPlayerbotHolder() { return playerbotHolder; }
|
||||
@ -53,7 +56,8 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
|
||||
if (!accountId)
|
||||
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())
|
||||
{
|
||||
return;
|
||||
@ -61,17 +65,15 @@ void PlayerbotHolder::AddPlayerBot(ObjectGuid playerGuid, uint32 masterAccountId
|
||||
|
||||
if (WorldSession* masterSession = sWorld->FindSession(masterAccountId))
|
||||
{
|
||||
masterSession->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
|
||||
{
|
||||
HandlePlayerBotLoginCallback(static_cast<PlayerbotLoginQueryHolder const&>(holder));
|
||||
});
|
||||
masterSession->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder))
|
||||
.AfterComplete([this](SQLQueryHolderBase const& holder)
|
||||
{ HandlePlayerBotLoginCallback(static_cast<PlayerbotLoginQueryHolder const&>(holder)); });
|
||||
}
|
||||
else
|
||||
{
|
||||
sWorld->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder)).AfterComplete([this](SQLQueryHolderBase const& holder)
|
||||
{
|
||||
HandlePlayerBotLoginCallback(static_cast<PlayerbotLoginQueryHolder const&>(holder));
|
||||
});
|
||||
sWorld->AddQueryHolderCallback(CharacterDatabase.DelayQueryHolder(holder))
|
||||
.AfterComplete([this](SQLQueryHolderBase const& holder)
|
||||
{ HandlePlayerBotLoginCallback(static_cast<PlayerbotLoginQueryHolder const&>(holder)); });
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,14 +81,17 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
|
||||
{
|
||||
// has bot already been added?
|
||||
Player* loginBot = ObjectAccessor::FindConnectedPlayer(holder.GetGuid());
|
||||
if (loginBot && loginBot->IsInWorld()) {
|
||||
if (loginBot && loginBot->IsInWorld())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
WorldSession* botSession = new WorldSession(botAccountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING, time_t(0), sWorld->GetDefaultDbcLocale(), 0, false, false, 0, true);
|
||||
// At login DBC locale should be what the server is set to use by default (as spells etc are hardcoded to ENUS this
|
||||
// allows channels to work as intended)
|
||||
WorldSession* botSession = new WorldSession(botAccountId, "", nullptr, SEC_PLAYER, EXPANSION_WRATH_OF_THE_LICH_KING,
|
||||
time_t(0), sWorld->GetDefaultDbcLocale(), 0, false, false, 0, true);
|
||||
|
||||
botSession->HandlePlayerLoginFromDB(holder); // will delete lqh
|
||||
|
||||
@ -95,7 +100,8 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
|
||||
{
|
||||
botSession->LogoutPlayer(true);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -103,25 +109,37 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
|
||||
WorldSession* masterSession = masterAccount ? sWorld->FindSession(masterAccount) : nullptr;
|
||||
std::ostringstream out;
|
||||
bool allowed = false;
|
||||
if (botAccountId == masterAccount) {
|
||||
if (botAccountId == masterAccount)
|
||||
{
|
||||
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;
|
||||
} else if (sPlayerbotAIConfig->IsInRandomAccountList(botAccountId)) {
|
||||
}
|
||||
else if (sPlayerbotAIConfig->IsInRandomAccountList(botAccountId))
|
||||
{
|
||||
allowed = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
allowed = false;
|
||||
out << "Failure: You are not allowed to control bot " << bot->GetName().c_str();
|
||||
}
|
||||
if (allowed && masterSession) {
|
||||
if (allowed && masterSession)
|
||||
{
|
||||
Player* player = masterSession->GetPlayer();
|
||||
PlayerbotMgr* mgr = GET_PLAYERBOT_MGR(player);
|
||||
uint32 count = mgr->GetPlayerbotsCount();
|
||||
uint32 cls_count = mgr->GetPlayerbotsCountByClass(bot->getClass());
|
||||
if (count >= sPlayerbotAIConfig->maxAddedBots) {
|
||||
if (count >= sPlayerbotAIConfig->maxAddedBots)
|
||||
{
|
||||
allowed = false;
|
||||
out << "Failure: You have added too many bots";
|
||||
} else if (cls_count >= sPlayerbotAIConfig->maxAddedBotsPerClass) {
|
||||
}
|
||||
else if (cls_count >= sPlayerbotAIConfig->maxAddedBotsPerClass)
|
||||
{
|
||||
allowed = false;
|
||||
out << "Failure: You have added too many bots for this class";
|
||||
}
|
||||
@ -143,7 +161,8 @@ void PlayerbotHolder::HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder con
|
||||
// OnBotLogin(bot);
|
||||
// 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())
|
||||
{
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (botAI) {
|
||||
if (botAI)
|
||||
{
|
||||
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;
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
@ -289,8 +310,10 @@ void PlayerbotHolder::LogoutPlayerBot(ObjectGuid guid)
|
||||
logout = true;
|
||||
}
|
||||
|
||||
if (master && (master->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || master->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
|
||||
(masterWorldSessionPtr && masterWorldSessionPtr->GetSecurity() >= (AccountTypes)sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))))
|
||||
if (master &&
|
||||
(master->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || master->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
|
||||
(masterWorldSessionPtr &&
|
||||
masterWorldSessionPtr->GetSecurity() >= (AccountTypes)sWorld->getIntConfig(CONFIG_INSTANT_LOGOUT))))
|
||||
{
|
||||
logout = true;
|
||||
}
|
||||
@ -347,7 +370,8 @@ void PlayerbotHolder::DisablePlayerBot(ObjectGuid guid)
|
||||
if (Player* bot = GetPlayerBot(guid))
|
||||
{
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
botAI->TellMaster("Goodbye!");
|
||||
@ -393,7 +417,8 @@ Player* PlayerbotHolder::GetPlayerBot(ObjectGuid::LowType lowGuid) const
|
||||
void PlayerbotHolder::OnBotLogin(Player* const bot)
|
||||
{
|
||||
// Prevent duplicate login
|
||||
if (playerBots.find(bot->GetGUID()) != playerBots.end()) {
|
||||
if (playerBots.find(bot->GetGUID()) != playerBots.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@ -401,9 +426,9 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
||||
playerBots[bot->GetGUID()] = bot;
|
||||
OnBotLoginInternal(bot);
|
||||
|
||||
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Player* master = botAI->GetMaster();
|
||||
@ -475,19 +500,27 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
||||
|
||||
botAI->TellMaster("Hello!", PLAYERBOT_SECURITY_TALK);
|
||||
|
||||
if (master && master->GetGroup() && !group) {
|
||||
if (master && master->GetGroup() && !group)
|
||||
{
|
||||
Group* mgroup = master->GetGroup();
|
||||
if (mgroup->GetMembersCount() >= 5) {
|
||||
if (!mgroup->isRaidGroup() && !mgroup->isLFGGroup() && !mgroup->isBGGroup() && !mgroup->isBFGroup()) {
|
||||
if (mgroup->GetMembersCount() >= 5)
|
||||
{
|
||||
if (!mgroup->isRaidGroup() && !mgroup->isLFGGroup() && !mgroup->isBGGroup() && !mgroup->isBFGroup())
|
||||
{
|
||||
mgroup->ConvertToRaid();
|
||||
}
|
||||
if (mgroup->isRaidGroup()) {
|
||||
if (mgroup->isRaidGroup())
|
||||
{
|
||||
mgroup->AddMember(bot);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
mgroup->AddMember(bot);
|
||||
}
|
||||
} else if (master && !group) {
|
||||
}
|
||||
else if (master && !group)
|
||||
{
|
||||
Group* newGroup = new Group();
|
||||
newGroup->Create(master);
|
||||
sGroupMgr->AddGroup(newGroup);
|
||||
@ -497,23 +530,29 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
||||
uint32 accountId = bot->GetSession()->GetAccountId();
|
||||
bool isRandomAccount = sPlayerbotAIConfig->IsInRandomAccountList(accountId);
|
||||
|
||||
if (isRandomAccount && sPlayerbotAIConfig->randomBotFixedLevel) {
|
||||
if (isRandomAccount && sPlayerbotAIConfig->randomBotFixedLevel)
|
||||
{
|
||||
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->SaveToDB(false, false);
|
||||
if (master && isRandomAccount && master->GetLevel() < bot->GetLevel()) {
|
||||
if (master && isRandomAccount && master->GetLevel() < bot->GetLevel())
|
||||
{
|
||||
// PlayerbotFactory factory(bot, master->GetLevel());
|
||||
// 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);
|
||||
factory.Randomize(false);
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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)
|
||||
{
|
||||
ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i);
|
||||
if (!channel) continue;
|
||||
if (!channel)
|
||||
continue;
|
||||
|
||||
bool isLfg = (channel->flags & CHANNEL_DBC_FLAG_LFG) != 0;
|
||||
|
||||
@ -551,7 +591,8 @@ void PlayerbotHolder::OnBotLogin(Player* const bot)
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
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())
|
||||
return "bot system is disabled";
|
||||
@ -573,7 +615,8 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
|
||||
if (!isRandomAccount && !isMasterAccount && !admin && 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";
|
||||
}
|
||||
|
||||
@ -609,21 +652,27 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
|
||||
if (!bot)
|
||||
return "bot not found";
|
||||
|
||||
if (!isRandomAccount || isRandomBot) {
|
||||
if (!isRandomAccount || isRandomBot)
|
||||
{
|
||||
return "ERROR: You can not use this command on non-summoned random bot.";
|
||||
}
|
||||
|
||||
if (!admin) {
|
||||
if (!admin)
|
||||
{
|
||||
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.";
|
||||
}
|
||||
}
|
||||
|
||||
if (GET_PLAYERBOT_AI(bot)) {
|
||||
if (GET_PLAYERBOT_AI(bot))
|
||||
{
|
||||
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.";
|
||||
}
|
||||
int gs;
|
||||
@ -659,10 +708,12 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
|
||||
}
|
||||
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);
|
||||
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)
|
||||
{
|
||||
@ -698,7 +749,8 @@ std::string const PlayerbotHolder::ProcessBotCommand(std::string const cmd, Obje
|
||||
sRandomPlayerbotMgr->Randomize(bot);
|
||||
return "ok";
|
||||
}
|
||||
else if (cmd == "quests"){
|
||||
else if (cmd == "quests")
|
||||
{
|
||||
PlayerbotFactory factory(bot, bot->GetLevel());
|
||||
factory.InitInstanceQuests();
|
||||
return "Initialization quests";
|
||||
@ -762,53 +814,70 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
return messages;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd, "initself")) {
|
||||
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) {
|
||||
if (!strcmp(cmd, "initself"))
|
||||
{
|
||||
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
|
||||
{
|
||||
// OnBotLogin(master);
|
||||
PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_EPIC);
|
||||
factory.Randomize(false);
|
||||
messages.push_back("initself ok");
|
||||
return messages;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
messages.push_back("ERROR: Only GM can use this command.");
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp(cmd, "initself=", 9)) {
|
||||
if (!strcmp(cmd, "initself=rare")) {
|
||||
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) {
|
||||
if (!strncmp(cmd, "initself=", 9))
|
||||
{
|
||||
if (!strcmp(cmd, "initself=rare"))
|
||||
{
|
||||
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
|
||||
{
|
||||
// OnBotLogin(master);
|
||||
PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_RARE);
|
||||
factory.Randomize(false);
|
||||
messages.push_back("initself ok");
|
||||
return messages;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
messages.push_back("ERROR: Only GM can use this command.");
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
if (!strcmp(cmd, "initself=epic")) {
|
||||
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) {
|
||||
if (!strcmp(cmd, "initself=epic"))
|
||||
{
|
||||
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
|
||||
{
|
||||
// OnBotLogin(master);
|
||||
PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_EPIC);
|
||||
factory.Randomize(false);
|
||||
messages.push_back("initself ok");
|
||||
return messages;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
messages.push_back("ERROR: Only GM can use this command.");
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
int32 gs;
|
||||
if (sscanf(cmd, "initself=%d", &gs) != -1) {
|
||||
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER) {
|
||||
if (sscanf(cmd, "initself=%d", &gs) != -1)
|
||||
{
|
||||
if (master->GetSession()->GetSecurity() >= SEC_GAMEMASTER)
|
||||
{
|
||||
// OnBotLogin(master);
|
||||
PlayerbotFactory factory(master, master->GetLevel(), ITEM_QUALITY_LEGENDARY, gs);
|
||||
factory.Randomize(false);
|
||||
messages.push_back("initself ok, gs = " + std::to_string(gs));
|
||||
return messages;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
messages.push_back("ERROR: Only GM can use this command.");
|
||||
return messages;
|
||||
}
|
||||
@ -867,12 +936,15 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
|
||||
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");
|
||||
return messages;
|
||||
}
|
||||
if (!charname) {
|
||||
messages.push_back("addclass: invalid CLASSNAME(warrior/paladin/hunter/rogue/priest/shaman/mage/warlock/druid/dk)");
|
||||
if (!charname)
|
||||
{
|
||||
messages.push_back(
|
||||
"addclass: invalid CLASSNAME(warrior/paladin/hunter/rogue/priest/shaman/mage/warlock/druid/dk)");
|
||||
return messages;
|
||||
}
|
||||
uint8 claz;
|
||||
@ -942,10 +1014,13 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
}
|
||||
uint32 maxAccountId = sPlayerbotAIConfig->randomBotAccounts.back();
|
||||
// find a bot fit conditions and not in any guild
|
||||
QueryResult results = CharacterDatabase.Query("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 ) "
|
||||
QueryResult results = CharacterDatabase.Query(
|
||||
"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 <= {} "
|
||||
"ORDER BY account DESC LIMIT 1", claz, race_limit, maxAccountId);
|
||||
"ORDER BY account DESC LIMIT 1",
|
||||
claz, race_limit, maxAccountId);
|
||||
if (results)
|
||||
{
|
||||
Field* fields = results->Fetch();
|
||||
@ -966,13 +1041,18 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
std::string name;
|
||||
bool isPlayer = sCharacterCache->GetCharacterNameByGuid(master->GetTarget(), name);
|
||||
// Player* tPlayer = ObjectAccessor::FindConnectedPlayer(master->GetTarget());
|
||||
if (isPlayer) {
|
||||
if (isPlayer)
|
||||
{
|
||||
charnameStr = name;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
messages.push_back("usage: list/reload/tweak/self or add/init/remove PLAYERNAME");
|
||||
return messages;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
charnameStr = charname;
|
||||
}
|
||||
|
||||
@ -1050,7 +1130,9 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -1063,10 +1145,7 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
return messages;
|
||||
}
|
||||
|
||||
uint32 PlayerbotHolder::GetAccountId(std::string const name)
|
||||
{
|
||||
return AccountMgr::GetId(name);
|
||||
}
|
||||
uint32 PlayerbotHolder::GetAccountId(std::string const name) { return AccountMgr::GetId(name); }
|
||||
|
||||
uint32 PlayerbotHolder::GetAccountId(ObjectGuid guid)
|
||||
{
|
||||
@ -1122,7 +1201,8 @@ std::string const PlayerbotHolder::ListBots(Player* 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)
|
||||
{
|
||||
do
|
||||
@ -1192,7 +1272,8 @@ std::string const PlayerbotHolder::LookupBots(Player* master)
|
||||
messages.push_back("DK");
|
||||
messages.push_back("(Usage: .bot lookup CLASS)");
|
||||
std::string ret_msg;
|
||||
for (std::string msg: messages) {
|
||||
for (std::string msg : messages)
|
||||
{
|
||||
ret_msg += msg + "\n";
|
||||
}
|
||||
return ret_msg;
|
||||
@ -1204,16 +1285,15 @@ uint32 PlayerbotHolder::GetPlayerbotsCountByClass(uint32 cls)
|
||||
for (PlayerBotMap::const_iterator it = GetPlayerBotsBegin(); it != GetPlayerBotsEnd(); ++it)
|
||||
{
|
||||
Player* const bot = it->second;
|
||||
if (bot->getClass() == cls) {
|
||||
if (bot->getClass() == cls)
|
||||
{
|
||||
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()
|
||||
{
|
||||
@ -1253,7 +1333,8 @@ void PlayerbotMgr::HandleCommand(uint32 type, std::string const text)
|
||||
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;
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
@ -1274,7 +1355,8 @@ void PlayerbotMgr::HandleMasterIncomingPacket(WorldPacket const& 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;
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
@ -1309,7 +1391,8 @@ void PlayerbotMgr::HandleMasterOutgoingPacket(WorldPacket const& 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;
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
@ -1326,7 +1409,8 @@ void PlayerbotMgr::SaveToDB()
|
||||
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;
|
||||
if (GET_PLAYERBOT_AI(bot) && GET_PLAYERBOT_AI(bot)->GetMaster() == GetMaster())
|
||||
@ -1337,7 +1421,8 @@ void PlayerbotMgr::SaveToDB()
|
||||
void PlayerbotMgr::OnBotLoginInternal(Player* const bot)
|
||||
{
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return;
|
||||
}
|
||||
botAI->SetMaster(master);
|
||||
@ -1458,13 +1543,16 @@ void PlayerbotsMgr::AddPlayerbotData(Player* player, bool isBotAI)
|
||||
|
||||
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);
|
||||
if (itr != _playerbotsAIMap.end())
|
||||
{
|
||||
_playerbotsAIMap.erase(itr);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unordered_map<ObjectGuid, PlayerbotAIBase*>::iterator itr = _playerbotsMgrMap.find(guid);
|
||||
if (itr != _playerbotsMgrMap.end())
|
||||
{
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PLAYERBOTMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "QueryHolder.h"
|
||||
#include "QueryResult.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerbotAIBase.h"
|
||||
#include "QueryHolder.h"
|
||||
#include "QueryResult.h"
|
||||
|
||||
class ChatHandler;
|
||||
class PlayerbotAI;
|
||||
@ -43,13 +44,15 @@ class PlayerbotHolder : public PlayerbotAIBase
|
||||
void OnBotLogin(Player* const bot);
|
||||
|
||||
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(ObjectGuid guid);
|
||||
std::string const ListBots(Player* master);
|
||||
std::string const LookupBots(Player* master);
|
||||
uint32 GetPlayerbotsCount() { return playerBots.size(); }
|
||||
uint32 GetPlayerbotsCountByClass(uint32 cls);
|
||||
|
||||
protected:
|
||||
virtual void OnBotLoginInternal(Player* const bot) = 0;
|
||||
|
||||
|
||||
@ -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 "LFGMgr.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
@ -19,7 +21,8 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
|
||||
return PLAYERBOT_SECURITY_ALLOW_ALL;
|
||||
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (!botAI) {
|
||||
if (!botAI)
|
||||
{
|
||||
return PLAYERBOT_SECURITY_DENY_ALL;
|
||||
}
|
||||
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)
|
||||
*reason = PLAYERBOT_DENY_NONE;
|
||||
|
||||
@ -85,9 +89,11 @@ PlayerbotSecurityLevel PlayerbotSecurity::LevelFor(Player* from, DenyReason* rea
|
||||
if (sPlayerbotAIConfig->gearscorecheck)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -199,7 +205,8 @@ bool PlayerbotSecurity::CheckLevelFor(PlayerbotSecurityLevel level, bool silent,
|
||||
out << "I'll do it later";
|
||||
break;
|
||||
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;
|
||||
case PLAYERBOT_DENY_GEARSCORE:
|
||||
{
|
||||
@ -207,7 +214,8 @@ bool PlayerbotSecurity::CheckLevelFor(PlayerbotSecurityLevel level, bool silent,
|
||||
int fromGS = (int)botAI->GetEquipGearScore(from, false, false);
|
||||
int diff = (100 * (botGS - fromGS) / botGS);
|
||||
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;
|
||||
case PLAYERBOT_DENY_NOT_YOURS:
|
||||
@ -244,7 +252,8 @@ bool PlayerbotSecurity::CheckLevelFor(PlayerbotSecurityLevel level, bool silent,
|
||||
case PLAYERBOT_DENY_NOT_LEADER:
|
||||
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
|
||||
{
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PLAYERBOTSECURITY_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Common.h"
|
||||
#include "ObjectGuid.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class Player;
|
||||
|
||||
enum PlayerbotSecurityLevel : uint32
|
||||
|
||||
@ -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 "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())
|
||||
return;
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
|
||||
{
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
|
||||
}
|
||||
@ -20,7 +24,8 @@ void PlayerbotTextMgr::LoadBotTexts()
|
||||
LOG_INFO("playerbots", "Loading playerbots texts...");
|
||||
|
||||
uint32 count = 0;
|
||||
if (PreparedQueryResult result = PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TEXT)))
|
||||
if (PreparedQueryResult result =
|
||||
PlayerbotsDatabase.Query(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_SEL_TEXT)))
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -37,8 +42,7 @@ void PlayerbotTextMgr::LoadBotTexts()
|
||||
|
||||
botTexts[name].push_back(BotTextEntry(name, text, sayType, replyType));
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
LOG_INFO("playerbots", "{} playerbots texts loaded", count);
|
||||
@ -123,14 +127,14 @@ std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::map<std::
|
||||
return "";
|
||||
|
||||
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)
|
||||
replaceAll(botText, placeholder.first, placeholder.second);
|
||||
|
||||
return botText;
|
||||
}
|
||||
|
||||
|
||||
std::string PlayerbotTextMgr::GetBotText(ChatReplyType replyType, std::string name)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
void PlayerbotTextMgr::AddLocalePriority(uint32 locale)
|
||||
{
|
||||
if (!locale)
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PLAYERBOTTEXTMGR_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#define BOT_TEXT1(name) sPlayerbotTextMgr->GetBotText(name)
|
||||
#define BOT_TEXT2(name, replace) sPlayerbotTextMgr->GetBotText(name, replace)
|
||||
|
||||
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::map<uint32, std::string> m_text;
|
||||
uint32 m_sayType;
|
||||
@ -31,7 +35,11 @@ struct ChatReplyData
|
||||
|
||||
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_guid1;
|
||||
uint32 m_guid2;
|
||||
@ -55,7 +63,8 @@ enum ChatReplyType
|
||||
class PlayerbotTextMgr
|
||||
{
|
||||
public:
|
||||
PlayerbotTextMgr() {
|
||||
PlayerbotTextMgr()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_LOCALES; ++i)
|
||||
{
|
||||
botTextLocalePriority[i] = 0;
|
||||
|
||||
@ -15,16 +15,17 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "cs_playerbots.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
#include "Channel.h"
|
||||
#include "Config.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "DatabaseLoader.h"
|
||||
#include "GuildTaskMgr.h"
|
||||
#include "Metric.h"
|
||||
#include "Playerbots.h"
|
||||
#include "RandomPlayerbotMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "cs_playerbots.h"
|
||||
|
||||
class PlayerbotsDatabaseScript : public DatabaseScript
|
||||
{
|
||||
@ -34,26 +35,19 @@ class PlayerbotsDatabaseScript : public DatabaseScript
|
||||
bool OnDatabasesLoading() override
|
||||
{
|
||||
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");
|
||||
|
||||
return playerbotLoader.Load();
|
||||
}
|
||||
|
||||
void OnDatabasesKeepAlive() override
|
||||
{
|
||||
PlayerbotsDatabase.KeepAlive();
|
||||
}
|
||||
void OnDatabasesKeepAlive() override { PlayerbotsDatabase.KeepAlive(); }
|
||||
|
||||
void OnDatabasesClosing() override
|
||||
{
|
||||
PlayerbotsDatabase.Close();
|
||||
}
|
||||
void OnDatabasesClosing() override { PlayerbotsDatabase.Close(); }
|
||||
|
||||
void OnDatabaseWarnAboutSyncQueries(bool apply) override
|
||||
{
|
||||
PlayerbotsDatabase.WarnAboutSyncQueries(apply);
|
||||
}
|
||||
void OnDatabaseWarnAboutSyncQueries(bool apply) override { PlayerbotsDatabase.WarnAboutSyncQueries(apply); }
|
||||
|
||||
void OnDatabaseSelectIndexLogout(Player* player, uint32& statementIndex, uint32& statementParam) override
|
||||
{
|
||||
@ -63,7 +57,8 @@ class PlayerbotsDatabaseScript : public DatabaseScript
|
||||
|
||||
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();
|
||||
revision = fields[0].Get<std::string>();
|
||||
@ -152,7 +147,8 @@ class PlayerbotsPlayerScript : public PlayerScript
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -332,10 +328,7 @@ class PlayerbotsScript : public PlayerbotScript
|
||||
sRandomPlayerbotMgr->OnPlayerLogout(player);
|
||||
}
|
||||
|
||||
void OnPlayerbotLogoutBots() override
|
||||
{
|
||||
sRandomPlayerbotMgr->LogoutAllBots();
|
||||
}
|
||||
void OnPlayerbotLogoutBots() override { sRandomPlayerbotMgr->LogoutAllBots(); }
|
||||
};
|
||||
|
||||
void AddPlayerbotsScripts()
|
||||
|
||||
@ -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
|
||||
@ -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 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_VALUE2(type, name, param) sSharedValueContext->getGlobalValue<type>(name, param)->Get()
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
#define _PLAYERBOT_RANDOMITEMMGR_H
|
||||
|
||||
#include "AiFactory.h"
|
||||
#include "Common.h"
|
||||
#include "ItemTemplate.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "AiFactory.h"
|
||||
#include "Common.h"
|
||||
#include "ItemTemplate.h"
|
||||
|
||||
class ChatHandler;
|
||||
|
||||
struct ItemTemplate;
|
||||
@ -60,7 +61,8 @@ struct StatWeight
|
||||
|
||||
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)
|
||||
{
|
||||
@ -106,13 +108,16 @@ class BotEquipKey
|
||||
{
|
||||
public:
|
||||
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(BotEquipKey const& other) : level(other.level), clazz(other.clazz), slot(other.slot), quality(other.quality), key(GetKey()) { }
|
||||
|
||||
bool operator<(BotEquipKey const& other) const
|
||||
BotEquipKey(uint32 level, uint8 clazz, uint8 slot, uint32 quality)
|
||||
: level(level), clazz(clazz), slot(slot), quality(quality), key(GetKey())
|
||||
{
|
||||
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;
|
||||
uint8 clazz;
|
||||
@ -144,7 +149,8 @@ class RandomItemMgr
|
||||
RandomItemList Query(uint32 level, RandomItemType type, RandomItemPredicate* predicate);
|
||||
RandomItemList Query(uint32 level, uint8 clazz, uint8 slot, uint32 quality);
|
||||
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);
|
||||
uint32 GetMinLevelFromCache(uint32 itemId);
|
||||
uint32 GetStatWeight(Player* player, uint32 itemId);
|
||||
@ -182,6 +188,7 @@ class RandomItemMgr
|
||||
bool CanEquipItemNew(ItemTemplate const* proto);
|
||||
void AddItemStats(uint32 mod, uint8& sp, uint8& ap, uint8& tank);
|
||||
bool CheckItemStats(uint8 clazz, uint8 sp, uint8 ap, uint8 tank);
|
||||
|
||||
private:
|
||||
std::map<uint32, RandomItemCache> randomItemCache;
|
||||
std::map<RandomItemType, RandomItemPredicate*> predicates;
|
||||
|
||||
@ -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 "ArenaTeamMgr.h"
|
||||
|
||||
#include "AccountMgr.h"
|
||||
#include "ArenaTeamMgr.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "GuildMgr.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotFactory.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SocialMgr.h"
|
||||
|
||||
@ -124,15 +126,18 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
|
||||
uint8 gender = rand() % 2 ? GENDER_MALE : GENDER_FEMALE;
|
||||
uint8 alliance = rand() % 2;
|
||||
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)];
|
||||
if ((alliance && IsAlliance(race)) || (!alliance && !IsAlliance(race))) {
|
||||
if ((alliance && IsAlliance(race)) || (!alliance && !IsAlliance(race)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::string name = CreateRandomBotName(gender);
|
||||
|
||||
if (name.empty()) {
|
||||
if (name.empty())
|
||||
{
|
||||
LOG_ERROR("playerbots", "Unable to get random bot name!");
|
||||
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> 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)];
|
||||
|
||||
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->GetMotionMaster()->Initialize();
|
||||
@ -178,7 +185,8 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
|
||||
player->CleanupsBeforeDelete();
|
||||
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;
|
||||
}
|
||||
|
||||
@ -191,7 +199,8 @@ Player* RandomPlayerbotFactory::CreateRandomBot(WorldSession* session, uint8 cls
|
||||
}
|
||||
// player->SaveToDB(true, false);
|
||||
// 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;
|
||||
}
|
||||
@ -200,9 +209,12 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
|
||||
{
|
||||
std::string botName = "";
|
||||
int tries = 10;
|
||||
while(--tries) {
|
||||
QueryResult result = CharacterDatabase.Query("SELECT name FROM playerbots_names "
|
||||
"WHERE in_use = 0 AND gender = {} ORDER BY RAND() LIMIT 1", gender);
|
||||
while (--tries)
|
||||
{
|
||||
QueryResult result = CharacterDatabase.Query(
|
||||
"SELECT name FROM playerbots_names "
|
||||
"WHERE in_use = 0 AND gender = {} ORDER BY RAND() LIMIT 1",
|
||||
gender);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
@ -218,27 +230,17 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
|
||||
// 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 groupFormStart[2][4] = {
|
||||
{"SV","SV","VK","RV"},
|
||||
{"V" ,"SU","VS","RV"}
|
||||
};
|
||||
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 groupFormStart[2][4] = {{"SV", "SV", "VK", "RV"}, {"V", "SU", "VS", "RV"}};
|
||||
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] = {
|
||||
// S C V K R U
|
||||
{"dtspkThfS", "bcCdfghjkmnNqqrrlsStTvwxyz", "aaeeiouA", "ppttkkbdg", "lmmnrr", "AEO"},
|
||||
{"dtskThfS" ,"bcCdfghjkmmnNqrrlssStTvwyz","aaaeeiiuAAEIO","ppttkbbdg","lmmnrrr","AEOy"}
|
||||
};
|
||||
{"dtskThfS", "bcCdfghjkmmnNqrrlssStTvwyz", "aaaeeiiuAAEIO", "ppttkbbdg", "lmmnrrr", "AEOy"}};
|
||||
const std::string replaceRule[2][17] = {
|
||||
{"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;
|
||||
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
|
||||
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
|
||||
@ -289,8 +292,10 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
|
||||
// TRUE RANDOM NAME GENERATION
|
||||
LOG_ERROR("playerbots", "Conlang name generation failed. True random name fallback.");
|
||||
tries = 10;
|
||||
while(--tries) {
|
||||
for (uint8 i = 0; i < 10; i++) {
|
||||
while (--tries)
|
||||
{
|
||||
for (uint8 i = 0; i < 10; i++)
|
||||
{
|
||||
botName += (i == 0 ? 'A' : 'a') + rand() % 26;
|
||||
}
|
||||
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());
|
||||
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;
|
||||
if (results)
|
||||
{
|
||||
@ -340,8 +346,8 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
||||
|
||||
PlayerbotsDatabase.Execute(PlayerbotsDatabase.GetPreparedStatement(PLAYERBOTS_DEL_RANDOM_BOTS));
|
||||
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
|
||||
the better way is turning the async db operation to sync db operation */
|
||||
/* TODO(yunfan): we need to sleep here to wait for async account deleted, or the newly account won't be created
|
||||
correctly the better way is turning the async db operation to sync db operation */
|
||||
std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount);
|
||||
LOG_INFO("playerbots", "Random bot characters deleted.");
|
||||
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());
|
||||
}
|
||||
|
||||
if (account_creation) {
|
||||
if (account_creation)
|
||||
{
|
||||
/* 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);
|
||||
std::this_thread::sleep_for(10ms * sPlayerbotAIConfig->randomBotAccountCount);
|
||||
@ -420,10 +427,12 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
||||
{
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
for (uint8 cls = CLASS_WARRIOR; cls < MAX_CLASSES - count; ++cls)
|
||||
@ -433,29 +442,33 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
||||
continue;
|
||||
|
||||
if (bool const isClassDeathKnight = cls == CLASS_DEATH_KNIGHT;
|
||||
isClassDeathKnight &&
|
||||
sWorld->getIntConfig(CONFIG_EXPANSION) !=
|
||||
EXPANSION_WRATH_OF_THE_LICH_KING)
|
||||
isClassDeathKnight && sWorld->getIntConfig(CONFIG_EXPANSION) != EXPANSION_WRATH_OF_THE_LICH_KING)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cls != 10) {
|
||||
if (Player* playerBot = factory.CreateRandomBot(session, cls)) {
|
||||
if (cls != 10)
|
||||
{
|
||||
if (Player* playerBot = factory.CreateRandomBot(session, cls))
|
||||
{
|
||||
playerBot->SaveToDB(true, false);
|
||||
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();
|
||||
delete playerBot;
|
||||
bot_creation++;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
/* wait for characters load into database, or characters will fail to loggin */
|
||||
std::this_thread::sleep_for(10s);
|
||||
@ -464,11 +477,13 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
||||
for (WorldSession* session : sessionBots)
|
||||
delete session;
|
||||
|
||||
for (uint32 accountId : sPlayerbotAIConfig->randomBotAccounts) {
|
||||
for (uint32 accountId : sPlayerbotAIConfig->randomBotAccounts)
|
||||
{
|
||||
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()
|
||||
@ -484,8 +499,7 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
|
||||
Field* fields = result->Fetch();
|
||||
uint32 bot = fields[0].Get<uint32>();
|
||||
randomBots.push_back(bot);
|
||||
}
|
||||
while (result->NextRow());
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
if (sPlayerbotAIConfig->deleteRandomBotGuilds)
|
||||
@ -538,7 +552,8 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
|
||||
Player* player = ObjectAccessor::FindPlayer(leader);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -548,7 +563,8 @@ void RandomPlayerbotFactory::CreateRandomGuilds()
|
||||
Guild* guild = new Guild();
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
@ -586,8 +602,10 @@ std::string const RandomPlayerbotFactory::CreateRandomGuildName()
|
||||
uint32 maxId = fields[0].Get<uint32>();
|
||||
|
||||
uint32 id = urand(0, maxId);
|
||||
result = CharacterDatabase.Query("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);
|
||||
result = CharacterDatabase.Query(
|
||||
"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)
|
||||
{
|
||||
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();
|
||||
uint32 bot = fields[0].Get<uint32>();
|
||||
randomBots.push_back(bot);
|
||||
}
|
||||
while (result->NextRow());
|
||||
} while (result->NextRow());
|
||||
}
|
||||
|
||||
uint32 arenaTeamNumber = 0;
|
||||
@ -664,10 +681,10 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
|
||||
continue;
|
||||
}
|
||||
|
||||
// Below query no longer required as now user has control over the number of each type of arena team they want to create.
|
||||
// Keeping commented for potential future reference.
|
||||
// QueryResult results = CharacterDatabase.Query("SELECT `type` FROM playerbots_arena_team_names WHERE name = '{}'", arenaTeamName.c_str());
|
||||
// if (!results)
|
||||
// Below query no longer required as now user has control over the number of each type of arena team they want
|
||||
// to create. Keeping commented for potential future reference. QueryResult results =
|
||||
// CharacterDatabase.Query("SELECT `type` FROM playerbots_arena_team_names WHERE name = '{}'",
|
||||
// arenaTeamName.c_str()); if (!results)
|
||||
// {
|
||||
// LOG_ERROR("playerbots", "No valid types for arena teams");
|
||||
// return;
|
||||
@ -686,7 +703,8 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
|
||||
arenateam->SetCaptain(player->GetGUID());
|
||||
|
||||
// set random rating
|
||||
arenateam->SetRatingForAll(urand(sPlayerbotAIConfig->randomBotArenaTeamMinRating, sPlayerbotAIConfig->randomBotArenaTeamMaxRating));
|
||||
arenateam->SetRatingForAll(
|
||||
urand(sPlayerbotAIConfig->randomBotArenaTeamMinRating, sPlayerbotAIConfig->randomBotArenaTeamMaxRating));
|
||||
|
||||
// set random emblem
|
||||
uint32 backgroundColor = urand(0xFF000000, 0xFFFFFFFF);
|
||||
@ -699,8 +717,9 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
|
||||
// set random kills (wip)
|
||||
// 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_GAMES_SEASON, urand(arenateam->GetStats().games_week, arenateam->GetStats().games_week * 5));
|
||||
//arenateam->SetStats(STAT_TYPE_WINS_SEASON, urand(arenateam->GetStats().wins_week, arenateam->GetStats().games
|
||||
// arenateam->SetStats(STAT_TYPE_GAMES_SEASON, urand(arenateam->GetStats().games_week,
|
||||
// arenateam->GetStats().games_week * 5)); arenateam->SetStats(STAT_TYPE_WINS_SEASON,
|
||||
// urand(arenateam->GetStats().wins_week, arenateam->GetStats().games
|
||||
arenateam->SaveToDB();
|
||||
|
||||
sArenaTeamMgr->AddArenaTeam(arenateam);
|
||||
@ -725,8 +744,10 @@ std::string const RandomPlayerbotFactory::CreateRandomArenaTeamName()
|
||||
uint32 maxId = fields[0].Get<uint32>();
|
||||
|
||||
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 "
|
||||
"WHERE e.arenateamid IS NULL AND n.name_id >= {} LIMIT 1", id);
|
||||
result = CharacterDatabase.Query(
|
||||
"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)
|
||||
{
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_RANDOMPLAYERBOTFACTORY_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
#include "DBCEnums.h"
|
||||
|
||||
class Player;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -7,7 +8,8 @@
|
||||
|
||||
#include "PlayerbotMgr.h"
|
||||
|
||||
struct BattlegroundInfo {
|
||||
struct BattlegroundInfo
|
||||
{
|
||||
std::vector<uint32> bgInstances;
|
||||
std::vector<uint32> ratedArenaInstances;
|
||||
std::vector<uint32> skirmishArenaInstances;
|
||||
@ -45,8 +47,14 @@ class CachedEvent
|
||||
{
|
||||
public:
|
||||
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(uint32 value, uint32 lastChangeTime, uint32 validIn, std::string const data = "") : value(value), lastChangeTime(lastChangeTime), validIn(validIn), data(data) { }
|
||||
CachedEvent(const CachedEvent& other)
|
||||
: 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; }
|
||||
|
||||
@ -150,7 +158,10 @@ class RandomPlayerbotMgr : public PlayerbotHolder
|
||||
void CheckPlayers();
|
||||
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 getActivityPercentage() { return activityMod * 100.0f; }
|
||||
@ -165,7 +176,8 @@ class RandomPlayerbotMgr : public PlayerbotHolder
|
||||
float activityMod = 0.25;
|
||||
uint32 GetEventValue(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();
|
||||
std::vector<uint32> GetBgBots(uint32 bracket);
|
||||
time_t BgCheckTimer;
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
|
||||
@ -33,15 +35,9 @@ bool ServerFacade::IsDistanceGreaterThan(float dist1, float dist2)
|
||||
return dist1 > dist2;
|
||||
}
|
||||
|
||||
bool ServerFacade::IsDistanceGreaterOrEqualThan(float dist1, float dist2)
|
||||
{
|
||||
return !IsDistanceLessThan(dist1, dist2);
|
||||
}
|
||||
bool ServerFacade::IsDistanceGreaterOrEqualThan(float dist1, float dist2) { return !IsDistanceLessThan(dist1, dist2); }
|
||||
|
||||
bool ServerFacade::IsDistanceLessOrEqualThan(float dist1, float dist2)
|
||||
{
|
||||
return !IsDistanceGreaterThan(dist1, dist2);
|
||||
}
|
||||
bool ServerFacade::IsDistanceLessOrEqualThan(float dist1, float dist2) { return !IsDistanceGreaterThan(dist1, dist2); }
|
||||
|
||||
void ServerFacade::SetFacingTo(Player* bot, WorldObject* wo, bool force)
|
||||
{
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 "Event.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
@ -50,10 +52,7 @@ uint32 TalentSpec::PointstoLevel(uint32 points) const
|
||||
return uint32(ceil(points / sWorld->getRate(RATE_TALENT))) + 9;
|
||||
}
|
||||
|
||||
TalentSpec::TalentSpec(uint32 classMask)
|
||||
{
|
||||
GetTalents(classMask);
|
||||
}
|
||||
TalentSpec::TalentSpec(uint32 classMask) { GetTalents(classMask); }
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -103,7 +103,8 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
|
||||
if (!found)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -120,7 +121,8 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
|
||||
if (entry.rank > 0 && entry.talentInfo->Row * 5 > points)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -140,7 +142,8 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
|
||||
// Set the talents for the bots to the current spec.
|
||||
void TalentSpec::ApplyTalents(Player* bot, std::ostringstream* out)
|
||||
{
|
||||
for (auto& entry : talents) {
|
||||
for (auto& entry : talents)
|
||||
{
|
||||
if (entry.rank == 0)
|
||||
continue;
|
||||
bot->LearnTalent(entry.talentInfo->TalentID, entry.rank - 1);
|
||||
@ -208,10 +211,7 @@ bool sortTalentMap(TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j,
|
||||
return false;
|
||||
}
|
||||
|
||||
void TalentSpec::SortTalents(uint32 sortBy)
|
||||
{
|
||||
SortTalents(talents, sortBy);
|
||||
}
|
||||
void TalentSpec::SortTalents(uint32 sortBy) { SortTalents(talents, sortBy); }
|
||||
|
||||
// Sort the talents.
|
||||
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:
|
||||
{
|
||||
uint32 tabSort[] = {0, 1, 2};
|
||||
std::sort(talents.begin(), talents.end(), [&tabSort](TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j)
|
||||
{
|
||||
return sortTalentMap(i, j, tabSort);
|
||||
});
|
||||
std::sort(talents.begin(), talents.end(),
|
||||
[&tabSort](TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j)
|
||||
{ return sortTalentMap(i, j, tabSort); });
|
||||
break;
|
||||
}
|
||||
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) };
|
||||
std::sort(talents.begin(), talents.end(), [&tabSort](TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j)
|
||||
{
|
||||
return sortTalentMap(i, j, tabSort);
|
||||
});
|
||||
uint32 tabSort[] = {GetTalentPoints(talents, 0) * 100 - urand(0, 99),
|
||||
GetTalentPoints(talents, 1) * 100 - urand(0, 99),
|
||||
GetTalentPoints(talents, 2) * 100 - urand(0, 99)};
|
||||
std::sort(talents.begin(), talents.end(),
|
||||
[&tabSort](TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j)
|
||||
{ return sortTalentMap(i, j, tabSort); });
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -320,10 +320,7 @@ std::vector<TalentSpec::TalentListEntry> TalentSpec::GetTalentTree(uint32 tabpag
|
||||
return std::move(retList);
|
||||
}
|
||||
|
||||
uint32 TalentSpec::GetTalentPoints(int32 tabpage)
|
||||
{
|
||||
return GetTalentPoints(talents, tabpage);
|
||||
};
|
||||
uint32 TalentSpec::GetTalentPoints(int32 tabpage) { return GetTalentPoints(talents, tabpage); };
|
||||
|
||||
// Counts the point in a talent list.
|
||||
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.
|
||||
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;
|
||||
|
||||
|
||||
@ -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
|
||||
@ -67,7 +68,8 @@ class TalentSpec
|
||||
void ReadTalents(std::string const link);
|
||||
|
||||
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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
304
src/TravelMgr.h
304
src/TravelMgr.h
@ -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
|
||||
#define _PLAYERBOT_TRAVELMGR_H
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <random>
|
||||
|
||||
#include "AiObject.h"
|
||||
#include "CreatureData.h"
|
||||
#include "GameObject.h"
|
||||
#include "GridDefines.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <random>
|
||||
|
||||
class GuidPosition;
|
||||
class ObjectGuid;
|
||||
class Quest;
|
||||
@ -27,7 +28,7 @@ namespace G3D
|
||||
class Vector2;
|
||||
class Vector3;
|
||||
class Vector4;
|
||||
}
|
||||
} // namespace G3D
|
||||
|
||||
// Constructor types for WorldPosition
|
||||
enum WorldPositionConst
|
||||
@ -84,7 +85,10 @@ class WorldPosition : public WorldLocation
|
||||
WorldPosition(WorldLocation const& loc) : WorldLocation(loc) {}
|
||||
WorldPosition(WorldPosition const& pos) : WorldLocation(pos), visitors(pos.visitors) {}
|
||||
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(WorldObject const* wo);
|
||||
WorldPosition(std::vector<WorldPosition*> list, WorldPositionConst conType);
|
||||
@ -101,15 +105,9 @@ class WorldPosition : public WorldLocation
|
||||
void setZ(float z);
|
||||
void setO(float o);
|
||||
|
||||
void addVisitor()
|
||||
{
|
||||
++visitors;
|
||||
}
|
||||
void addVisitor() { ++visitors; }
|
||||
|
||||
void remVisitor()
|
||||
{
|
||||
--visitors;
|
||||
}
|
||||
void remVisitor() { --visitors; }
|
||||
|
||||
// Getters
|
||||
operator bool() const;
|
||||
@ -146,24 +144,17 @@ class WorldPosition : public WorldLocation
|
||||
|
||||
// Slow distance function using possible map transfers.
|
||||
float distance(WorldPosition* center);
|
||||
float distance(WorldPosition center)
|
||||
{
|
||||
return distance(¢er);
|
||||
}
|
||||
float distance(WorldPosition center) { return distance(¢er); }
|
||||
|
||||
float fDist(WorldPosition* center);
|
||||
float fDist(WorldPosition center)
|
||||
{
|
||||
return fDist(¢er);
|
||||
}
|
||||
float fDist(WorldPosition center) { return fDist(¢er); }
|
||||
|
||||
template <class T>
|
||||
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 this->distance(i.second) < this->distance(j.second);
|
||||
});
|
||||
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); });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@ -175,47 +166,59 @@ class WorldPosition : public WorldLocation
|
||||
// Returns the closest point from the 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)
|
||||
{
|
||||
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.
|
||||
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.
|
||||
float sqDistance(WorldPosition center)
|
||||
{
|
||||
return (getX() - center.getX()) * (getX() - center.getX()) + (getY() - center.getY()) *
|
||||
(getY() - center.getY()) + (getZ() - center.getZ()) * (getZ() - center.getZ());
|
||||
return (getX() - center.getX()) * (getX() - center.getX()) +
|
||||
(getY() - center.getY()) * (getY() - center.getY()) +
|
||||
(getZ() - center.getZ()) * (getZ() - center.getZ());
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return (getX() - center->getX()) * (getX() - center->getX()) + (getY() - center->getY()) *
|
||||
(getY() - center->getY()) + (getZ() - center->getZ()) * (getZ() - center->getZ());
|
||||
return (getX() - center->getX()) * (getX() - center->getX()) +
|
||||
(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.
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -224,10 +227,7 @@ class WorldPosition : public WorldLocation
|
||||
return (ang >= 0) ? ang : 2 * static_cast<float>(M_PI) + ang;
|
||||
}
|
||||
|
||||
float getAngleBetween(WorldPosition dir1, WorldPosition dir2)
|
||||
{
|
||||
return abs(getAngleTo(dir1) - getAngleTo(dir2));
|
||||
}
|
||||
float getAngleBetween(WorldPosition dir1, WorldPosition dir2) { return abs(getAngleTo(dir1) - getAngleTo(dir2)); }
|
||||
|
||||
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);
|
||||
@ -257,7 +257,8 @@ class WorldPosition : public WorldLocation
|
||||
|
||||
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);
|
||||
@ -265,24 +266,15 @@ class WorldPosition : public WorldLocation
|
||||
|
||||
void loadMapAndVMap(uint32 mapId, uint8 x, uint8 y);
|
||||
|
||||
void loadMapAndVMap()
|
||||
{
|
||||
loadMapAndVMap(getMapId(), getmGridCoord().first, getmGridCoord().second);
|
||||
}
|
||||
void loadMapAndVMap() { loadMapAndVMap(getMapId(), getmGridCoord().first, getmGridCoord().second); }
|
||||
|
||||
void loadMapAndVMaps(WorldPosition secondPos);
|
||||
|
||||
// Display functions
|
||||
WorldPosition getDisplayLocation();
|
||||
float getDisplayX()
|
||||
{
|
||||
return getDisplayLocation().getY() * -1.0;
|
||||
}
|
||||
float getDisplayX() { return getDisplayLocation().getY() * -1.0; }
|
||||
|
||||
float getDisplayY()
|
||||
{
|
||||
return getDisplayLocation().getX();
|
||||
}
|
||||
float getDisplayY() { return getDisplayLocation().getX(); }
|
||||
|
||||
uint16 getAreaId();
|
||||
AreaTableEntry const* getArea();
|
||||
@ -299,12 +291,12 @@ class WorldPosition : public WorldLocation
|
||||
return getPathFromPath({startPos}, bot);
|
||||
}
|
||||
|
||||
std::vector<WorldPosition> getPathTo(WorldPosition endPos, Unit* bot)
|
||||
{
|
||||
return endPos.getPathFrom(*this, bot);
|
||||
}
|
||||
std::vector<WorldPosition> getPathTo(WorldPosition endPos, Unit* 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 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
|
||||
{
|
||||
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);
|
||||
std::vector<CreatureData const*> GetResult() const { return data; };
|
||||
@ -386,7 +383,12 @@ class FindPointCreatureData
|
||||
class FindPointGameObjectData
|
||||
{
|
||||
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);
|
||||
std::vector<GameObjectData const*> GetResult() const { return data; };
|
||||
@ -453,42 +455,26 @@ class mapTransfer
|
||||
{
|
||||
public:
|
||||
mapTransfer(WorldPosition pointFrom1, WorldPosition pointTo1, float portalLength1 = 0.1f)
|
||||
: pointFrom(pointFrom1), pointTo(pointTo1), portalLength(portalLength1) { }
|
||||
|
||||
bool isFrom(WorldPosition point)
|
||||
: pointFrom(pointFrom1), pointTo(pointTo1), portalLength(portalLength1)
|
||||
{
|
||||
return point.getMapId() == pointFrom.getMapId();
|
||||
}
|
||||
|
||||
bool isTo(WorldPosition point)
|
||||
{
|
||||
return point.getMapId() == pointTo.getMapId();
|
||||
}
|
||||
bool isFrom(WorldPosition point) { return point.getMapId() == pointFrom.getMapId(); }
|
||||
|
||||
WorldPosition* getPointFrom()
|
||||
{
|
||||
return &pointFrom;
|
||||
}
|
||||
bool isTo(WorldPosition point) { return point.getMapId() == pointTo.getMapId(); }
|
||||
|
||||
WorldPosition* getPointTo()
|
||||
{
|
||||
return &pointTo;
|
||||
}
|
||||
WorldPosition* getPointFrom() { return &pointFrom; }
|
||||
|
||||
bool isUseful(WorldPosition point)
|
||||
{
|
||||
return isFrom(point) || isTo(point);
|
||||
}
|
||||
WorldPosition* getPointTo() { return &pointTo; }
|
||||
|
||||
bool isUseful(WorldPosition point) { return isFrom(point) || isTo(point); }
|
||||
|
||||
float distance(WorldPosition point)
|
||||
{
|
||||
return isUseful(point) ? (isFrom(point) ? point.distance(pointFrom) : point.distance(pointTo)) : 200000;
|
||||
}
|
||||
|
||||
bool isUseful(WorldPosition start, WorldPosition end)
|
||||
{
|
||||
return isFrom(start) && isTo(end);
|
||||
}
|
||||
bool isUseful(WorldPosition start, WorldPosition end) { return isFrom(start) && isTo(end); }
|
||||
|
||||
float distance(WorldPosition start, WorldPosition end)
|
||||
{
|
||||
@ -510,28 +496,22 @@ class TravelDestination
|
||||
TravelDestination() {}
|
||||
TravelDestination(float radiusMin1, float radiusMax1)
|
||||
{
|
||||
radiusMin = radiusMin1; radiusMax = radiusMax1;
|
||||
radiusMin = radiusMin1;
|
||||
radiusMax = 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;
|
||||
|
||||
void addPoint(WorldPosition* pos)
|
||||
{
|
||||
points.push_back(pos);
|
||||
}
|
||||
void addPoint(WorldPosition* pos) { points.push_back(pos); }
|
||||
|
||||
void setExpireDelay(uint32 delay)
|
||||
{
|
||||
expireDelay = delay;
|
||||
}
|
||||
void setExpireDelay(uint32 delay) { expireDelay = delay; }
|
||||
|
||||
void setCooldownDelay(uint32 delay)
|
||||
{
|
||||
cooldownDelay = delay;
|
||||
}
|
||||
void setCooldownDelay(uint32 delay) { cooldownDelay = delay; }
|
||||
|
||||
void setMaxVisitors(uint32 maxVisitors1 = 0, uint32 maxVisitorsPerPoint1 = 0)
|
||||
{
|
||||
@ -543,20 +523,11 @@ class TravelDestination
|
||||
uint32 getExpireDelay() { return expireDelay; }
|
||||
uint32 getCooldownDelay() { return cooldownDelay; }
|
||||
|
||||
void addVisitor()
|
||||
{
|
||||
++visitors;
|
||||
}
|
||||
void addVisitor() { ++visitors; }
|
||||
|
||||
void remVisitor()
|
||||
{
|
||||
--visitors;
|
||||
}
|
||||
void remVisitor() { --visitors; }
|
||||
|
||||
uint32 getVisitors()
|
||||
{
|
||||
return visitors;
|
||||
}
|
||||
uint32 getVisitors() { return visitors; }
|
||||
|
||||
virtual Quest const* GetQuestTemplate() { return nullptr; }
|
||||
virtual bool isActive([[maybe_unused]] Player* bot) { return false; }
|
||||
@ -571,8 +542,14 @@ class TravelDestination
|
||||
|
||||
float distanceTo(WorldPosition* pos) { return nearestPoint(pos)->distance(pos); }
|
||||
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 isOut(WorldPosition* pos, float radius = 0.f) { return !onMap(pos) || distanceTo(pos) > (radius? radius : radiusMax); }
|
||||
virtual bool isIn(WorldPosition* pos, float radius = 0.f)
|
||||
{
|
||||
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; }
|
||||
|
||||
std::vector<WorldPosition*> touchingPoints(WorldPosition* pos);
|
||||
@ -634,8 +611,9 @@ class QuestTravelDestination : public TravelDestination
|
||||
class QuestRelationTravelDestination : public QuestTravelDestination
|
||||
{
|
||||
public:
|
||||
QuestRelationTravelDestination(uint32 quest_id1, uint32 entry1, uint32 relation1, float radiusMin1, float radiusMax1) :
|
||||
QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
|
||||
QuestRelationTravelDestination(uint32 quest_id1, uint32 entry1, uint32 relation1, float radiusMin1,
|
||||
float radiusMax1)
|
||||
: QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
|
||||
{
|
||||
entry = entry1;
|
||||
relation = relation1;
|
||||
@ -656,8 +634,9 @@ class QuestRelationTravelDestination : public QuestTravelDestination
|
||||
class QuestObjectiveTravelDestination : public QuestTravelDestination
|
||||
{
|
||||
public:
|
||||
QuestObjectiveTravelDestination(uint32 quest_id1, uint32 entry1, uint32 objective1, float radiusMin1, float radiusMax1, uint32 itemId1 = 0) :
|
||||
QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
|
||||
QuestObjectiveTravelDestination(uint32 quest_id1, uint32 entry1, uint32 objective1, float radiusMin1,
|
||||
float radiusMax1, uint32 itemId1 = 0)
|
||||
: QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
|
||||
{
|
||||
objective = objective1;
|
||||
entry = entry1;
|
||||
@ -703,7 +682,8 @@ class RpgTravelDestination : public TravelDestination
|
||||
class ExploreTravelDestination : public TravelDestination
|
||||
{
|
||||
public:
|
||||
ExploreTravelDestination(uint32 areaId1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1)
|
||||
ExploreTravelDestination(uint32 areaId1, float radiusMin1, float radiusMax1)
|
||||
: TravelDestination(radiusMin1, radiusMax1)
|
||||
{
|
||||
areaId = areaId1;
|
||||
}
|
||||
@ -770,7 +750,8 @@ class TravelTarget : AiObject
|
||||
{
|
||||
public:
|
||||
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);
|
||||
}
|
||||
@ -779,10 +760,7 @@ class TravelTarget : AiObject
|
||||
|
||||
void setTarget(TravelDestination* tDestination1, WorldPosition* wPosition1, bool groupCopy1 = false);
|
||||
void setStatus(TravelStatus status);
|
||||
void setExpireIn(uint32 expireMs)
|
||||
{
|
||||
statusTime = getExpiredTime() + expireMs;
|
||||
}
|
||||
void setExpireIn(uint32 expireMs) { statusTime = getExpiredTime() + expireMs; }
|
||||
|
||||
void incRetry(bool isMove)
|
||||
{
|
||||
@ -800,15 +778,9 @@ class TravelTarget : AiObject
|
||||
extendRetryCount = newCount;
|
||||
}
|
||||
|
||||
void setForced(bool forced1)
|
||||
{
|
||||
forced = forced1;
|
||||
}
|
||||
void setForced(bool forced1) { forced = forced1; }
|
||||
|
||||
void setRadius(float radius1)
|
||||
{
|
||||
radius = radius1;
|
||||
}
|
||||
void setRadius(float radius1) { radius = radius1; }
|
||||
|
||||
void copyTarget(TravelTarget* target);
|
||||
void addVisitors();
|
||||
@ -827,52 +799,28 @@ class TravelTarget : AiObject
|
||||
return tDestination->getEntry();
|
||||
}
|
||||
|
||||
PlayerbotAI* getAi()
|
||||
{
|
||||
return botAI;
|
||||
}
|
||||
PlayerbotAI* getAi() { return botAI; }
|
||||
|
||||
uint32 getExpiredTime()
|
||||
{
|
||||
return getMSTime() - startTime;
|
||||
}
|
||||
uint32 getExpiredTime() { return getMSTime() - startTime; }
|
||||
|
||||
uint32 getTimeLeft()
|
||||
{
|
||||
return statusTime - getExpiredTime();
|
||||
}
|
||||
uint32 getTimeLeft() { return statusTime - getExpiredTime(); }
|
||||
|
||||
uint32 getMaxTravelTime();
|
||||
uint32 getRetryCount(bool isMove)
|
||||
{
|
||||
return isMove ? moveRetryCount: extendRetryCount;
|
||||
}
|
||||
uint32 getRetryCount(bool isMove) { return isMove ? moveRetryCount : extendRetryCount; }
|
||||
|
||||
bool isTraveling();
|
||||
bool isActive();
|
||||
bool isWorking();
|
||||
bool isPreparing();
|
||||
bool isMaxRetry(bool isMove)
|
||||
{
|
||||
return isMove ? (moveRetryCount > 5) : (extendRetryCount > 5);
|
||||
}
|
||||
bool isMaxRetry(bool isMove) { return isMove ? (moveRetryCount > 5) : (extendRetryCount > 5); }
|
||||
|
||||
TravelStatus getStatus()
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
TravelStatus getStatus() { return m_status; }
|
||||
|
||||
TravelState getTravelState();
|
||||
|
||||
bool isGroupCopy()
|
||||
{
|
||||
return groupCopy;
|
||||
}
|
||||
bool isGroupCopy() { return groupCopy; }
|
||||
|
||||
bool isForced()
|
||||
{
|
||||
return forced;
|
||||
}
|
||||
bool isForced() { return forced; }
|
||||
|
||||
protected:
|
||||
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);
|
||||
QuestStatusData* getQuestStatus(Player* bot, uint32 questId);
|
||||
bool getObjectiveStatus(Player* bot, Quest const* pQuest, uint32 objective);
|
||||
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*> getRpgTravelDestinations(Player* bot, bool ignoreFull = false, 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);
|
||||
std::vector<TravelDestination*> getQuestTravelDestinations(Player* bot, int32 questId = -1, bool ignoreFull = false,
|
||||
bool ignoreInactive = false, float maxDistance = 5000,
|
||||
bool ignoreObjectives = false);
|
||||
std::vector<TravelDestination*> getRpgTravelDestinations(Player* bot, bool ignoreFull = false,
|
||||
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);
|
||||
|
||||
@ -946,15 +901,9 @@ class TravelMgr
|
||||
NullTravelDestination* nullTravelDestination = new NullTravelDestination();
|
||||
WorldPosition* nullWorldPosition = new WorldPosition();
|
||||
|
||||
void addBadVmap(uint32 mapId, uint8 x, uint8 y)
|
||||
{
|
||||
badVmap.push_back(std::make_tuple(mapId, x, y));
|
||||
}
|
||||
void addBadVmap(uint32 mapId, uint8 x, uint8 y) { badVmap.push_back(std::make_tuple(mapId, x, y)); }
|
||||
|
||||
void addBadMmap(uint32 mapId, uint8 x, uint8 y)
|
||||
{
|
||||
badMmap.push_back(std::make_tuple(mapId, x, y));
|
||||
}
|
||||
void addBadMmap(uint32 mapId, uint8 x, uint8 y) { badMmap.push_back(std::make_tuple(mapId, x, 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::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()
|
||||
|
||||
@ -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 <iomanip>
|
||||
#include <regex>
|
||||
|
||||
#include "BudgetValues.h"
|
||||
#include "PathGenerator.h"
|
||||
#include "Playerbots.h"
|
||||
#include "ServerFacade.h"
|
||||
#include "TransportMgr.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <regex>
|
||||
|
||||
// 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)
|
||||
// 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::ostringstream out;
|
||||
@ -22,7 +26,8 @@ std::string const TravelNodePath::print()
|
||||
out << std::to_string(uint8(pathType)) << ",";
|
||||
out << pathObject << ",";
|
||||
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";
|
||||
|
||||
return out.str().c_str();
|
||||
@ -55,11 +60,15 @@ void TravelNodePath::calculateCost(bool distanceOnly)
|
||||
FactionTemplateEntry const* factionEntry = sFactionTemplateStore.LookupEntry(cInfo->faction);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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* 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;
|
||||
}
|
||||
|
||||
@ -127,7 +138,8 @@ float TravelNodePath::getCost(Player* bot, uint32 cGold)
|
||||
swimSpeed *= 1.5;
|
||||
|
||||
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;
|
||||
if (maxLevelCreature.size() > 0)
|
||||
@ -257,7 +269,9 @@ TravelNodePath* TravelNode::buildPath(TravelNode* endNode, Unit* bot, bool postP
|
||||
|
||||
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())
|
||||
canPath = false;
|
||||
}
|
||||
@ -292,7 +306,6 @@ TravelNodePath* TravelNode::buildPath(TravelNode* endNode, Unit* bot, bool postP
|
||||
return returnNodePath;
|
||||
}
|
||||
|
||||
|
||||
// Generic routine to remove references to nodes.
|
||||
void TravelNode::removeLinkTo(TravelNode* node, bool removePaths)
|
||||
{
|
||||
@ -341,7 +354,8 @@ std::vector<TravelNode*> TravelNode::getNodeMap(bool importantOnly, std::vector<
|
||||
TravelNode* nextNode = nextPath.first;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -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?
|
||||
if (nearLength + nearNode->linkDistanceTo(farNode) < farLength * 1.1)
|
||||
return true;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -465,8 +478,8 @@ bool TravelNode::cropUselessLinks()
|
||||
if (firstNode == secondNode)
|
||||
continue;
|
||||
|
||||
if (std::find(toRemove.begin(), toRemove.end(), [firstNode, secondNode](std::pair<TravelNode*, TravelNode*> pair) {return pair.first == firstNode || pair.first == secondNode;}) != toRemove.end())
|
||||
continue;
|
||||
if (std::find(toRemove.begin(), toRemove.end(), [firstNode, secondNode](std::pair<TravelNode*, TravelNode*>
|
||||
pair) {return pair.first == firstNode || pair.first == secondNode;}) != toRemove.end()) continue;
|
||||
|
||||
if (firstNode->hasLinkTo(secondNode))
|
||||
{
|
||||
@ -489,8 +502,8 @@ bool TravelNode::cropUselessLinks()
|
||||
if (route.hasNode(this))
|
||||
continue;
|
||||
|
||||
//Is it quicker to go past first (and multiple) nodes to reach the second node instead of going directly?
|
||||
if (firstLength + route.getLength() < secondLength * 1.1)
|
||||
//Is it quicker to go past first (and multiple) nodes to reach the second node instead of going
|
||||
directly? if (firstLength + route.getLength() < secondLength * 1.1)
|
||||
{
|
||||
if (secondNode->hasLinkTo(this) && !firstNode->hasLinkTo(this))
|
||||
continue;
|
||||
@ -513,8 +526,8 @@ bool TravelNode::cropUselessLinks()
|
||||
if (this == secondNode)
|
||||
continue;
|
||||
|
||||
if (std::find(toRemove.begin(), toRemove.end(), [firstNode, secondNode](std::pair<TravelNode*, TravelNode*> pair) {return pair.first == firstNode || pair.first == secondNode; }) != toRemove.end())
|
||||
continue;
|
||||
if (std::find(toRemove.begin(), toRemove.end(), [firstNode, secondNode](std::pair<TravelNode*,
|
||||
TravelNode*> pair) {return pair.first == firstNode || pair.first == secondNode; }) != toRemove.end()) continue;
|
||||
|
||||
if (firstNode->hasLinkTo(secondNode))
|
||||
{
|
||||
@ -537,8 +550,8 @@ bool TravelNode::cropUselessLinks()
|
||||
if (route.hasNode(this))
|
||||
continue;
|
||||
|
||||
//Is it quicker to go past first (and multiple) nodes to reach the second node instead of going directly?
|
||||
if (firstLength + route.getLength() < secondLength * 1.1)
|
||||
//Is it quicker to go past first (and multiple) nodes to reach the second node instead of going
|
||||
directly? if (firstLength + route.getLength() < secondLength * 1.1)
|
||||
{
|
||||
if (secondNode->hasLinkTo(this) && !firstNode->hasLinkTo(this))
|
||||
continue;
|
||||
@ -679,7 +692,9 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
|
||||
if (&p != &fullPath.front())
|
||||
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;
|
||||
totalDist = curDist;
|
||||
@ -691,7 +706,9 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
|
||||
if (!firstNode)
|
||||
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;
|
||||
totalDist = curDist;
|
||||
@ -736,7 +753,9 @@ bool TravelPath::makeShortCut(WorldPosition startPos, float maxDist)
|
||||
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.
|
||||
return false;
|
||||
@ -764,7 +783,8 @@ bool TravelPath::shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathN
|
||||
// We are moving to a transport node.
|
||||
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 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);
|
||||
|
||||
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;
|
||||
}
|
||||
@ -789,7 +810,8 @@ bool TravelPath::shouldMoveToNextPoint(WorldPosition startPos, std::vector<PathN
|
||||
}
|
||||
|
||||
// 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())
|
||||
return WorldPosition();
|
||||
@ -882,7 +904,8 @@ std::ostringstream const TravelPath::print()
|
||||
std::ostringstream out;
|
||||
|
||||
out << sPlayerbotAIConfig->GetTimestampStr();
|
||||
out << "+00," << "1,";
|
||||
out << "+00,"
|
||||
<< "1,";
|
||||
out << std::fixed;
|
||||
|
||||
WorldPosition().printWKT(getPointPath(), out, 1);
|
||||
@ -901,7 +924,8 @@ float TravelNodeRoute::getTotalDistance()
|
||||
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;
|
||||
|
||||
@ -921,7 +945,8 @@ TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, st
|
||||
{
|
||||
if (!prevNode->isTransport())
|
||||
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.
|
||||
nodePath = prevNode->getPathTo(node);
|
||||
@ -930,9 +955,11 @@ TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, st
|
||||
|
||||
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::reverse(path.begin(), path.end()); // Reverse the 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
|
||||
{
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
else if (nodePath->getPathType() == TravelNodePathType::teleportSpell)
|
||||
@ -970,13 +999,18 @@ TravelPath TravelNodeRoute::buildPath(std::vector<WorldPosition> pathToStart, st
|
||||
{
|
||||
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();
|
||||
|
||||
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());
|
||||
|
||||
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());
|
||||
|
||||
travelPath.addPath(path, NODE_PATH);
|
||||
@ -996,7 +1030,9 @@ std::ostringstream const TravelNodeRoute::print()
|
||||
std::ostringstream out;
|
||||
|
||||
out << sPlayerbotAIConfig->GetTimestampStr();
|
||||
out << "+00" << ",0," << "\"LINESTRING(";
|
||||
out << "+00"
|
||||
<< ",0,"
|
||||
<< "\"LINESTRING(";
|
||||
|
||||
for (auto& node : nodes)
|
||||
{
|
||||
@ -1036,7 +1072,9 @@ TravelNodeMap::TravelNodeMap(TravelNodeMap* baseMap)
|
||||
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;
|
||||
|
||||
@ -1119,12 +1157,15 @@ std::vector<TravelNode*> TravelNodeMap::getNodes(WorldPosition pos, float range)
|
||||
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);
|
||||
}
|
||||
|
||||
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 y = pos.getY();
|
||||
@ -1210,7 +1251,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
|
||||
// childNode->parent = startStub;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -1238,7 +1280,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
|
||||
currentNode->close = true;
|
||||
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;
|
||||
|
||||
@ -1266,7 +1309,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
h = childNode->dataNode->fDist(goal) / botSpeed;
|
||||
@ -1285,7 +1329,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
|
||||
if (!childNode->open)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -1294,7 +1339,8 @@ TravelNodeRoute TravelNodeMap::getRoute(TravelNode* start, TravelNode* goal, Pla
|
||||
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())
|
||||
return TravelNodeRoute();
|
||||
@ -1303,15 +1349,11 @@ TravelNodeRoute TravelNodeMap::getRoute(WorldPosition startPos, WorldPosition en
|
||||
std::vector<TravelNode*> startNodes = m_nodes, endNodes = m_nodes;
|
||||
|
||||
// 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)
|
||||
{
|
||||
return i->fDist(startPos) < j->fDist(startPos);
|
||||
});
|
||||
std::partial_sort(startNodes.begin(), startNodes.begin() + 5, startNodes.end(),
|
||||
[startPos](TravelNode* i, TravelNode* j) { return i->fDist(startPos) < j->fDist(startPos); });
|
||||
|
||||
std::partial_sort(endNodes.begin(), endNodes.begin() + 5, endNodes.end(), [endPos](TravelNode* i, TravelNode* j)
|
||||
{
|
||||
return i->fDist(endPos) < j->fDist(endPos);
|
||||
});
|
||||
std::partial_sort(endNodes.begin(), endNodes.begin() + 5, endNodes.end(),
|
||||
[endPos](TravelNode* i, TravelNode* j) { return i->fDist(endPos) < j->fDist(endPos); });
|
||||
|
||||
// Cycle over the combinations of these 5 nodes.
|
||||
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.
|
||||
newStartPath = startPath;
|
||||
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;
|
||||
return route;
|
||||
@ -1394,8 +1437,8 @@ TravelPath TravelNodeMap::getFullPath(WorldPosition startPos, WorldPosition endP
|
||||
// Then bot has to move towards/along the route.
|
||||
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.
|
||||
//Also returns longPath: The path from the start position to the first node in the route.
|
||||
// Find the route of nodes starting at a node closest to the start position and ending at a node closest to the
|
||||
// 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);
|
||||
|
||||
if (route.isEmpty())
|
||||
@ -1468,7 +1511,6 @@ TravelNode* TravelNodeMap::addZoneLinkNode(TravelNode* startNode)
|
||||
|
||||
zoneName = newZoneName;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1518,7 +1560,6 @@ void TravelNodeMap::manageNodes(Unit* bot, bool mapFull)
|
||||
|
||||
if (m_nMapMtx.try_lock())
|
||||
{
|
||||
|
||||
TravelNode* startNode;
|
||||
TravelNode* newNode;
|
||||
|
||||
@ -1552,7 +1593,6 @@ void TravelNodeMap::manageNodes(Unit* bot, bool mapFull)
|
||||
|
||||
rePrint = nodeDone || rePrint || newNode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (rePrint && (mapFull || !urand(0, 20)))
|
||||
@ -1575,13 +1615,15 @@ void TravelNodeMap::generateNpcNodes()
|
||||
|
||||
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);
|
||||
if (!cInfo)
|
||||
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)
|
||||
{
|
||||
@ -1674,7 +1716,8 @@ void TravelNodeMap::generateAreaTriggerNodes()
|
||||
continue;
|
||||
|
||||
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;
|
||||
|
||||
@ -1699,7 +1742,8 @@ void TravelNodeMap::generateAreaTriggerNodes()
|
||||
continue;
|
||||
|
||||
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;
|
||||
|
||||
@ -1756,7 +1800,8 @@ void TravelNodeMap::generateTransportNodes()
|
||||
for (auto& transport : WorldPosition().getGameObjectsNear(0, itr.first))
|
||||
{
|
||||
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();
|
||||
|
||||
for (auto& p : aPath)
|
||||
@ -1764,7 +1809,9 @@ void TravelNodeMap::generateTransportNodes()
|
||||
float dx = -1 * p.second->X;
|
||||
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)
|
||||
{
|
||||
@ -1773,7 +1820,8 @@ void TravelNodeMap::generateTransportNodes()
|
||||
|
||||
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)
|
||||
{
|
||||
@ -1784,7 +1832,8 @@ void TravelNodeMap::generateTransportNodes()
|
||||
{
|
||||
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);
|
||||
ppath.clear();
|
||||
ppath.push_back(pos);
|
||||
@ -1803,13 +1852,16 @@ void TravelNodeMap::generateTransportNodes()
|
||||
{
|
||||
float dx = -1 * p.second->X;
|
||||
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);
|
||||
|
||||
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 (p.second->TimeSeg < timeStart)
|
||||
@ -1817,7 +1869,8 @@ void TravelNodeMap::generateTransportNodes()
|
||||
|
||||
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);
|
||||
node->setPathTo(prevNode, travelPath);
|
||||
ppath.clear();
|
||||
@ -1892,7 +1945,8 @@ void TravelNodeMap::generateTransportNodes()
|
||||
|
||||
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);
|
||||
|
||||
node->setPathTo(prevNode, travelPath);
|
||||
@ -1952,7 +2006,6 @@ void TravelNodeMap::generateWalkPaths()
|
||||
nodeMaps[startNode->getMapId()] = true;
|
||||
}
|
||||
|
||||
|
||||
for (auto& map : nodeMaps)
|
||||
{
|
||||
for (auto& startNode : sTravelNodeMap->getNodes(WorldPosition(map.first, 1, 1)))
|
||||
@ -2196,16 +2249,20 @@ void TravelNodeMap::printNodeStore()
|
||||
std::string name = node->getName();
|
||||
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 << "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 << "\"";
|
||||
if (node->isTransport())
|
||||
out << "," << (node->isTransport() ? "true" : "false") << "," << node->getTransportId();
|
||||
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";
|
||||
if (node->isTransport())
|
||||
out << "," << (node->isTransport() ? "true" : "false") << "," << node->getTransportId();
|
||||
@ -2225,13 +2282,16 @@ void TravelNodeMap::printNodeStore()
|
||||
{
|
||||
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 << std::fixed << std::setprecision(1) << " nodes[" << i << "]->setPathTo(nodes[" << saveNodes.find(Link.first)->second << "],TravelNodePath(";
|
||||
//out << Link.second->print() << "), true);";
|
||||
// out << std::fixed << std::setprecision(1) << " nodes[" << i << "]->setPathTo(nodes[" <<
|
||||
// saveNodes.find(Link.first)->second << "],TravelNodePath("; out << Link.second->print() << "), true);";
|
||||
sPlayerbotAIConfig->log(nodeStore, out.str().c_str());
|
||||
}
|
||||
}
|
||||
@ -2291,7 +2351,8 @@ void TravelNodeMap::saveNodeStore()
|
||||
{
|
||||
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(1, saveNodes.find(link.first)->second);
|
||||
stmt->SetData(2, static_cast<uint8>(path->getPathType()));
|
||||
@ -2313,7 +2374,8 @@ void TravelNodeMap::saveNodeStore()
|
||||
{
|
||||
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(1, saveNodes.find(link.first)->second);
|
||||
stmt->SetData(2, j);
|
||||
@ -2341,13 +2403,16 @@ void TravelNodeMap::loadNodeStore()
|
||||
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
|
||||
{
|
||||
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>())
|
||||
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
|
||||
{
|
||||
@ -2380,7 +2446,13 @@ void TravelNodeMap::loadNodeStore()
|
||||
if (!startNode || !endNode)
|
||||
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>())
|
||||
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
|
||||
{
|
||||
@ -2411,7 +2484,8 @@ void TravelNodeMap::loadNodeStore()
|
||||
TravelNodePath* path = startNode->getPathTo(endNode);
|
||||
|
||||
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);
|
||||
|
||||
@ -2481,7 +2555,8 @@ void TravelNodeMap::calcMapOffset()
|
||||
//+X -> -Y
|
||||
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));
|
||||
curPos.setX(curPos.getX() + (max[i].getX() - min[i].getX() + 500));
|
||||
|
||||
115
src/TravelNode.h
115
src/TravelNode.h
@ -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
|
||||
#define _PLAYERBOT_TRAVELNODE_H
|
||||
|
||||
#include "TravelMgr.h"
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "TravelMgr.h"
|
||||
|
||||
// THEORY
|
||||
//
|
||||
// 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.
|
||||
// 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.
|
||||
// Bots would get stuck moving from Northshire to Stormwind because there is no 296y path that doesn't go (initially) the wrong direction.
|
||||
// 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. 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.
|
||||
//
|
||||
// <S> ---> [N1] ---> [N2] ---> [N3] ---> <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]
|
||||
// If we can move fom [S] to [N1] and from [N3] to [E] we have a complete route to travel.
|
||||
// [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] If we can move fom [S] to [N1] and from [N3] to [E] we have a complete route to travel.
|
||||
//
|
||||
// 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.
|
||||
// Link: the connection between two nodes. A link signifies that the bot can travel from one node to another. A link is one-directional.
|
||||
// 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.
|
||||
// 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: 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. Link: the connection between two nodes. A link signifies that the bot can travel from one node to
|
||||
// another. A link is one-directional. 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. 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.
|
||||
// Nodes can be added and removed realtime however because bots access the nodes from different threads this requires a locking mechanism.
|
||||
// On server start saved nodes and links are loaded. Paths and routes are calculated on the fly but saved for future
|
||||
// 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:
|
||||
// Flightmasters and Inns (Bots can use these to fast-travel so eventually they will be included in the route calculation)
|
||||
// WorldBosses and Unique bosses in instances (These are a logical places bots might want to go in instances)
|
||||
// Player start spawns (Obviously all lvl1 bots will spawn and move from here)
|
||||
// Area triggers locations with teleport and their teleport destinations (These used to travel in or between maps)
|
||||
// Transports including elevators (Again used to travel in and in maps)
|
||||
// (sub)Zone means (These are the center most point for each sub-zone which is good for global coverage)
|
||||
// Flightmasters and Inns (Bots can use these to fast-travel so eventually they will be included in the route
|
||||
// calculation) WorldBosses and Unique bosses in instances (These are a logical places bots might want to go in
|
||||
// instances) Player start spawns (Obviously all lvl1 bots will spawn and move from here) Area triggers locations with
|
||||
// teleport and their teleport destinations (These used to travel in or between maps) Transports including elevators
|
||||
// (Again used to travel in and in maps) (sub)Zone means (These are the center most point for each sub-zone which is
|
||||
// good for global coverage)
|
||||
//
|
||||
// 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.
|
||||
@ -61,12 +67,21 @@ class TravelNodePath
|
||||
{
|
||||
public:
|
||||
// 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
|
||||
TravelNodePath(float distance = 0.1f, float extraCost = 0, uint8 pathType = (uint8)TravelNodePathType::walk, uint32 pathObject = 0, bool calculated = false,
|
||||
std::vector<uint8> maxLevelCreature = { 0, 0, 0 }, float swimDistance = 0)
|
||||
: extraCost(extraCost), calculated(calculated), distance(distance), maxLevelCreature(maxLevelCreature), swimDistance(swimDistance), pathType(TravelNodePathType(pathType)), pathObject(pathObject) // reorder args - whipowill
|
||||
TravelNodePath(float distance = 0.1f, float extraCost = 0, uint8 pathType = (uint8)TravelNodePathType::walk,
|
||||
uint32 pathObject = 0, bool calculated = false, std::vector<uint8> maxLevelCreature = {0, 0, 0},
|
||||
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)
|
||||
complete = true;
|
||||
@ -104,15 +119,9 @@ class TravelNodePath
|
||||
std::string const print();
|
||||
|
||||
// Setters
|
||||
void setComplete(bool complete1)
|
||||
{
|
||||
complete = complete1;
|
||||
}
|
||||
void setComplete(bool complete1) { complete = complete1; }
|
||||
|
||||
void setPath(std::vector<WorldPosition> path1)
|
||||
{
|
||||
path = path1;
|
||||
}
|
||||
void setPath(std::vector<WorldPosition> path1) { path = path1; }
|
||||
|
||||
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 setTransport(bool transport1) { transport = transport1; }
|
||||
|
||||
void setPathType(TravelNodePathType pathType1)
|
||||
{
|
||||
pathType = pathType1;
|
||||
}
|
||||
void setPathType(TravelNodePathType pathType1) { pathType = pathType1; }
|
||||
|
||||
void setPathObject(uint32 pathObject1)
|
||||
{
|
||||
pathObject = pathObject1;
|
||||
}
|
||||
void setPathObject(uint32 pathObject1) { pathObject = pathObject1; }
|
||||
|
||||
void calculateCost(bool distanceOnly = false);
|
||||
|
||||
@ -388,9 +391,21 @@ class TravelPath
|
||||
}
|
||||
|
||||
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 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 addPoint(WorldPosition point, PathNodeType type = NODE_PATH, uint32 entry = 0)
|
||||
{
|
||||
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(); }
|
||||
|
||||
bool empty() { return fullPath.empty(); }
|
||||
@ -407,7 +422,9 @@ class TravelPath
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
std::ostringstream const print();
|
||||
@ -430,12 +447,16 @@ class TravelNodeRoute
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
@ -465,7 +486,8 @@ class TravelNodeMap
|
||||
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);
|
||||
bool removeNodes()
|
||||
{
|
||||
@ -520,7 +542,8 @@ class TravelNodeMap
|
||||
TravelNodeRoute getRoute(TravelNode* start, TravelNode* goal, Player* bot = nullptr);
|
||||
|
||||
// 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
|
||||
static TravelPath getFullPath(WorldPosition startPos, WorldPosition endPos, Player* bot = nullptr);
|
||||
|
||||
@ -13,13 +13,13 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BattleGroundTactics.h"
|
||||
#include "Chat.h"
|
||||
#include "GuildTaskMgr.h"
|
||||
#include "PerformanceMonitor.h"
|
||||
#include "PlayerbotMgr.h"
|
||||
#include "RandomPlayerbotMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "BattleGroundTactics.h"
|
||||
|
||||
using namespace Acore::ChatCommands;
|
||||
|
||||
@ -30,12 +30,10 @@ public:
|
||||
|
||||
ChatCommandTable GetCommands() const override
|
||||
{
|
||||
static ChatCommandTable playerbotsDebugCommandTable =
|
||||
{
|
||||
static ChatCommandTable playerbotsDebugCommandTable = {
|
||||
{"bg", HandleDebugBGCommand, SEC_GAMEMASTER, Console::Yes},
|
||||
};
|
||||
static ChatCommandTable playerbotsCommandTable =
|
||||
{
|
||||
static ChatCommandTable playerbotsCommandTable = {
|
||||
{"bot", HandlePlayerbotCommand, SEC_PLAYER, Console::No},
|
||||
{"gtask", HandleGuildTaskCommand, SEC_GAMEMASTER, Console::Yes},
|
||||
{"pmon", HandlePerfMonCommand, SEC_GAMEMASTER, Console::Yes},
|
||||
@ -43,8 +41,7 @@ public:
|
||||
{"debug", playerbotsDebugCommandTable},
|
||||
};
|
||||
|
||||
static ChatCommandTable commandTable =
|
||||
{
|
||||
static ChatCommandTable commandTable = {
|
||||
{"playerbots", playerbotsCommandTable},
|
||||
};
|
||||
|
||||
@ -96,7 +93,4 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_playerbots_commandscript()
|
||||
{
|
||||
new playerbots_commandscript();
|
||||
}
|
||||
void AddSC_playerbots_commandscript() { new playerbots_commandscript(); }
|
||||
|
||||
@ -19,7 +19,4 @@
|
||||
void AddPlayerbotsScripts();
|
||||
|
||||
// Add all
|
||||
void Addmod_playerbotsScripts()
|
||||
{
|
||||
AddPlayerbotsScripts();
|
||||
}
|
||||
void Addmod_playerbotsScripts() { AddPlayerbotsScripts(); }
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
#include "Timer.h"
|
||||
|
||||
@ -66,8 +68,7 @@ NextAction** NextAction::array(uint32 nil, ...)
|
||||
{
|
||||
cur = va_arg(vl, NextAction*);
|
||||
++size;
|
||||
}
|
||||
while (cur);
|
||||
} while (cur);
|
||||
|
||||
va_end(vl);
|
||||
|
||||
@ -91,22 +92,13 @@ void NextAction::destroy(NextAction** actions)
|
||||
delete[] actions;
|
||||
}
|
||||
|
||||
Value<Unit*>* Action::GetTargetValue()
|
||||
{
|
||||
return context->GetValue<Unit*>(GetTargetName());
|
||||
}
|
||||
Value<Unit*>* Action::GetTargetValue() { return context->GetValue<Unit*>(GetTargetName()); }
|
||||
|
||||
Unit* Action::GetTarget()
|
||||
{
|
||||
return GetTargetValue()->Get();
|
||||
}
|
||||
Unit* Action::GetTarget() { return GetTargetValue()->Get(); }
|
||||
|
||||
ActionBasket::ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, Event event) :
|
||||
action(action), relevance(relevance), skipPrerequisites(skipPrerequisites), event(event), created(getMSTime())
|
||||
ActionBasket::ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, Event event)
|
||||
: action(action), relevance(relevance), skipPrerequisites(skipPrerequisites), event(event), created(getMSTime())
|
||||
{
|
||||
}
|
||||
|
||||
bool ActionBasket::isExpired(uint32 msecs)
|
||||
{
|
||||
return getMSTime() - created >= msecs;
|
||||
}
|
||||
bool ActionBasket::isExpired(uint32 msecs) { return getMSTime() - created >= msecs; }
|
||||
|
||||
@ -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
|
||||
@ -16,7 +17,8 @@ class Unit;
|
||||
class NextAction
|
||||
{
|
||||
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
|
||||
|
||||
std::string const getName() { return name; }
|
||||
@ -43,7 +45,8 @@ class Action : public AiNamedObject
|
||||
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 bool Execute([[maybe_unused]] Event event) { return true; }
|
||||
@ -70,8 +73,11 @@ class Action : public AiNamedObject
|
||||
class ActionNode
|
||||
{
|
||||
public:
|
||||
ActionNode(std::string const name, NextAction** prerequisites = nullptr, NextAction** alternatives = nullptr, NextAction** continuers = nullptr) :
|
||||
name(name), action(nullptr), continuers(continuers), alternatives(alternatives), prerequisites(prerequisites) { } // reorder arguments - whipowill
|
||||
ActionNode(std::string const name, NextAction** prerequisites = nullptr, NextAction** alternatives = nullptr,
|
||||
NextAction** continuers = nullptr)
|
||||
: name(name), action(nullptr), continuers(continuers), alternatives(alternatives), prerequisites(prerequisites)
|
||||
{
|
||||
} // reorder arguments - whipowill
|
||||
|
||||
virtual ~ActionNode()
|
||||
{
|
||||
@ -85,8 +91,14 @@ class ActionNode
|
||||
std::string const getName() { return name; }
|
||||
|
||||
NextAction** getContinuers() { return NextAction::merge(NextAction::clone(continuers), action->getContinuers()); }
|
||||
NextAction** getAlternatives() { return NextAction::merge(NextAction::clone(alternatives), action->getAlternatives()); }
|
||||
NextAction** getPrerequisites() { return NextAction::merge(NextAction::clone(prerequisites), action->getPrerequisites()); }
|
||||
NextAction** getAlternatives()
|
||||
{
|
||||
return NextAction::merge(NextAction::clone(alternatives), action->getAlternatives());
|
||||
}
|
||||
NextAction** getPrerequisites()
|
||||
{
|
||||
return NextAction::merge(NextAction::clone(prerequisites), action->getPrerequisites());
|
||||
}
|
||||
|
||||
private:
|
||||
std::string const name;
|
||||
|
||||
@ -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 "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()
|
||||
{
|
||||
return botAI->GetMaster();
|
||||
}
|
||||
Player* AiObject::GetMaster() { return botAI->GetMaster(); }
|
||||
|
||||
@ -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
|
||||
@ -49,10 +50,11 @@ class clazz : public super \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : super(botAI) {} \
|
||||
bool IsActive() override; \
|
||||
bool IsActive() override;
|
||||
|
||||
#define END_TRIGGER() \
|
||||
};
|
||||
} \
|
||||
;
|
||||
|
||||
#define BUFF_TRIGGER(clazz, spell) \
|
||||
class clazz : public BuffTrigger \
|
||||
@ -385,10 +387,7 @@ class clazz : public CastDebuffSpellAction \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) \
|
||||
{ \
|
||||
range = distance; \
|
||||
} \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) { range = distance; } \
|
||||
}
|
||||
|
||||
#define DEBUFF_ENEMY_ACTION(clazz, spell) \
|
||||
@ -420,7 +419,6 @@ class clazz : public CastSpellOnEnemyHealerAction \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
|
||||
#define SNARE_ACTION(clazz, spell) \
|
||||
class clazz : public CastSnareSpellAction \
|
||||
{ \
|
||||
@ -443,37 +441,40 @@ class clazz : public CastProtectSpellAction \
|
||||
}
|
||||
|
||||
#define END_RANGED_SPELL_ACTION() \
|
||||
};
|
||||
} \
|
||||
;
|
||||
|
||||
#define BEGIN_SPELL_ACTION(clazz, name) \
|
||||
class clazz : public CastSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, name) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, name) {}
|
||||
|
||||
#define END_SPELL_ACTION() \
|
||||
};
|
||||
} \
|
||||
;
|
||||
|
||||
#define BEGIN_DEBUFF_ACTION(clazz, name) \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, name) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, name) {}
|
||||
|
||||
#define BEGIN_RANGED_SPELL_ACTION(clazz, name) \
|
||||
class clazz : public CastSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, name) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, name) {}
|
||||
|
||||
#define BEGIN_MELEE_SPELL_ACTION(clazz, name) \
|
||||
class clazz : public CastMeleeSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, name) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, name) {}
|
||||
|
||||
#define END_RANGED_SPELL_ACTION() \
|
||||
};
|
||||
} \
|
||||
;
|
||||
|
||||
#define BEGIN_BUFF_ON_PARTY_ACTION(clazz, name) \
|
||||
class clazz : public BuffOnPartyAction \
|
||||
@ -489,9 +490,7 @@ class clazz : public BuffOnPartyAction \
|
||||
#define ACTION_NODE_P(name, spell, pre) \
|
||||
static ActionNode* name(PlayerbotAI* botAI) \
|
||||
{ \
|
||||
return new ActionNode(spell, \
|
||||
/*P*/ NextAction::array(0, new NextAction(pre), nullptr), \
|
||||
/*A*/ nullptr, \
|
||||
return new ActionNode(spell, /*P*/ NextAction::array(0, new NextAction(pre), nullptr), /*A*/ nullptr, \
|
||||
/*C*/ nullptr); \
|
||||
}
|
||||
|
||||
@ -499,9 +498,7 @@ static ActionNode* name(PlayerbotAI* botAI) \
|
||||
#define ACTION_NODE_A(name, spell, alt) \
|
||||
static ActionNode* name(PlayerbotAI* botAI) \
|
||||
{ \
|
||||
return new ActionNode(spell, \
|
||||
/*P*/ nullptr, \
|
||||
/*A*/ NextAction::array(0, new NextAction(alt), nullptr), \
|
||||
return new ActionNode(spell, /*P*/ nullptr, /*A*/ NextAction::array(0, new NextAction(alt), nullptr), \
|
||||
/*C*/ nullptr); \
|
||||
}
|
||||
|
||||
@ -509,9 +506,7 @@ static ActionNode* name(PlayerbotAI* botAI) \
|
||||
#define ACTION_NODE_C(name, spell, con) \
|
||||
static ActionNode* name(PlayerbotAI* botAI) \
|
||||
{ \
|
||||
return new ActionNode(spell, \
|
||||
/*P*/ nullptr, \
|
||||
/*A*/ nullptr, \
|
||||
return new ActionNode(spell, /*P*/ nullptr, /*A*/ nullptr, \
|
||||
/*C*/ NextAction::array(0, new NextAction(con), nullptr)); \
|
||||
}
|
||||
|
||||
|
||||
@ -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 "StrategyContext.h"
|
||||
|
||||
#include "ActionContext.h"
|
||||
#include "ChatActionContext.h"
|
||||
#include "WorldPacketActionContext.h"
|
||||
#include "ChatTriggerContext.h"
|
||||
#include "TriggerContext.h"
|
||||
#include "SharedValueContext.h"
|
||||
#include "WorldPacketTriggerContext.h"
|
||||
#include "ValueContext.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/RaidStrategyContext.h"
|
||||
#include "raids/RaidTriggerContext.h"
|
||||
#include "raids/naxxramas/RaidNaxxActionContext.h"
|
||||
#include "raids/naxxramas/RaidNaxxTriggerContext.h"
|
||||
|
||||
@ -116,35 +118,20 @@ std::set<std::string> AiObjectContext::GetSiblingStrategy(std::string const name
|
||||
return strategyContexts.GetSiblings(name);
|
||||
}
|
||||
|
||||
Trigger* AiObjectContext::GetTrigger(std::string const name)
|
||||
{
|
||||
return triggerContexts.GetContextObject(name, botAI);
|
||||
}
|
||||
Trigger* AiObjectContext::GetTrigger(std::string const name) { return triggerContexts.GetContextObject(name, botAI); }
|
||||
|
||||
Action* AiObjectContext::GetAction(std::string const name)
|
||||
{
|
||||
return actionContexts.GetContextObject(name, botAI);
|
||||
}
|
||||
Action* AiObjectContext::GetAction(std::string const name) { return actionContexts.GetContextObject(name, botAI); }
|
||||
|
||||
UntypedValue* AiObjectContext::GetUntypedValue(std::string const name)
|
||||
{
|
||||
return valueContexts.GetContextObject(name, botAI);
|
||||
}
|
||||
|
||||
std::set<std::string> AiObjectContext::GetValues()
|
||||
{
|
||||
return valueContexts.GetCreated();
|
||||
}
|
||||
std::set<std::string> AiObjectContext::GetValues() { return valueContexts.GetCreated(); }
|
||||
|
||||
std::set<std::string> AiObjectContext::GetSupportedStrategies()
|
||||
{
|
||||
return strategyContexts.supports();
|
||||
}
|
||||
std::set<std::string> AiObjectContext::GetSupportedStrategies() { return strategyContexts.supports(); }
|
||||
|
||||
std::set<std::string> AiObjectContext::GetSupportedActions()
|
||||
{
|
||||
return actionContexts.supports();
|
||||
}
|
||||
std::set<std::string> AiObjectContext::GetSupportedActions() { return actionContexts.supports(); }
|
||||
|
||||
std::string const AiObjectContext::FormatValues()
|
||||
{
|
||||
@ -166,7 +153,4 @@ std::string const AiObjectContext::FormatValues()
|
||||
return out.str();
|
||||
}
|
||||
|
||||
void AiObjectContext::AddShared(NamedObjectContext<UntypedValue>* sharedValues)
|
||||
{
|
||||
valueContexts.Add(sharedValues);
|
||||
}
|
||||
void AiObjectContext::AddShared(NamedObjectContext<UntypedValue>* sharedValues) { valueContexts.Add(sharedValues); }
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_AIOBJECTCONTEXT_H
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "Common.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "PlayerbotAIAware.h"
|
||||
@ -12,9 +16,6 @@
|
||||
#include "Trigger.h"
|
||||
#include "Value.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class AiObjectContext : public PlayerbotAIAware
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
|
||||
#include <regex>
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
std::map<std::string, std::string> CustomStrategy::actionLinesCache;
|
||||
|
||||
NextAction* toNextAction(std::string const action)
|
||||
@ -47,9 +49,7 @@ TriggerNode* toTriggerNode(std::string const actionLine)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CustomStrategy::CustomStrategy(PlayerbotAI* botAI) : Strategy(botAI), Qualified()
|
||||
{
|
||||
}
|
||||
CustomStrategy::CustomStrategy(PlayerbotAI* botAI) : Strategy(botAI), Qualified() {}
|
||||
|
||||
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)
|
||||
{
|
||||
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::string const actionLine = match[1].str();
|
||||
@ -88,7 +89,8 @@ void CustomStrategy::InitTriggers(std::vector<TriggerNode*> &triggers)
|
||||
|
||||
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(1, qualifier);
|
||||
PreparedQueryResult result = PlayerbotsDatabase.Query(stmt);
|
||||
@ -99,8 +101,7 @@ void CustomStrategy::LoadActionLines(uint32 owner)
|
||||
Field* fields = result->Fetch();
|
||||
std::string const action = fields[1].Get<std::string>();
|
||||
actionLines.push_back(action);
|
||||
}
|
||||
while (result->NextRow());
|
||||
} while (result->NextRow());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_CUSTOMSTRATEGY_H
|
||||
|
||||
#include "Strategy.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Strategy.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class CustomStrategy : public Strategy, public Qualified
|
||||
|
||||
@ -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 "Action.h"
|
||||
#include "Event.h"
|
||||
#include "Queue.h"
|
||||
#include "PerformanceMonitor.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Queue.h"
|
||||
#include "Strategy.h"
|
||||
|
||||
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)
|
||||
{
|
||||
//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());
|
||||
}
|
||||
else if (action->isUseful())
|
||||
@ -185,7 +188,8 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
if (pmo)
|
||||
pmo->finish();
|
||||
@ -264,8 +269,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal)
|
||||
|
||||
delete actionNode;
|
||||
}
|
||||
}
|
||||
while (basket && ++iterations <= iterationsPerTick);
|
||||
} while (basket && ++iterations <= iterationsPerTick);
|
||||
|
||||
// if (!basket)
|
||||
// {
|
||||
@ -318,7 +322,8 @@ ActionNode* Engine::CreateActionNode(std::string const name)
|
||||
/*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;
|
||||
if (actions)
|
||||
@ -432,8 +437,7 @@ void Engine::addStrategies(std::string first, ...)
|
||||
cur = va_arg(vl, const char*);
|
||||
if (cur)
|
||||
addStrategy(cur);
|
||||
}
|
||||
while (cur);
|
||||
} while (cur);
|
||||
|
||||
va_end(vl);
|
||||
}
|
||||
@ -463,10 +467,7 @@ void Engine::toggleStrategy(std::string const name)
|
||||
addStrategy(name);
|
||||
}
|
||||
|
||||
bool Engine::HasStrategy(std::string const name)
|
||||
{
|
||||
return strategies.find(name) != strategies.end();
|
||||
}
|
||||
bool Engine::HasStrategy(std::string const name) { return strategies.find(name) != strategies.end(); }
|
||||
|
||||
void Engine::ProcessTriggers(bool minimal)
|
||||
{
|
||||
@ -495,7 +496,8 @@ void Engine::ProcessTriggers(bool minimal)
|
||||
if (minimal && node->getFirstRelevance() < 100)
|
||||
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();
|
||||
if (pmo)
|
||||
pmo->finish();
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_ENGINE_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Multiplier.h"
|
||||
#include "Queue.h"
|
||||
#include "PlayerbotAIAware.h"
|
||||
#include "Queue.h"
|
||||
#include "Strategy.h"
|
||||
#include "Trigger.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class Action;
|
||||
class ActionNode;
|
||||
class AiObjectContext;
|
||||
@ -50,15 +51,9 @@ class ActionExecutionListeners : public ActionExecutionListener
|
||||
void After(Action* action, bool executed, Event event) override;
|
||||
bool OverrideResult(Action* action, bool executed, Event event) override;
|
||||
|
||||
void Add(ActionExecutionListener* listener)
|
||||
{
|
||||
listeners.push_back(listener);
|
||||
}
|
||||
void Add(ActionExecutionListener* listener) { listeners.push_back(listener); }
|
||||
|
||||
void Remove(ActionExecutionListener* listener)
|
||||
{
|
||||
listeners.remove(listener);
|
||||
}
|
||||
void Remove(ActionExecutionListener* listener) { listeners.remove(listener); }
|
||||
|
||||
private:
|
||||
std::list<ActionExecutionListener*> listeners;
|
||||
@ -85,22 +80,17 @@ class Engine : public PlayerbotAIAware
|
||||
virtual bool DoNextAction(Unit*, uint32 depth = 0, bool minimal = false);
|
||||
ActionResult ExecuteAction(std::string const name, Event event = Event(), std::string const qualifier = "");
|
||||
|
||||
void AddActionExecutionListener(ActionExecutionListener* listener)
|
||||
{
|
||||
actionExecutionListeners.Add(listener);
|
||||
}
|
||||
void AddActionExecutionListener(ActionExecutionListener* listener) { actionExecutionListeners.Add(listener); }
|
||||
|
||||
void removeActionExecutionListener(ActionExecutionListener* listener)
|
||||
{
|
||||
actionExecutionListeners.Remove(listener);
|
||||
}
|
||||
void removeActionExecutionListener(ActionExecutionListener* listener) { actionExecutionListeners.Remove(listener); }
|
||||
|
||||
virtual ~Engine(void);
|
||||
|
||||
bool testMode;
|
||||
|
||||
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 ProcessTriggers(bool minimal);
|
||||
void PushDefaultActions();
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
|
||||
Event::Event(std::string const source, ObjectGuid object, Player* owner) : source(source), owner(owner)
|
||||
|
||||
@ -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
|
||||
@ -16,8 +17,14 @@ class Event
|
||||
Event(Event const& other) : source(other.source), param(other.param), packet(other.packet), owner(other.owner) {}
|
||||
Event() {}
|
||||
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, WorldPacket& packet, Player* owner = nullptr) : source(source), packet(packet), owner(owner) { }
|
||||
Event(std::string const source, std::string const param, Player* owner = nullptr)
|
||||
: 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);
|
||||
virtual ~Event() {}
|
||||
|
||||
|
||||
@ -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 "Trigger.h"
|
||||
|
||||
#include "ChatHelper.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Trigger.h"
|
||||
|
||||
bool ExternalEventHelper::ParseChatCommand(std::string const command, Player* owner)
|
||||
{
|
||||
@ -37,7 +39,8 @@ bool ExternalEventHelper::ParseChatCommand(std::string const command, Player* ow
|
||||
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();
|
||||
std::string const name = handlers[opcode];
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_EXTERNALEVENTHELPER_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
class AiObjectContext;
|
||||
class Player;
|
||||
class WorldPacket;
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
|
||||
bool FindUsableItemVisitor::Visit(Item* item)
|
||||
@ -15,7 +17,8 @@ bool FindUsableItemVisitor::Visit(Item* item)
|
||||
|
||||
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++)
|
||||
{
|
||||
|
||||
@ -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
|
||||
@ -82,10 +83,7 @@ class FindItemsByQualityVisitor : public IterateItemsVisitor
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Item*>& GetResult()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
std::vector<Item*>& GetResult() { return result; }
|
||||
|
||||
private:
|
||||
uint32 quality;
|
||||
@ -111,7 +109,9 @@ class FindItemsToTradeByClassVisitor : public IterateItemsVisitor
|
||||
{
|
||||
public:
|
||||
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
|
||||
{
|
||||
@ -128,10 +128,7 @@ class FindItemsToTradeByClassVisitor : public IterateItemsVisitor
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Item*>& GetResult()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
std::vector<Item*>& GetResult() { return result; }
|
||||
|
||||
private:
|
||||
uint32 itemClass;
|
||||
@ -197,10 +194,7 @@ class FindItemByIdVisitor : public FindItemVisitor
|
||||
public:
|
||||
FindItemByIdVisitor(uint32 id) : FindItemVisitor(), id(id) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override
|
||||
{
|
||||
return proto->ItemId == id;
|
||||
}
|
||||
bool Accept(ItemTemplate const* proto) override { return proto->ItemId == id; }
|
||||
|
||||
private:
|
||||
uint32 id;
|
||||
@ -211,10 +205,7 @@ class FindItemByIdsVisitor : public FindItemVisitor
|
||||
public:
|
||||
FindItemByIdsVisitor(ItemIds ids) : FindItemVisitor(), ids(ids) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override
|
||||
{
|
||||
return ids.find(proto->ItemId) != ids.end();
|
||||
}
|
||||
bool Accept(ItemTemplate const* proto) override { return ids.find(proto->ItemId) != ids.end(); }
|
||||
|
||||
private:
|
||||
ItemIds ids;
|
||||
@ -274,12 +265,15 @@ class FindPotionVisitor : public FindUsableItemVisitor
|
||||
class FindFoodVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindFoodVisitor(Player* bot, uint32 spellCategory, bool conjured = false) : FindUsableItemVisitor(bot),
|
||||
spellCategory(spellCategory), conjured(conjured) { }
|
||||
FindFoodVisitor(Player* bot, uint32 spellCategory, bool conjured = false)
|
||||
: FindUsableItemVisitor(bot), spellCategory(spellCategory), conjured(conjured)
|
||||
{
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@ -417,6 +411,7 @@ class FindUsableNamedItemVisitor : public FindUsableItemVisitor
|
||||
FindUsableNamedItemVisitor(Player* bot, std::string name) : FindUsableItemVisitor(bot), name(name) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
|
||||
void Qualified::Qualify(int qual)
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_NAMEDOBJECTCONEXT_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class Qualified
|
||||
@ -20,17 +21,11 @@ class Qualified
|
||||
public:
|
||||
Qualified(){};
|
||||
Qualified(std::string const qualifier) : qualifier(qualifier) {}
|
||||
Qualified(int32 qualifier1)
|
||||
{
|
||||
Qualify(qualifier1);
|
||||
}
|
||||
Qualified(int32 qualifier1) { Qualify(qualifier1); }
|
||||
|
||||
virtual void Qualify(int qual);
|
||||
|
||||
virtual void Qualify(std::string const qual)
|
||||
{
|
||||
qualifier = qual;
|
||||
}
|
||||
virtual void Qualify(std::string const qual) { qualifier = qual; }
|
||||
|
||||
std::string const getQualifier() { return qualifier; }
|
||||
|
||||
@ -78,7 +73,8 @@ class NamedObjectFactory
|
||||
std::set<std::string> supports()
|
||||
{
|
||||
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);
|
||||
|
||||
return keys;
|
||||
@ -89,14 +85,13 @@ template <class T>
|
||||
class NamedObjectContext : public NamedObjectFactory<T>
|
||||
{
|
||||
public:
|
||||
NamedObjectContext(bool shared = false, bool supportsSiblings = false) :
|
||||
NamedObjectFactory<T>(), shared(shared), supportsSiblings(supportsSiblings) { }
|
||||
|
||||
virtual ~NamedObjectContext()
|
||||
NamedObjectContext(bool shared = false, bool supportsSiblings = false)
|
||||
: NamedObjectFactory<T>(), shared(shared), supportsSiblings(supportsSiblings)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
virtual ~NamedObjectContext() { Clear(); }
|
||||
|
||||
T* create(std::string const name, PlayerbotAI* botAI)
|
||||
{
|
||||
if (created.find(name) == created.end())
|
||||
@ -166,10 +161,7 @@ class NamedObjectContextList
|
||||
}
|
||||
}
|
||||
|
||||
void Add(NamedObjectContext<T>* context)
|
||||
{
|
||||
contexts.push_back(context);
|
||||
}
|
||||
void Add(NamedObjectContext<T>* context) { contexts.push_back(context); }
|
||||
|
||||
T* GetContextObject(std::string const name, PlayerbotAI* botAI)
|
||||
{
|
||||
@ -260,10 +252,7 @@ class NamedObjectFactoryList
|
||||
delete *i;
|
||||
}
|
||||
|
||||
void Add(NamedObjectFactory<T>* context)
|
||||
{
|
||||
factories.push_front(context);
|
||||
}
|
||||
void Add(NamedObjectFactory<T>* context) { factories.push_front(context); }
|
||||
|
||||
T* GetContextObject(std::string const& name, PlayerbotAI* botAI)
|
||||
{
|
||||
|
||||
@ -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 "Action.h"
|
||||
#include "AiObjectContext.h"
|
||||
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_PASSIVEMULTIPLIER_H
|
||||
|
||||
#include "Multiplier.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Multiplier.h"
|
||||
|
||||
class Action;
|
||||
class PlayerbotAI;
|
||||
|
||||
|
||||
@ -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 "AiObjectContext.h"
|
||||
#include "Log.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
@ -75,10 +77,7 @@ ActionBasket* Queue::Peek()
|
||||
return selection;
|
||||
}
|
||||
|
||||
uint32 Queue::Size()
|
||||
{
|
||||
return actions.size();
|
||||
}
|
||||
uint32 Queue::Size() { return actions.size(); }
|
||||
|
||||
void Queue::RemoveExpired()
|
||||
{
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_QUEUE_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Action.h"
|
||||
#include "Common.h"
|
||||
|
||||
class Queue
|
||||
{
|
||||
|
||||
@ -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 "Playerbots.h"
|
||||
|
||||
class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
@ -118,8 +120,4 @@ Strategy::Strategy(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
||||
actionNodeFactories.Add(new ActionNodeFactoryInternal());
|
||||
}
|
||||
|
||||
ActionNode* Strategy::GetAction(std::string const name)
|
||||
{
|
||||
return actionNodeFactories.GetContextObject(name, botAI);
|
||||
}
|
||||
|
||||
ActionNode* Strategy::GetAction(std::string const name) { return actionNodeFactories.GetContextObject(name, botAI); }
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_STRATEGY_H
|
||||
|
||||
#include "Action.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "Multiplier.h"
|
||||
#include "Trigger.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "PlayerbotAIAware.h"
|
||||
#include "Trigger.h"
|
||||
|
||||
enum StrategyType : uint32
|
||||
{
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_STRATEGYCONTEXT_H
|
||||
|
||||
#include "CustomStrategy.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "AttackEnemyPlayersStrategy.h"
|
||||
#include "BattlegroundStrategy.h"
|
||||
#include "CastTimeStrategy.h"
|
||||
#include "ChatCommandHandlerStrategy.h"
|
||||
#include "ConserveManaStrategy.h"
|
||||
#include "CustomStrategy.h"
|
||||
#include "DeadStrategy.h"
|
||||
#include "DebugStrategy.h"
|
||||
#include "DpsAssistStrategy.h"
|
||||
@ -29,15 +29,16 @@
|
||||
#include "MaintenanceStrategy.h"
|
||||
#include "MarkRtiStrategy.h"
|
||||
#include "MeleeCombatStrategy.h"
|
||||
#include "NamedObjectContext.h"
|
||||
#include "NonCombatStrategy.h"
|
||||
#include "QuestStrategies.h"
|
||||
#include "PassiveStrategy.h"
|
||||
#include "PullStrategy.h"
|
||||
#include "QuestStrategies.h"
|
||||
#include "RTSCStrategy.h"
|
||||
#include "RacialsStrategy.h"
|
||||
#include "RangedCombatStrategy.h"
|
||||
#include "ReturnStrategy.h"
|
||||
#include "RpgStrategy.h"
|
||||
#include "RTSCStrategy.h"
|
||||
#include "RunawayStrategy.h"
|
||||
#include "StayStrategy.h"
|
||||
#include "TankAssistStrategy.h"
|
||||
@ -228,6 +229,4 @@ class QuestStrategyContext : public NamedObjectContext<Strategy>
|
||||
static Strategy* accept_all_quests(PlayerbotAI* botAI) { return new AcceptAllQuestsStrategy(botAI); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -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 "Event.h"
|
||||
#include "Playerbots.h"
|
||||
#include "Timer.h"
|
||||
|
||||
Trigger::Trigger(PlayerbotAI* botAI, std::string const name, int32 checkInterval) :
|
||||
AiNamedObject(botAI, name), checkInterval(checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)), lastCheckTime(0)
|
||||
Trigger::Trigger(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
|
||||
: AiNamedObject(botAI, name),
|
||||
checkInterval(checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)),
|
||||
lastCheckTime(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -24,15 +28,9 @@ Event Trigger::Check()
|
||||
return event;
|
||||
}
|
||||
|
||||
Value<Unit*>* Trigger::GetTargetValue()
|
||||
{
|
||||
return context->GetValue<Unit*>(GetTargetName());
|
||||
}
|
||||
Value<Unit*>* Trigger::GetTargetValue() { return context->GetValue<Unit*>(GetTargetName()); }
|
||||
|
||||
Unit* Trigger::GetTarget()
|
||||
{
|
||||
return GetTargetValue()->Get();
|
||||
}
|
||||
Unit* Trigger::GetTarget() { return GetTargetValue()->Get(); }
|
||||
|
||||
bool Trigger::needCheck()
|
||||
{
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_TRIGGER_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "Action.h"
|
||||
#include "Common.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
class Unit;
|
||||
@ -39,26 +40,20 @@ class Trigger : public AiNamedObject
|
||||
class TriggerNode
|
||||
{
|
||||
public:
|
||||
TriggerNode(std::string const name, NextAction** handlers = nullptr) : trigger(nullptr), handlers(handlers), name(name) { } // reorder args - whipowill
|
||||
|
||||
virtual ~TriggerNode()
|
||||
TriggerNode(std::string const name, NextAction** handlers = nullptr)
|
||||
: trigger(nullptr), handlers(handlers), name(name)
|
||||
{
|
||||
NextAction::destroy(handlers);
|
||||
}
|
||||
} // reorder args - whipowill
|
||||
|
||||
virtual ~TriggerNode() { NextAction::destroy(handlers); }
|
||||
|
||||
Trigger* getTrigger() { return trigger; }
|
||||
void setTrigger(Trigger* trigger) { this->trigger = trigger; }
|
||||
std::string const getName() { return name; }
|
||||
|
||||
NextAction** getHandlers()
|
||||
{
|
||||
return NextAction::merge(NextAction::clone(handlers), trigger->getHandlers());
|
||||
}
|
||||
NextAction** getHandlers() { return NextAction::merge(NextAction::clone(handlers), trigger->getHandlers()); }
|
||||
|
||||
float getFirstRelevance()
|
||||
{
|
||||
return handlers[0] ? handlers[0]->getRelevance() : -1;
|
||||
}
|
||||
float getFirstRelevance() { return handlers[0] ? handlers[0]->getRelevance() : -1; }
|
||||
|
||||
private:
|
||||
Trigger* trigger;
|
||||
|
||||
@ -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 "PerformanceMonitor.h"
|
||||
#include "Playerbots.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();
|
||||
}
|
||||
|
||||
CDPairCalculatedValue::CDPairCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) :
|
||||
CalculatedValue<CreatureData const*>(botAI, name, checkInterval)
|
||||
CDPairCalculatedValue::CDPairCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
|
||||
: CalculatedValue<CreatureData const*>(botAI, name, checkInterval)
|
||||
{
|
||||
// lastCheckTime = getMSTime() - checkInterval / 2;
|
||||
}
|
||||
@ -62,15 +65,16 @@ std::string const CDPairCalculatedValue::Format()
|
||||
return "<none>";
|
||||
}
|
||||
|
||||
CDPairListCalculatedValue::CDPairListCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) :
|
||||
CalculatedValue<std::vector<CreatureData const*>>(botAI, name, checkInterval)
|
||||
CDPairListCalculatedValue::CDPairListCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
|
||||
: CalculatedValue<std::vector<CreatureData const*>>(botAI, name, checkInterval)
|
||||
{
|
||||
// lastCheckTime = time(nullptr) - checkInterval / 2;
|
||||
}
|
||||
|
||||
std::string const CDPairListCalculatedValue::Format()
|
||||
{
|
||||
std::ostringstream out; out << "{";
|
||||
std::ostringstream out;
|
||||
out << "{";
|
||||
std::vector<CreatureData const*> cdPairs = Calculate();
|
||||
for (CreatureData const* cdPair : cdPairs)
|
||||
{
|
||||
@ -81,8 +85,8 @@ std::string const CDPairListCalculatedValue::Format()
|
||||
return out.str();
|
||||
}
|
||||
|
||||
ObjectGuidCalculatedValue::ObjectGuidCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) :
|
||||
CalculatedValue<ObjectGuid>(botAI, name, checkInterval)
|
||||
ObjectGuidCalculatedValue::ObjectGuidCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval)
|
||||
: CalculatedValue<ObjectGuid>(botAI, name, checkInterval)
|
||||
{
|
||||
// lastCheckTime = time(nullptr) - checkInterval / 2;
|
||||
}
|
||||
@ -93,8 +97,9 @@ std::string const ObjectGuidCalculatedValue::Format()
|
||||
return guid ? std::to_string(guid.GetRawValue()) : "<none>";
|
||||
}
|
||||
|
||||
ObjectGuidListCalculatedValue::ObjectGuidListCalculatedValue(PlayerbotAI* botAI, std::string const name, int32 checkInterval) :
|
||||
CalculatedValue<GuidVector>(botAI, name, checkInterval)
|
||||
ObjectGuidListCalculatedValue::ObjectGuidListCalculatedValue(PlayerbotAI* botAI, std::string const name,
|
||||
int32 checkInterval)
|
||||
: CalculatedValue<GuidVector>(botAI, name, checkInterval)
|
||||
{
|
||||
}
|
||||
|
||||
@ -116,17 +121,22 @@ std::string const ObjectGuidListCalculatedValue::Format()
|
||||
|
||||
Unit* UnitCalculatedValue::Get()
|
||||
{
|
||||
if (checkInterval < 2) {
|
||||
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr);
|
||||
if (checkInterval < 2)
|
||||
{
|
||||
PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(
|
||||
PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr);
|
||||
value = Calculate();
|
||||
if (pmo)
|
||||
pmo->finish();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t now = getMSTime();
|
||||
if (!lastCheckTime || now - lastCheckTime >= checkInterval)
|
||||
{
|
||||
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();
|
||||
if (pmo)
|
||||
pmo->finish();
|
||||
|
||||
@ -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
|
||||
#define _PLAYERBOT_VALUE_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "AiObject.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include "PerformanceMonitor.h"
|
||||
#include "Timer.h"
|
||||
#include "Unit.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
class PlayerbotAI;
|
||||
class Unit;
|
||||
|
||||
@ -57,24 +58,34 @@ template<class T>
|
||||
class CalculatedValue : public UntypedValue, public Value<T>
|
||||
{
|
||||
public:
|
||||
CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1) : UntypedValue(botAI, name),
|
||||
checkInterval(checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)) /*turn s -> ms?*/, lastCheckTime(0) { }
|
||||
CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1)
|
||||
: UntypedValue(botAI, name),
|
||||
checkInterval(
|
||||
checkInterval == 1 ? 1 : (checkInterval < 100 ? checkInterval * 1000 : checkInterval)) /*turn s -> ms?*/,
|
||||
lastCheckTime(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CalculatedValue() {}
|
||||
|
||||
T Get() override
|
||||
{
|
||||
if (checkInterval < 2) {
|
||||
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr);
|
||||
if (checkInterval < 2)
|
||||
{
|
||||
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(),
|
||||
// this->context ? &this->context->performanceStack : nullptr);
|
||||
value = Calculate();
|
||||
// if (pmo)
|
||||
// pmo->finish();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t now = getMSTime();
|
||||
if (!lastCheckTime || now - lastCheckTime >= checkInterval)
|
||||
{
|
||||
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();
|
||||
// if (pmo)
|
||||
// pmo->finish();
|
||||
@ -92,17 +103,22 @@ class CalculatedValue : public UntypedValue, public Value<T>
|
||||
}
|
||||
T& RefGet() override
|
||||
{
|
||||
if (checkInterval < 2) {
|
||||
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(), this->context ? &this->context->performanceStack : nullptr);
|
||||
if (checkInterval < 2)
|
||||
{
|
||||
// PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_VALUE, this->getName(),
|
||||
// this->context ? &this->context->performanceStack : nullptr);
|
||||
value = Calculate();
|
||||
// if (pmo)
|
||||
// pmo->finish();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t now = getMSTime();
|
||||
if (!lastCheckTime || now - lastCheckTime >= checkInterval)
|
||||
{
|
||||
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();
|
||||
// if (pmo)
|
||||
// pmo->finish();
|
||||
@ -138,7 +154,8 @@ class SingleCalculatedValue : public CalculatedValue<T>
|
||||
{
|
||||
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();
|
||||
if (pmo)
|
||||
pmo->finish();
|
||||
@ -152,16 +169,14 @@ template<class T>
|
||||
class MemoryCalculatedValue : public CalculatedValue<T>
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
virtual bool EqualToLast(T value) = 0;
|
||||
virtual bool CanCheckChange()
|
||||
{
|
||||
return time(0) - lastChangeTime < minChangeInterval || EqualToLast(this->value);
|
||||
}
|
||||
virtual bool CanCheckChange() { return time(0) - lastChangeTime < minChangeInterval || EqualToLast(this->value); }
|
||||
|
||||
virtual bool UpdateChange()
|
||||
{
|
||||
@ -186,10 +201,7 @@ class MemoryCalculatedValue : public CalculatedValue<T>
|
||||
return this->value;
|
||||
}
|
||||
|
||||
T LazyGet() override
|
||||
{
|
||||
return this->value;
|
||||
}
|
||||
T LazyGet() override { return this->value; }
|
||||
|
||||
time_t LastChangeOn()
|
||||
{
|
||||
@ -216,7 +228,10 @@ template<class T>
|
||||
class LogCalculatedValue : public MemoryCalculatedValue<T>
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -246,8 +261,10 @@ class LogCalculatedValue : public MemoryCalculatedValue<T>
|
||||
class Uint8CalculatedValue : public CalculatedValue<uint8>
|
||||
{
|
||||
public:
|
||||
Uint8CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1) :
|
||||
CalculatedValue<uint8>(botAI, name, checkInterval) { }
|
||||
Uint8CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1)
|
||||
: CalculatedValue<uint8>(botAI, name, checkInterval)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const Format() override;
|
||||
};
|
||||
@ -255,8 +272,10 @@ class Uint8CalculatedValue : public CalculatedValue<uint8>
|
||||
class Uint32CalculatedValue : public CalculatedValue<uint32>
|
||||
{
|
||||
public:
|
||||
Uint32CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1) :
|
||||
CalculatedValue<uint32>(botAI, name, checkInterval) { }
|
||||
Uint32CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1)
|
||||
: CalculatedValue<uint32>(botAI, name, checkInterval)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const Format() override;
|
||||
};
|
||||
@ -264,8 +283,10 @@ class Uint32CalculatedValue : public CalculatedValue<uint32>
|
||||
class FloatCalculatedValue : public CalculatedValue<float>
|
||||
{
|
||||
public:
|
||||
FloatCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1) :
|
||||
CalculatedValue<float>(botAI, name, checkInterval) { }
|
||||
FloatCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1)
|
||||
: CalculatedValue<float>(botAI, name, checkInterval)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const Format() override;
|
||||
};
|
||||
@ -273,13 +294,12 @@ class FloatCalculatedValue : public CalculatedValue<float>
|
||||
class BoolCalculatedValue : public CalculatedValue<bool>
|
||||
{
|
||||
public:
|
||||
BoolCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1) :
|
||||
CalculatedValue<bool>(botAI, name, checkInterval) { }
|
||||
|
||||
std::string const Format() override
|
||||
BoolCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1)
|
||||
: CalculatedValue<bool>(botAI, name, checkInterval)
|
||||
{
|
||||
return Calculate() ? "true" : "false";
|
||||
}
|
||||
|
||||
std::string const Format() override { return Calculate() ? "true" : "false"; }
|
||||
};
|
||||
|
||||
class UnitCalculatedValue : public CalculatedValue<Unit*>
|
||||
@ -327,8 +347,10 @@ template<class T>
|
||||
class ManualSetValue : public UntypedValue, public Value<T>
|
||||
{
|
||||
public:
|
||||
ManualSetValue(PlayerbotAI* botAI, T defaultValue, std::string const name = "value") :
|
||||
UntypedValue(botAI, name), value(defaultValue), defaultValue(defaultValue) { }
|
||||
ManualSetValue(PlayerbotAI* botAI, T defaultValue, std::string const name = "value")
|
||||
: UntypedValue(botAI, name), value(defaultValue), defaultValue(defaultValue)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ManualSetValue() {}
|
||||
|
||||
@ -337,10 +359,7 @@ class ManualSetValue : public UntypedValue, public Value<T>
|
||||
T& RefGet() override { return value; }
|
||||
void Set(T val) override { value = val; }
|
||||
void Update() override {}
|
||||
void Reset() override
|
||||
{
|
||||
value = defaultValue;
|
||||
}
|
||||
void Reset() override { value = defaultValue; }
|
||||
|
||||
protected:
|
||||
T value;
|
||||
@ -350,8 +369,10 @@ class ManualSetValue : public UntypedValue, public Value<T>
|
||||
class UnitManualSetValue : public ManualSetValue<Unit*>
|
||||
{
|
||||
public:
|
||||
UnitManualSetValue(PlayerbotAI* botAI, Unit* defaultValue, std::string const name = "value") :
|
||||
ManualSetValue<Unit*>(botAI, defaultValue, name) { }
|
||||
UnitManualSetValue(PlayerbotAI* botAI, Unit* defaultValue, std::string const name = "value")
|
||||
: ManualSetValue<Unit*>(botAI, defaultValue, name)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const Format() override;
|
||||
Unit* Get() override;
|
||||
@ -360,29 +381,38 @@ class UnitManualSetValue : public ManualSetValue<Unit*>
|
||||
class DisperseDistanceValue : public ManualSetValue<float>
|
||||
{
|
||||
public:
|
||||
DisperseDistanceValue(PlayerbotAI* botAI, float defaultValue = -1.0f, std::string const name = "disperse distance") :
|
||||
ManualSetValue<float>(botAI, defaultValue, name) { }
|
||||
DisperseDistanceValue(PlayerbotAI* botAI, float defaultValue = -1.0f, std::string const name = "disperse distance")
|
||||
: ManualSetValue<float>(botAI, defaultValue, name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class LastFleeAngleValue : public ManualSetValue<float>
|
||||
{
|
||||
public:
|
||||
LastFleeAngleValue(PlayerbotAI* botAI, float defaultValue = 0.0f, std::string const name = "last flee angle") :
|
||||
ManualSetValue<float>(botAI, defaultValue, name) { }
|
||||
LastFleeAngleValue(PlayerbotAI* botAI, float defaultValue = 0.0f, std::string const name = "last flee angle")
|
||||
: ManualSetValue<float>(botAI, defaultValue, name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class LastFleeTimestampValue : public ManualSetValue<uint32>
|
||||
{
|
||||
public:
|
||||
LastFleeTimestampValue(PlayerbotAI* botAI, uint32 defaultValue = 0, std::string const name = "last flee timestamp") :
|
||||
ManualSetValue<uint32>(botAI, defaultValue, name) { }
|
||||
LastFleeTimestampValue(PlayerbotAI* botAI, uint32 defaultValue = 0, std::string const name = "last flee timestamp")
|
||||
: ManualSetValue<uint32>(botAI, defaultValue, name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class RecentlyFleeInfo : public ManualSetValue<std::list<FleeInfo>>
|
||||
{
|
||||
public:
|
||||
RecentlyFleeInfo(PlayerbotAI* botAI, std::list<FleeInfo> defaultValue = {}, std::string const name = "recently flee info") :
|
||||
ManualSetValue<std::list<FleeInfo>>(botAI, defaultValue, name) { }
|
||||
RecentlyFleeInfo(PlayerbotAI* botAI, std::list<FleeInfo> defaultValue = {},
|
||||
std::string const name = "recently flee info")
|
||||
: ManualSetValue<std::list<FleeInfo>>(botAI, defaultValue, name)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -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 "Event.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 "Event.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
@ -16,7 +18,8 @@ bool AcceptDuelAction::Execute(Event event)
|
||||
p >> playerGuid;
|
||||
|
||||
// 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);
|
||||
packet << flagGuid;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 "Event.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
#include "Playerbots.h"
|
||||
#include "PlayerbotSecurity.h"
|
||||
#include "Playerbots.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
bool AcceptInvitationAction::Execute(Event event)
|
||||
@ -50,7 +52,8 @@ bool AcceptInvitationAction::Execute(Event event)
|
||||
|
||||
botAI->TellMaster("Hello");
|
||||
|
||||
if (sPlayerbotAIConfig->summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig->sightDistance) {
|
||||
if (sPlayerbotAIConfig->summonWhenGroup && bot->GetDistance(inviter) > sPlayerbotAIConfig->sightDistance)
|
||||
{
|
||||
Teleport(inviter, bot);
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 "Event.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
|
||||
@ -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
|
||||
@ -14,7 +15,9 @@ class WorldObject;
|
||||
class AcceptAllQuestsAction : public QuestAction
|
||||
{
|
||||
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:
|
||||
void ProcessQuest(Quest const* quest, Object* questGiver) override;
|
||||
|
||||
@ -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 "Event.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -8,21 +9,23 @@
|
||||
#include "AddLootAction.h"
|
||||
#include "AttackAction.h"
|
||||
#include "AutoLearnSpellAction.h"
|
||||
#include "BattleGroundTactics.h"
|
||||
#include "AutoTeleportForLevelAction.h"
|
||||
#include "BattleGroundJoinAction.h"
|
||||
#include "BattleGroundTactics.h"
|
||||
#include "BuyAction.h"
|
||||
#include "CastCustomSpellAction.h"
|
||||
#include "ChangeStrategyAction.h"
|
||||
#include "ChangeTalentsAction.h"
|
||||
#include "CheckMailAction.h"
|
||||
#include "CheckValuesAction.h"
|
||||
#include "ChooseRpgTargetAction.h"
|
||||
#include "ChooseTargetActions.h"
|
||||
#include "ChooseTravelTargetAction.h"
|
||||
#include "ChooseRpgTargetAction.h"
|
||||
#include "CombatActions.h"
|
||||
#include "DelayAction.h"
|
||||
#include "DestroyItemAction.h"
|
||||
#include "EmoteAction.h"
|
||||
#include "FollowActions.h"
|
||||
#include "GenericActions.h"
|
||||
#include "GenericSpellActions.h"
|
||||
#include "GiveItemAction.h"
|
||||
@ -33,14 +36,14 @@
|
||||
#include "ImbueAction.h"
|
||||
#include "InviteToGroupAction.h"
|
||||
#include "LeaveGroupAction.h"
|
||||
#include "FollowActions.h"
|
||||
#include "LootAction.h"
|
||||
#include "MovementActions.h"
|
||||
#include "MoveToRpgTargetAction.h"
|
||||
#include "MoveToTravelTargetAction.h"
|
||||
#include "MovementActions.h"
|
||||
#include "NonCombatActions.h"
|
||||
#include "OutfitAction.h"
|
||||
#include "PositionAction.h"
|
||||
#include "RaidNaxxActions.h"
|
||||
#include "RandomBotUpdateAction.h"
|
||||
#include "ReachTargetActions.h"
|
||||
#include "ReleaseSpiritAction.h"
|
||||
@ -54,11 +57,9 @@
|
||||
#include "StayActions.h"
|
||||
#include "SuggestWhatToDoAction.h"
|
||||
#include "TravelAction.h"
|
||||
#include "XpGainAction.h"
|
||||
#include "VehicleActions.h"
|
||||
#include "WorldBuffAction.h"
|
||||
#include "RaidNaxxActions.h"
|
||||
#include "AutoTeleportForLevelAction.h"
|
||||
#include "XpGainAction.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
@ -231,7 +232,6 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
|
||||
creators["toggle pet spell"] = &ActionContext::toggle_pet_spell;
|
||||
creators["pet attack"] = &ActionContext::pet_attack;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
@ -265,7 +265,10 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
static Action* ReachSpell(PlayerbotAI* botAI) { return new ReachSpellAction(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_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_with_pet(PlayerbotAI* botAI) { return new FleeWithPetAction(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* pet_attack(PlayerbotAI* ai) { return new PetAttackAction(ai); }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -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 "CellImpl.h"
|
||||
#include "Event.h"
|
||||
#include "GridNotifiers.h"
|
||||
@ -35,20 +37,11 @@ bool AddAllLootAction::Execute(Event event)
|
||||
return added;
|
||||
}
|
||||
|
||||
bool AddLootAction::isUseful()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool AddLootAction::isUseful() { return true; }
|
||||
|
||||
bool AddAllLootAction::isUseful()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool AddAllLootAction::isUseful() { return true; }
|
||||
|
||||
bool AddAllLootAction::AddLoot(ObjectGuid guid)
|
||||
{
|
||||
return AI_VALUE(LootObjectStack*, "available loot")->Add(guid);
|
||||
}
|
||||
bool AddAllLootAction::AddLoot(ObjectGuid guid) { return AI_VALUE(LootObjectStack*, "available loot")->Add(guid); }
|
||||
|
||||
bool AddGatheringLootAction::AddLoot(ObjectGuid guid)
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user