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,11 +102,12 @@ 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);
|
||||
if(!talentPos)
|
||||
if (!talentPos)
|
||||
continue;
|
||||
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id);
|
||||
if (!talentInfo)
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -310,13 +319,13 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
|
||||
if (tab == 2)
|
||||
engine->addStrategies("tank", "tank assist", "aoe", "mark rti", nullptr);
|
||||
else if (player->GetLevel() < 36 || tab == 0)
|
||||
engine->addStrategies("arms", "aoe", "dps assist",/*"behind",*/ nullptr);
|
||||
engine->addStrategies("arms", "aoe", "dps assist", /*"behind",*/ nullptr);
|
||||
else
|
||||
engine->addStrategies("fury", "aoe", "dps assist",/*"behind",*/ nullptr);
|
||||
engine->addStrategies("fury", "aoe", "dps assist", /*"behind",*/ nullptr);
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
if (tab == 0)
|
||||
engine->addStrategies("caster", "caster aoe", "bmana",nullptr);
|
||||
engine->addStrategies("caster", "caster aoe", "bmana", nullptr);
|
||||
else if (tab == 2)
|
||||
engine->addStrategies("heal", "bmana", nullptr);
|
||||
else
|
||||
@ -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,18 +506,22 @@ 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");
|
||||
}
|
||||
}
|
||||
else if (tab == 0)
|
||||
nonCombatEngine->addStrategies("dps assist", "bmana", "bcast", nullptr);
|
||||
else
|
||||
nonCombatEngine->addStrategies("dps assist", "bdps", "baoe",nullptr);
|
||||
nonCombatEngine->addStrategies("dps assist", "bdps", "baoe", nullptr);
|
||||
|
||||
nonCombatEngine->addStrategies("cure", nullptr);
|
||||
break;
|
||||
@ -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;
|
||||
@ -18,7 +19,7 @@ enum BotRoles : uint8;
|
||||
|
||||
class AiFactory
|
||||
{
|
||||
public:
|
||||
public:
|
||||
static AiObjectContext* createAiObjectContext(Player* player, PlayerbotAI* botAI);
|
||||
static Engine* createCombatEngine(Player* player, PlayerbotAI* const facade, AiObjectContext* aiObjectContext);
|
||||
static Engine* createNonCombatEngine(Player* player, PlayerbotAI* const facade, AiObjectContext* aiObjectContext);
|
||||
|
||||
@ -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"
|
||||
@ -17,8 +19,8 @@ std::string const ChatFilter::Filter(std::string& message)
|
||||
|
||||
class StrategyChatFilter : public ChatFilter
|
||||
{
|
||||
public:
|
||||
StrategyChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) { }
|
||||
public:
|
||||
StrategyChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) {}
|
||||
|
||||
std::string const Filter(std::string& message) override
|
||||
{
|
||||
@ -53,8 +55,8 @@ class StrategyChatFilter : public ChatFilter
|
||||
|
||||
class LevelChatFilter : public ChatFilter
|
||||
{
|
||||
public:
|
||||
LevelChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) { }
|
||||
public:
|
||||
LevelChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) {}
|
||||
|
||||
std::string const Filter(std::string& message) override
|
||||
{
|
||||
@ -84,8 +86,8 @@ class LevelChatFilter : public ChatFilter
|
||||
|
||||
class CombatTypeChatFilter : public ChatFilter
|
||||
{
|
||||
public:
|
||||
CombatTypeChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) { }
|
||||
public:
|
||||
CombatTypeChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) {}
|
||||
|
||||
std::string const Filter(std::string& message) override
|
||||
{
|
||||
@ -133,7 +135,7 @@ class CombatTypeChatFilter : public ChatFilter
|
||||
|
||||
class RtiChatFilter : public ChatFilter
|
||||
{
|
||||
public:
|
||||
public:
|
||||
RtiChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI)
|
||||
{
|
||||
rtis.push_back("@star");
|
||||
@ -185,13 +187,13 @@ class RtiChatFilter : public ChatFilter
|
||||
return message;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<std::string> rtis;
|
||||
};
|
||||
|
||||
class ClassChatFilter : public ChatFilter
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ClassChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI)
|
||||
{
|
||||
classNames["@death_knight"] = CLASS_DEATH_KNIGHT;
|
||||
@ -229,14 +231,14 @@ class ClassChatFilter : public ChatFilter
|
||||
return message;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
std::map<std::string, uint8> classNames;
|
||||
};
|
||||
|
||||
class SubGroupChatFilter : public ChatFilter
|
||||
{
|
||||
public:
|
||||
SubGroupChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) { }
|
||||
public:
|
||||
SubGroupChatFilter(PlayerbotAI* botAI) : ChatFilter(botAI) {}
|
||||
|
||||
std::string const Filter(std::string& message) override
|
||||
{
|
||||
@ -295,4 +297,3 @@ std::string const CompositeChatFilter::Filter(std::string& message)
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
@ -1,35 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU 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
|
||||
{
|
||||
public:
|
||||
ChatFilter(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) { }
|
||||
virtual ~ChatFilter() { }
|
||||
public:
|
||||
ChatFilter(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) {}
|
||||
virtual ~ChatFilter() {}
|
||||
|
||||
virtual std::string const Filter(std::string& message);
|
||||
};
|
||||
|
||||
class CompositeChatFilter : public ChatFilter
|
||||
{
|
||||
public:
|
||||
public:
|
||||
CompositeChatFilter(PlayerbotAI* botAI);
|
||||
|
||||
virtual ~CompositeChatFilter();
|
||||
std::string const Filter(std::string& message) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<ChatFilter*> filters;
|
||||
};
|
||||
|
||||
|
||||
@ -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"
|
||||
@ -18,7 +20,7 @@ std::map<uint8, std::string> ChatHelper::classes;
|
||||
std::map<uint8, std::string> ChatHelper::races;
|
||||
std::map<uint8, std::map<uint8, std::string> > ChatHelper::specs;
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
static bool substrContainsInMap(std::string const searchTerm, std::map<std::string, T> searchIn)
|
||||
{
|
||||
for (typename std::map<std::string, T>::iterator i = searchIn.begin(); i != searchIn.end(); ++i)
|
||||
@ -57,19 +59,19 @@ ChatHelper::ChatHelper(PlayerbotAI* botAI) : PlayerbotAIAware(botAI)
|
||||
projectileSubClasses["arrows"] = ITEM_SUBCLASS_ARROW;
|
||||
projectileSubClasses["bullets"] = ITEM_SUBCLASS_BULLET;
|
||||
|
||||
//tradeSubClasses["cloth"] = ITEM_SUBCLASS_CLOTH;
|
||||
//tradeSubClasses["leather"] = ITEM_SUBCLASS_LEATHER;
|
||||
//tradeSubClasses["metal"] = ITEM_SUBCLASS_METAL_STONE;
|
||||
//tradeSubClasses["stone"] = ITEM_SUBCLASS_METAL_STONE;
|
||||
//tradeSubClasses["ore"] = ITEM_SUBCLASS_METAL_STONE;
|
||||
//tradeSubClasses["meat"] = ITEM_SUBCLASS_MEAT;
|
||||
//tradeSubClasses["herb"] = ITEM_SUBCLASS_HERB;
|
||||
//tradeSubClasses["elemental"] = ITEM_SUBCLASS_ELEMENTAL;
|
||||
//tradeSubClasses["disenchants"] = ITEM_SUBCLASS_ENCHANTING;
|
||||
//tradeSubClasses["enchanting"] = ITEM_SUBCLASS_ENCHANTING;
|
||||
//tradeSubClasses["gems"] = ITEM_SUBCLASS_JEWELCRAFTING;
|
||||
//tradeSubClasses["jewels"] = ITEM_SUBCLASS_JEWELCRAFTING;
|
||||
//tradeSubClasses["jewelcrafting"] = ITEM_SUBCLASS_JEWELCRAFTING;
|
||||
// tradeSubClasses["cloth"] = ITEM_SUBCLASS_CLOTH;
|
||||
// tradeSubClasses["leather"] = ITEM_SUBCLASS_LEATHER;
|
||||
// tradeSubClasses["metal"] = ITEM_SUBCLASS_METAL_STONE;
|
||||
// tradeSubClasses["stone"] = ITEM_SUBCLASS_METAL_STONE;
|
||||
// tradeSubClasses["ore"] = ITEM_SUBCLASS_METAL_STONE;
|
||||
// tradeSubClasses["meat"] = ITEM_SUBCLASS_MEAT;
|
||||
// tradeSubClasses["herb"] = ITEM_SUBCLASS_HERB;
|
||||
// tradeSubClasses["elemental"] = ITEM_SUBCLASS_ELEMENTAL;
|
||||
// tradeSubClasses["disenchants"] = ITEM_SUBCLASS_ENCHANTING;
|
||||
// tradeSubClasses["enchanting"] = ITEM_SUBCLASS_ENCHANTING;
|
||||
// tradeSubClasses["gems"] = ITEM_SUBCLASS_JEWELCRAFTING;
|
||||
// tradeSubClasses["jewels"] = ITEM_SUBCLASS_JEWELCRAFTING;
|
||||
// tradeSubClasses["jewelcrafting"] = ITEM_SUBCLASS_JEWELCRAFTING;
|
||||
|
||||
slots["head"] = EQUIPMENT_SLOT_HEAD;
|
||||
slots["neck"] = EQUIPMENT_SLOT_NECK;
|
||||
@ -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());
|
||||
@ -414,9 +420,9 @@ GuidVector ChatHelper::parseGameobjects(std::string const text)
|
||||
if (i == std::string::npos) // break if error
|
||||
break;
|
||||
|
||||
pos = i + 7; //start of window in text 11 + 7 = 18
|
||||
pos = i + 7; // start of window in text 11 + 7 = 18
|
||||
auto endPos = text.find(':', pos); // end of window in text 22
|
||||
if (endPos == std::string::npos) //break if error
|
||||
if (endPos == std::string::npos) // break if error
|
||||
break;
|
||||
|
||||
std::istringstream stream(text.substr(pos, endPos - pos));
|
||||
@ -426,7 +432,7 @@ GuidVector ChatHelper::parseGameobjects(std::string const text)
|
||||
// extract GO entry
|
||||
pos = endPos + 1;
|
||||
endPos = text.find(':', pos); // end of window in text
|
||||
if (endPos == std::string::npos) //break if error
|
||||
if (endPos == std::string::npos) // break if error
|
||||
break;
|
||||
|
||||
std::string const entryC = text.substr(pos, endPos - pos); // get std::string const within window i.e entry
|
||||
@ -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;
|
||||
@ -26,7 +27,7 @@ typedef std::set<uint32> SpellIds;
|
||||
|
||||
class ChatHelper : public PlayerbotAIAware
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ChatHelper(PlayerbotAI* botAI);
|
||||
|
||||
static std::string const formatMoney(uint32 copper);
|
||||
@ -61,7 +62,7 @@ class ChatHelper : public PlayerbotAIAware
|
||||
|
||||
void eraseAllSubStr(std::string& mainStr, std::string const toErase);
|
||||
|
||||
private:
|
||||
private:
|
||||
static std::map<std::string, uint32> consumableSubClasses;
|
||||
static std::map<std::string, uint32> tradeSubClasses;
|
||||
static std::map<std::string, uint32> itemQualities;
|
||||
|
||||
@ -1,22 +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 "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))
|
||||
{
|
||||
}
|
||||
|
||||
void FleeManager::calculateDistanceToCreatures(FleePoint *point)
|
||||
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");
|
||||
@ -45,10 +53,11 @@ bool intersectsOri(float angle, std::vector<float>& angles, float angleIncrement
|
||||
return false;
|
||||
}
|
||||
|
||||
void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*> &points)
|
||||
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);
|
||||
for (float dist = maxAllowedDistance; dist >= sPlayerbotAIConfig->tooCloseDistance ; dist -= distIncrement)
|
||||
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;
|
||||
@ -108,7 +123,7 @@ void FleeManager::calculatePossibleDestinations(std::vector<FleePoint*> &points)
|
||||
}
|
||||
}
|
||||
|
||||
void FleeManager::cleanup(std::vector<FleePoint*> &points)
|
||||
void FleeManager::cleanup(std::vector<FleePoint*>& points)
|
||||
{
|
||||
for (std::vector<FleePoint*>::iterator i = points.begin(); i != points.end(); i++)
|
||||
{
|
||||
@ -123,7 +138,7 @@ bool FleeManager::isBetterThan(FleePoint* point, FleePoint* other)
|
||||
return point->sumDistance - other->sumDistance > 0;
|
||||
}
|
||||
|
||||
FleePoint* FleeManager::selectOptimalDestination(std::vector<FleePoint*> &points)
|
||||
FleePoint* FleeManager::selectOptimalDestination(std::vector<FleePoint*>& points)
|
||||
{
|
||||
FleePoint* best = nullptr;
|
||||
for (std::vector<FleePoint*>::iterator i = points.begin(); i != points.end(); i++)
|
||||
@ -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) { }
|
||||
public:
|
||||
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;
|
||||
@ -25,23 +29,24 @@ class FleePoint
|
||||
float sumDistance;
|
||||
float minDistance;
|
||||
|
||||
private:
|
||||
private:
|
||||
PlayerbotAI* botAI;
|
||||
};
|
||||
|
||||
class FleeManager
|
||||
{
|
||||
public:
|
||||
FleeManager(Player* bot, float maxAllowedDistance, float followAngle, bool forceMaxDistance = false, WorldPosition startPosition = WorldPosition());
|
||||
public:
|
||||
FleeManager(Player* bot, float maxAllowedDistance, float followAngle, bool forceMaxDistance = false,
|
||||
WorldPosition startPosition = WorldPosition());
|
||||
|
||||
bool CalculateDestination(float* rx, float* ry, float* rz);
|
||||
bool isUseful();
|
||||
|
||||
private:
|
||||
void calculatePossibleDestinations(std::vector<FleePoint*> &points);
|
||||
void calculateDistanceToCreatures(FleePoint *point);
|
||||
void cleanup(std::vector<FleePoint*> &points);
|
||||
FleePoint* selectOptimalDestination(std::vector<FleePoint*> &points);
|
||||
private:
|
||||
void calculatePossibleDestinations(std::vector<FleePoint*>& points);
|
||||
void calculateDistanceToCreatures(FleePoint* point);
|
||||
void cleanup(std::vector<FleePoint*>& points);
|
||||
FleePoint* selectOptimalDestination(std::vector<FleePoint*>& points);
|
||||
bool isBetterThan(FleePoint* point, FleePoint* other);
|
||||
|
||||
Player* bot;
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,7 +164,7 @@ uint32 GuildTaskMgr::CreateTask(Player* owner, uint32 guildId)
|
||||
class RandomItemBySkillGuildTaskPredicate : public RandomItemPredicate
|
||||
{
|
||||
public:
|
||||
RandomItemBySkillGuildTaskPredicate(Player* player) : RandomItemPredicate(), player(player) { }
|
||||
RandomItemBySkillGuildTaskPredicate(Player* player) : RandomItemPredicate(), player(player) {}
|
||||
|
||||
bool Apply(ItemTemplate const* proto) override
|
||||
{
|
||||
@ -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";
|
||||
}
|
||||
@ -294,7 +317,7 @@ std::string const formatTime(uint32 secs)
|
||||
std::string const formatDateTime(uint32 secs)
|
||||
{
|
||||
time_t rawtime = time(nullptr) + secs;
|
||||
tm* timeinfo = localtime (&rawtime);
|
||||
tm* timeinfo = localtime(&rawtime);
|
||||
|
||||
char buffer[256];
|
||||
strftime(buffer, sizeof(buffer), "%b %d, %H:%M", timeinfo);
|
||||
@ -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,24 +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_GUILDTASKMGR_H
|
||||
#define _PLAYERBOT_GUILDTASKMGR_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Transaction.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
class ChatHandler;
|
||||
class Player;
|
||||
class Unit;
|
||||
|
||||
class GuildTaskMgr
|
||||
{
|
||||
public:
|
||||
GuildTaskMgr() { };
|
||||
virtual ~GuildTaskMgr() { };
|
||||
public:
|
||||
GuildTaskMgr(){};
|
||||
virtual ~GuildTaskMgr(){};
|
||||
|
||||
static GuildTaskMgr* instance()
|
||||
{
|
||||
@ -35,14 +36,16 @@ class GuildTaskMgr
|
||||
void CheckKillTaskInternal(Player* owner, Unit* victim);
|
||||
bool CheckTaskTransfer(std::string const text, Player* owner, Player* bot);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::map<uint32, uint32> GetTaskValues(uint32 owner, std::string const type, uint32* validIn = nullptr);
|
||||
uint32 GetTaskValue(uint32 owner, uint32 guildId, std::string const type, uint32* validIn = nullptr);
|
||||
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"
|
||||
@ -15,7 +16,7 @@ char* strstri(char const* haystack, char const* needle)
|
||||
{
|
||||
if (tolower(*haystack) == tolower(*needle))
|
||||
{
|
||||
char const* h = haystack, * n = needle;
|
||||
char const *h = haystack, *n = needle;
|
||||
for (; *h && *n; ++h, ++n)
|
||||
{
|
||||
if (tolower(*h) != tolower(*n))
|
||||
@ -36,17 +37,14 @@ char* strstri(char const* haystack, char const* needle)
|
||||
|
||||
std::string& ltrim(std::string& s)
|
||||
{
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) {return !std::isspace(c); }));
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); }));
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string& rtrim(std::string& s)
|
||||
{
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) {return !std::isspace(c); }).base(), s.end());
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end());
|
||||
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
|
||||
@ -8,16 +9,13 @@
|
||||
template <class TValue, class TOwner>
|
||||
class LazyCalculatedValue
|
||||
{
|
||||
public:
|
||||
public:
|
||||
typedef TValue (TOwner::*Calculator)();
|
||||
|
||||
public:
|
||||
LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
public:
|
||||
LazyCalculatedValue(TOwner* owner, Calculator calculator) : calculator(calculator), owner(owner) { Reset(); }
|
||||
|
||||
public:
|
||||
public:
|
||||
TValue GetValue()
|
||||
{
|
||||
if (!calculated)
|
||||
@ -29,12 +27,9 @@ class LazyCalculatedValue
|
||||
return value;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
calculated = false;
|
||||
}
|
||||
void Reset() { calculated = false; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
Calculator calculator;
|
||||
TOwner* owner;
|
||||
bool calculated;
|
||||
|
||||
@ -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,14 +30,11 @@ 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)
|
||||
{
|
||||
for (std::set<LootTarget>::iterator i = begin(); i != end(); )
|
||||
for (std::set<LootTarget>::iterator i = begin(); i != end();)
|
||||
{
|
||||
if (i->asOfTime <= fromTime)
|
||||
erase(i++);
|
||||
@ -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);
|
||||
@ -73,7 +71,7 @@ void LootObject::Refresh(Player* bot, ObjectGuid lootGUID)
|
||||
skillId = creature->GetCreatureTemplate()->GetRequiredLootSkill();
|
||||
uint32 targetLevel = creature->GetLevel();
|
||||
reqSkillValue = targetLevel < 10 ? 1 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
|
||||
if (botAI->HasSkill((SkillType) skillId) && bot->GetSkillValue(skillId) >= reqSkillValue)
|
||||
if (botAI->HasSkill((SkillType)skillId) && bot->GetSkillValue(skillId) >= reqSkillValue)
|
||||
guid = 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());
|
||||
@ -130,7 +127,7 @@ void LootObject::Refresh(Player* bot, ObjectGuid lootGUID)
|
||||
else if (SkillByLockType(LockType(lockInfo->Index[i])) > 0)
|
||||
{
|
||||
skillId = SkillByLockType(LockType(lockInfo->Index[i]));
|
||||
reqSkillValue = std::max((uint32) 1, lockInfo->Skill[i]);
|
||||
reqSkillValue = std::max((uint32)1, lockInfo->Skill[i]);
|
||||
guid = lootGUID;
|
||||
}
|
||||
break;
|
||||
@ -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
|
||||
@ -15,17 +16,17 @@ struct ItemTemplate;
|
||||
|
||||
class LootStrategy
|
||||
{
|
||||
public:
|
||||
LootStrategy() { }
|
||||
virtual ~LootStrategy() { };
|
||||
public:
|
||||
LootStrategy() {}
|
||||
virtual ~LootStrategy(){};
|
||||
virtual bool CanLoot(ItemTemplate const* proto, AiObjectContext* context) = 0;
|
||||
virtual std::string const GetName() = 0;
|
||||
};
|
||||
|
||||
class LootObject
|
||||
{
|
||||
public:
|
||||
LootObject() : skillId(0), reqSkillValue(0), reqItem(0) { }
|
||||
public:
|
||||
LootObject() : skillId(0), reqSkillValue(0), reqItem(0) {}
|
||||
LootObject(Player* bot, ObjectGuid guid);
|
||||
LootObject(LootObject const& other);
|
||||
|
||||
@ -45,29 +46,29 @@ private:
|
||||
|
||||
class LootTarget
|
||||
{
|
||||
public:
|
||||
public:
|
||||
LootTarget(ObjectGuid guid);
|
||||
LootTarget(LootTarget const& other);
|
||||
|
||||
public:
|
||||
public:
|
||||
LootTarget& operator=(LootTarget const& other);
|
||||
bool operator<(LootTarget const& other) const;
|
||||
|
||||
public:
|
||||
public:
|
||||
ObjectGuid guid;
|
||||
time_t asOfTime;
|
||||
};
|
||||
|
||||
class LootTargetList : public std::set<LootTarget>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
void shrink(time_t fromTime);
|
||||
};
|
||||
|
||||
class LootObjectStack
|
||||
{
|
||||
public:
|
||||
LootObjectStack(Player* bot) : bot(bot) { }
|
||||
public:
|
||||
LootObjectStack(Player* bot) : bot(bot) {}
|
||||
|
||||
bool Add(ObjectGuid guid);
|
||||
void Remove(ObjectGuid guid);
|
||||
@ -75,7 +76,7 @@ class LootObjectStack
|
||||
bool CanLoot(float maxDistance);
|
||||
LootObject GetLoot(float maxDistance = 0);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<LootObject> OrderByDistance(float maxDistance = 0);
|
||||
|
||||
Player* bot;
|
||||
|
||||
@ -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
|
||||
@ -35,11 +36,11 @@ enum PerformanceMetric
|
||||
|
||||
class PerformanceMonitorOperation
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PerformanceMonitorOperation(PerformanceData* data, std::string const name, PerformanceStack* stack);
|
||||
void finish();
|
||||
|
||||
private:
|
||||
private:
|
||||
PerformanceData* data;
|
||||
std::string const name;
|
||||
PerformanceStack* stack;
|
||||
@ -48,21 +49,22 @@ class PerformanceMonitorOperation
|
||||
|
||||
class PerformanceMonitor
|
||||
{
|
||||
public:
|
||||
PerformanceMonitor() { };
|
||||
virtual ~PerformanceMonitor() { };
|
||||
public:
|
||||
PerformanceMonitor(){};
|
||||
virtual ~PerformanceMonitor(){};
|
||||
static PerformanceMonitor* instance()
|
||||
{
|
||||
static PerformanceMonitor instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
public:
|
||||
PerformanceMonitorOperation* start(PerformanceMetric metric, std::string const name, PerformanceStack* stack = nullptr);
|
||||
public:
|
||||
PerformanceMonitorOperation* start(PerformanceMetric metric, std::string const name,
|
||||
PerformanceStack* stack = nullptr);
|
||||
void PrintStats(bool perTick = false, bool fullStack = false);
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
private:
|
||||
std::map<PerformanceMetric, std::map<std::string, PerformanceData*> > data;
|
||||
std::mutex lock;
|
||||
};
|
||||
|
||||
@ -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);
|
||||
@ -82,8 +80,8 @@ void PlaceholderHelper::InsertDifficulty(Insertion& insertion, [[maybe_unused]]
|
||||
{
|
||||
bool const isRandomlyNormal = urand(0, 1);
|
||||
bool const isRandomlyHeroic = urand(0, 1);
|
||||
std::vector<std::string> normalAbbrevations = { "Normal", "N" };
|
||||
std::vector<std::string> heroicAbbrevations = { "Heroic", "HC", "H"};
|
||||
std::vector<std::string> normalAbbrevations = {"Normal", "N"};
|
||||
std::vector<std::string> heroicAbbrevations = {"Heroic", "HC", "H"};
|
||||
uint32 const randomAbbrevationIndex = urand(0, 1);
|
||||
if (isRandomlyNormal)
|
||||
{
|
||||
|
||||
@ -1,29 +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_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:
|
||||
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:
|
||||
private:
|
||||
struct Insertion
|
||||
{
|
||||
std::ostringstream& out;
|
||||
|
||||
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;
|
||||
@ -75,9 +76,9 @@ enum BotState
|
||||
|
||||
bool IsAlliance(uint8 race);
|
||||
|
||||
class PlayerbotChatHandler: protected ChatHandler
|
||||
class PlayerbotChatHandler : protected ChatHandler
|
||||
{
|
||||
public:
|
||||
public:
|
||||
explicit PlayerbotChatHandler(Player* pMasterPlayer);
|
||||
void sysmessage(std::string const str) { SendSysMessage(str.c_str()); }
|
||||
uint32 extractQuestId(std::string const str);
|
||||
@ -90,8 +91,8 @@ class PlayerbotChatHandler: protected ChatHandler
|
||||
|
||||
class MinValueCalculator
|
||||
{
|
||||
public:
|
||||
MinValueCalculator(float def = 0.0f) : param(nullptr), minValue(def) { }
|
||||
public:
|
||||
MinValueCalculator(float def = 0.0f) : param(nullptr), minValue(def) {}
|
||||
|
||||
void probe(float value, void* p)
|
||||
{
|
||||
@ -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,
|
||||
@ -272,28 +284,35 @@ enum WARRIOR_TABS {
|
||||
|
||||
class PacketHandlingHelper
|
||||
{
|
||||
public:
|
||||
public:
|
||||
void AddHandler(uint16 opcode, std::string const handler);
|
||||
void Handle(ExternalEventHelper &helper);
|
||||
void Handle(ExternalEventHelper& helper);
|
||||
void AddPacket(WorldPacket const& packet);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::map<uint16, std::string> handlers;
|
||||
std::stack<WorldPacket> queue;
|
||||
};
|
||||
|
||||
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) { }
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const GetCommand() { return command; }
|
||||
Player* GetOwner() { return owner; }
|
||||
uint32 GetType() { return type; }
|
||||
time_t GetTime() { return time; }
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string const command;
|
||||
Player* owner;
|
||||
uint32 type;
|
||||
@ -302,7 +321,7 @@ class ChatCommandHolder
|
||||
|
||||
class PlayerbotAI : public PlayerbotAIBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PlayerbotAI();
|
||||
PlayerbotAI(Player* bot);
|
||||
virtual ~PlayerbotAI();
|
||||
@ -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);
|
||||
@ -413,17 +441,17 @@ class PlayerbotAI : public PlayerbotAIBase
|
||||
Player* GetBot() { return bot; }
|
||||
Player* GetMaster() { return master; }
|
||||
|
||||
//Checks if the bot is really a player. Players always have themselves as master.
|
||||
// Checks if the bot is really a player. Players always have themselves as master.
|
||||
bool IsRealPlayer() { return master ? (master == bot) : false; }
|
||||
//Bot has a master that is a player.
|
||||
// Bot has a master that is a player.
|
||||
bool HasRealPlayerMaster();
|
||||
//Bot has a master that is activly playing.
|
||||
// Bot has a master that is activly playing.
|
||||
bool HasActivePlayerMaster();
|
||||
//Get the group leader or the master of the bot.
|
||||
//Checks if the bot is summoned as alt of a player
|
||||
// Get the group leader or the master of the bot.
|
||||
// Checks if the bot is summoned as alt of a player
|
||||
bool IsAlt();
|
||||
Player* GetGroupMaster();
|
||||
//Returns a semi-random (cycling) number that is fixed for each bot.
|
||||
// Returns a semi-random (cycling) number that is fixed for each bot.
|
||||
uint32 GetFixedBotNumer(BotTypeNumber typeNumber, uint32 maxNum = 100, float cyclePerMin = 1);
|
||||
GrouperType GetGrouperType();
|
||||
GuilderType GetGuilderType();
|
||||
@ -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,10 +486,13 @@ 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);
|
||||
|
||||
private:
|
||||
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:
|
||||
|
||||
protected:
|
||||
Player* bot;
|
||||
Player* master;
|
||||
uint32 accountId;
|
||||
|
||||
@ -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
|
||||
@ -9,10 +10,10 @@ class PlayerbotAI;
|
||||
|
||||
class PlayerbotAIAware
|
||||
{
|
||||
public:
|
||||
PlayerbotAIAware(PlayerbotAI* botAI) : botAI(botAI) { }
|
||||
public:
|
||||
PlayerbotAIAware(PlayerbotAI* botAI) : botAI(botAI) {}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
PlayerbotAI* botAI;
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
@ -9,7 +10,7 @@
|
||||
|
||||
class PlayerbotAIBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PlayerbotAIBase(bool isBotAI);
|
||||
|
||||
bool CanUpdateAI();
|
||||
@ -21,10 +22,10 @@ class PlayerbotAIBase
|
||||
bool IsActive();
|
||||
bool IsBotAI() const;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
uint32 nextAICheckDelay;
|
||||
|
||||
private:
|
||||
private:
|
||||
bool _isBotAI;
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -437,7 +470,7 @@ bool PlayerbotAIConfig::openLog(std::string const fileName, char const* mode)
|
||||
FILE* file = logFileIt->second.first;
|
||||
bool fileOpen = logFileIt->second.second;
|
||||
|
||||
if (fileOpen) //close log file
|
||||
if (fileOpen) // close log file
|
||||
fclose(file);
|
||||
|
||||
std::string m_logsDir = sConfigMgr->GetOption<std::string>("LogsDir", "", false);
|
||||
@ -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;
|
||||
|
||||
@ -490,7 +522,7 @@ void PlayerbotAIConfig::loadWorldBuf(uint32 factionId1, uint32 classId1, uint32
|
||||
|
||||
for (auto buff : buffs)
|
||||
{
|
||||
worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 };
|
||||
worldBuff wb = {buff, factionId1, classId1, minLevel1, maxLevel1};
|
||||
worldBuffs.push_back(wb);
|
||||
}
|
||||
|
||||
@ -503,7 +535,7 @@ void PlayerbotAIConfig::loadWorldBuf(uint32 factionId1, uint32 classId1, uint32
|
||||
|
||||
for (auto buff : buffs)
|
||||
{
|
||||
worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 };
|
||||
worldBuff wb = {buff, factionId1, classId1, minLevel1, maxLevel1};
|
||||
worldBuffs.push_back(wb);
|
||||
}
|
||||
}
|
||||
@ -517,7 +549,7 @@ void PlayerbotAIConfig::loadWorldBuf(uint32 factionId1, uint32 classId1, uint32
|
||||
|
||||
for (auto buff : buffs)
|
||||
{
|
||||
worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 };
|
||||
worldBuff wb = {buff, factionId1, classId1, minLevel1, maxLevel1};
|
||||
worldBuffs.push_back(wb);
|
||||
}
|
||||
}
|
||||
@ -531,7 +563,7 @@ void PlayerbotAIConfig::loadWorldBuf(uint32 factionId1, uint32 classId1, uint32
|
||||
|
||||
for (auto buff : buffs)
|
||||
{
|
||||
worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 };
|
||||
worldBuff wb = {buff, factionId1, classId1, minLevel1, maxLevel1};
|
||||
worldBuffs.push_back(wb);
|
||||
}
|
||||
}
|
||||
@ -545,34 +577,35 @@ void PlayerbotAIConfig::loadWorldBuf(uint32 factionId1, uint32 classId1, uint32
|
||||
|
||||
for (auto buff : buffs)
|
||||
{
|
||||
worldBuff wb = { buff, factionId1, classId1, minLevel1, maxLevel1 };
|
||||
worldBuff wb = {buff, factionId1, classId1, minLevel1, maxLevel1};
|
||||
worldBuffs.push_back(wb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<std::string> split(const std::string &str, const std::string &pattern)
|
||||
static std::vector<std::string> split(const std::string& str, const std::string& pattern)
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
if(str == "")
|
||||
if (str == "")
|
||||
return res;
|
||||
// Also add separators to string connections to facilitate intercepting the last paragraph.
|
||||
std::string strs = str + pattern;
|
||||
size_t pos = strs.find(pattern);
|
||||
|
||||
while(pos != strs.npos)
|
||||
while (pos != strs.npos)
|
||||
{
|
||||
std::string temp = strs.substr(0, pos);
|
||||
res.push_back(temp);
|
||||
// Remove the split string and split the remaining string
|
||||
strs = strs.substr(pos+1, strs.size());
|
||||
strs = strs.substr(pos + 1, strs.size());
|
||||
pos = strs.find(pattern);
|
||||
}
|
||||
|
||||
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;
|
||||
@ -581,40 +614,44 @@ std::vector<std::vector<uint32>> PlayerbotAIConfig::ParseTempTalentsOrder(uint32
|
||||
std::vector<std::vector<std::vector<uint32>>> orders(3);
|
||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||
{
|
||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
||||
if(!talentInfo)
|
||||
TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
|
||||
if (!talentInfo)
|
||||
continue;
|
||||
|
||||
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry( talentInfo->TalentTab );
|
||||
if(!talentTabInfo)
|
||||
TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
|
||||
if (!talentTabInfo)
|
||||
continue;
|
||||
|
||||
if( (classMask & talentTabInfo->ClassMask) == 0 )
|
||||
if ((classMask & talentTabInfo->ClassMask) == 0)
|
||||
continue;
|
||||
|
||||
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,
|
||||
@ -37,8 +38,8 @@ enum class HealingManaEfficiency : uint8
|
||||
|
||||
class PlayerbotAIConfig
|
||||
{
|
||||
public:
|
||||
PlayerbotAIConfig() { };
|
||||
public:
|
||||
PlayerbotAIConfig(){};
|
||||
static PlayerbotAIConfig* instance()
|
||||
{
|
||||
static PlayerbotAIConfig instance;
|
||||
@ -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];
|
||||
|
||||
@ -215,7 +214,7 @@ class PlayerbotAIConfig
|
||||
bool randomBotSayWithoutMaster;
|
||||
bool sayWhenCollectingItems;
|
||||
bool randomBotGroupNearby;
|
||||
uint32 tweakValue; //Debugging config
|
||||
uint32 tweakValue; // Debugging config
|
||||
|
||||
uint32 randomBotArenaTeamCount;
|
||||
uint32 randomBotArenaTeamMaxRating;
|
||||
@ -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
|
||||
@ -7,9 +8,9 @@
|
||||
|
||||
class PlayerbotCommandServer
|
||||
{
|
||||
public:
|
||||
PlayerbotCommandServer() { }
|
||||
virtual ~PlayerbotCommandServer() { }
|
||||
public:
|
||||
PlayerbotCommandServer() {}
|
||||
virtual ~PlayerbotCommandServer() {}
|
||||
static PlayerbotCommandServer* instance()
|
||||
{
|
||||
static PlayerbotCommandServer instance;
|
||||
|
||||
@ -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,21 +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.
|
||||
*/
|
||||
|
||||
#ifndef _PLAYERBOT_PLAYERBOTDBSTORE_H
|
||||
#define _PLAYERBOT_PLAYERBOTDBSTORE_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class PlayerbotDbStore
|
||||
{
|
||||
public:
|
||||
PlayerbotDbStore() { }
|
||||
virtual ~PlayerbotDbStore() { }
|
||||
public:
|
||||
PlayerbotDbStore() {}
|
||||
virtual ~PlayerbotDbStore() {}
|
||||
static PlayerbotDbStore* instance()
|
||||
{
|
||||
static PlayerbotDbStore instance;
|
||||
@ -26,7 +27,7 @@ class PlayerbotDbStore
|
||||
void Load(PlayerbotAI* botAI);
|
||||
void Reset(PlayerbotAI* botAI);
|
||||
|
||||
private:
|
||||
private:
|
||||
void SaveValue(uint32 guid, std::string const key, std::string const value);
|
||||
std::string const FormatStrategies(std::string const type, std::vector<std::string> strategies);
|
||||
};
|
||||
|
||||
@ -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;
|
||||
@ -23,9 +24,9 @@ struct DungeonSuggestion
|
||||
|
||||
class PlayerbotDungeonSuggestionMgr
|
||||
{
|
||||
public:
|
||||
PlayerbotDungeonSuggestionMgr() { };
|
||||
~PlayerbotDungeonSuggestionMgr() { };
|
||||
public:
|
||||
PlayerbotDungeonSuggestionMgr(){};
|
||||
~PlayerbotDungeonSuggestionMgr(){};
|
||||
static PlayerbotDungeonSuggestionMgr* instance()
|
||||
{
|
||||
static PlayerbotDungeonSuggestionMgr instance;
|
||||
@ -35,7 +36,7 @@ class PlayerbotDungeonSuggestionMgr
|
||||
void LoadDungeonSuggestions();
|
||||
std::vector<DungeonSuggestion> const GetDungeonSuggestions();
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<DungeonSuggestion> m_dungeonSuggestions;
|
||||
};
|
||||
|
||||
|
||||
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
|
||||
@ -23,7 +24,7 @@ struct EnchantTemplate
|
||||
|
||||
typedef std::vector<EnchantTemplate> EnchantContainer;
|
||||
|
||||
//TODO: more spec/role
|
||||
// TODO: more spec/role
|
||||
/* classid+talenttree
|
||||
enum spec : uint8
|
||||
{
|
||||
@ -103,7 +104,7 @@ enum PriorizedConsumables
|
||||
|
||||
class PlayerbotFactory
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PlayerbotFactory(Player* bot, uint32 level, uint32 itemQuality = 0, uint32 gearScoreLimit = 0);
|
||||
|
||||
static ObjectGuid GetRandomBot();
|
||||
@ -137,7 +138,8 @@ class PlayerbotFactory
|
||||
void ApplyEnchantAndGemsNew(bool destoryOld = true);
|
||||
void InitInstanceQuests();
|
||||
void UnbindInstance();
|
||||
private:
|
||||
|
||||
private:
|
||||
void Prepare();
|
||||
// void InitSecondEquipmentSet();
|
||||
// void InitEquipmentNew(bool incremental);
|
||||
@ -194,7 +196,8 @@ class PlayerbotFactory
|
||||
std::vector<uint32> trainerIdCache;
|
||||
static std::vector<uint32> enchantSpellIdCache;
|
||||
static std::vector<uint32> enchantGemIdCache;
|
||||
protected:
|
||||
|
||||
protected:
|
||||
EnchantContainer m_EnchantContainer;
|
||||
Player* bot;
|
||||
PlayerbotAI* botAI;
|
||||
|
||||
@ -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,32 +20,26 @@
|
||||
#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
|
||||
{
|
||||
private:
|
||||
private:
|
||||
uint32 masterAccountId;
|
||||
PlayerbotHolder* playerbotHolder;
|
||||
|
||||
public:
|
||||
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);
|
||||
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,14 +310,16 @@ 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;
|
||||
}
|
||||
|
||||
TravelTarget* target = nullptr;
|
||||
if (botAI->GetAiObjectContext()) //Maybe some day re-write to delate all pointer values.
|
||||
if (botAI->GetAiObjectContext()) // Maybe some day re-write to delate all pointer values.
|
||||
{
|
||||
target = botAI->GetAiObjectContext()->GetValue<TravelTarget*>("travel target")->Get();
|
||||
}
|
||||
@ -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!");
|
||||
@ -364,7 +388,7 @@ void PlayerbotHolder::DisablePlayerBot(ObjectGuid guid)
|
||||
|
||||
bot->SaveToDB(false, false);
|
||||
|
||||
if (botAI->GetAiObjectContext()) //Maybe some day re-write to delate all pointer values.
|
||||
if (botAI->GetAiObjectContext()) // Maybe some day re-write to delate all pointer values.
|
||||
{
|
||||
TravelTarget* target = botAI->GetAiObjectContext()->GetValue<TravelTarget*>("travel target")->Get();
|
||||
if (target)
|
||||
@ -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,16 +426,16 @@ 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();
|
||||
if (master)
|
||||
{
|
||||
ObjectGuid masterGuid = master->GetGUID();
|
||||
if (master->GetGroup() && ! master->GetGroup()->IsLeader(masterGuid))
|
||||
if (master->GetGroup() && !master->GetGroup()->IsLeader(masterGuid))
|
||||
master->GetGroup()->ChangeLeader(masterGuid);
|
||||
}
|
||||
|
||||
@ -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";
|
||||
@ -754,61 +806,78 @@ std::vector<std::string> PlayerbotHolder::HandlePlayerbotCommand(char const* arg
|
||||
return messages;
|
||||
}
|
||||
|
||||
char* cmd = strtok ((char*)args, " ");
|
||||
char* charname = strtok (nullptr, " ");
|
||||
char* cmd = strtok((char*)args, " ");
|
||||
char* charname = strtok(nullptr, " ");
|
||||
if (!cmd)
|
||||
{
|
||||
messages.push_back("usage: list/reload/tweak/self or add/init/remove PLAYERNAME or addclass CLASSNAME");
|
||||
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
|
||||
@ -1147,7 +1227,7 @@ std::string const PlayerbotHolder::ListBots(Player* master)
|
||||
Group::MemberSlotList const& groupSlot = group->GetMemberSlots();
|
||||
for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++)
|
||||
{
|
||||
Player *member = ObjectAccessor::FindPlayer(itr->guid);
|
||||
Player* member = ObjectAccessor::FindPlayer(itr->guid);
|
||||
if (member && sRandomPlayerbotMgr->IsRandomBot(member))
|
||||
{
|
||||
std::string const name = member->GetName();
|
||||
@ -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())
|
||||
@ -1334,10 +1418,11 @@ void PlayerbotMgr::SaveToDB()
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerbotMgr::OnBotLoginInternal(Player * const bot)
|
||||
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;
|
||||
@ -21,9 +22,9 @@ typedef std::map<std::string, std::set<std::string> > PlayerBotErrorMap;
|
||||
|
||||
class PlayerbotHolder : public PlayerbotAIBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PlayerbotHolder();
|
||||
virtual ~PlayerbotHolder() { };
|
||||
virtual ~PlayerbotHolder(){};
|
||||
|
||||
void AddPlayerBot(ObjectGuid guid, uint32 masterAccountId);
|
||||
void HandlePlayerBotLoginCallback(PlayerbotLoginQueryHolder const& holder);
|
||||
@ -35,7 +36,7 @@ class PlayerbotHolder : public PlayerbotAIBase
|
||||
PlayerBotMap::const_iterator GetPlayerBotsBegin() const { return playerBots.begin(); }
|
||||
PlayerBotMap::const_iterator GetPlayerBotsEnd() const { return playerBots.end(); }
|
||||
|
||||
void UpdateAIInternal([[maybe_unused]] uint32 elapsed, [[maybe_unused]] bool minimal = false) override { };
|
||||
void UpdateAIInternal([[maybe_unused]] uint32 elapsed, [[maybe_unused]] bool minimal = false) override{};
|
||||
void UpdateSessions();
|
||||
void HandleBotPackets(WorldSession* session);
|
||||
|
||||
@ -43,14 +44,16 @@ 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:
|
||||
|
||||
protected:
|
||||
virtual void OnBotLoginInternal(Player* const bot) = 0;
|
||||
|
||||
PlayerBotMap playerBots;
|
||||
@ -58,7 +61,7 @@ class PlayerbotHolder : public PlayerbotAIBase
|
||||
|
||||
class PlayerbotMgr : public PlayerbotHolder
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PlayerbotMgr(Player* const master);
|
||||
virtual ~PlayerbotMgr();
|
||||
|
||||
@ -76,11 +79,11 @@ class PlayerbotMgr : public PlayerbotHolder
|
||||
|
||||
void SaveToDB();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void OnBotLoginInternal(Player* const bot) override;
|
||||
void CheckTellErrors(uint32 elapsed);
|
||||
|
||||
private:
|
||||
private:
|
||||
Player* const master;
|
||||
PlayerBotErrorMap errors;
|
||||
time_t lastErrorTell;
|
||||
@ -88,9 +91,9 @@ class PlayerbotMgr : public PlayerbotHolder
|
||||
|
||||
class PlayerbotsMgr
|
||||
{
|
||||
public:
|
||||
PlayerbotsMgr() { }
|
||||
~PlayerbotsMgr() { }
|
||||
public:
|
||||
PlayerbotsMgr() {}
|
||||
~PlayerbotsMgr() {}
|
||||
|
||||
static PlayerbotsMgr* instance()
|
||||
{
|
||||
@ -104,7 +107,7 @@ class PlayerbotsMgr
|
||||
PlayerbotAI* GetPlayerbotAI(Player* player);
|
||||
PlayerbotMgr* GetPlayerbotMgr(Player* player);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::unordered_map<ObjectGuid, PlayerbotAIBase*> _playerbotsAIMap;
|
||||
std::unordered_map<ObjectGuid, PlayerbotAIBase*> _playerbotsMgrMap;
|
||||
};
|
||||
|
||||
@ -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
|
||||
@ -40,13 +41,13 @@ enum DenyReason
|
||||
|
||||
class PlayerbotSecurity
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PlayerbotSecurity(Player* const bot);
|
||||
|
||||
PlayerbotSecurityLevel LevelFor(Player* from, DenyReason* reason = nullptr, bool ignoreGroup = false);
|
||||
bool CheckLevelFor(PlayerbotSecurityLevel level, bool silent, Player* from, bool ignoreGroup = false);
|
||||
|
||||
private:
|
||||
private:
|
||||
Player* const bot;
|
||||
uint32 account;
|
||||
std::map<ObjectGuid, std::map<std::string, time_t> > whispers;
|
||||
|
||||
@ -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];
|
||||
for (auto & placeholder : placeholders)
|
||||
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;
|
||||
@ -149,7 +153,7 @@ bool PlayerbotTextMgr::rollTextChance(std::string name)
|
||||
return urand(0, 100) < botTextChance[name];
|
||||
}
|
||||
|
||||
bool PlayerbotTextMgr::GetBotText(std::string name, std::string &text)
|
||||
bool PlayerbotTextMgr::GetBotText(std::string name, std::string& text)
|
||||
{
|
||||
if (!rollTextChance(name))
|
||||
return false;
|
||||
@ -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;
|
||||
@ -54,14 +62,15 @@ enum ChatReplyType
|
||||
|
||||
class PlayerbotTextMgr
|
||||
{
|
||||
public:
|
||||
PlayerbotTextMgr() {
|
||||
public:
|
||||
PlayerbotTextMgr()
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_LOCALES; ++i)
|
||||
{
|
||||
botTextLocalePriority[i] = 0;
|
||||
}
|
||||
};
|
||||
virtual ~PlayerbotTextMgr() { };
|
||||
virtual ~PlayerbotTextMgr(){};
|
||||
static PlayerbotTextMgr* instance()
|
||||
{
|
||||
static PlayerbotTextMgr instance;
|
||||
@ -83,9 +92,9 @@ class PlayerbotTextMgr
|
||||
void AddLocalePriority(uint32 locale);
|
||||
void ResetLocalePriority();
|
||||
|
||||
private:
|
||||
private:
|
||||
std::map<std::string, std::vector<BotTextEntry>> botTexts;
|
||||
std::map<std::string, uint32 > botTextChance;
|
||||
std::map<std::string, uint32> botTextChance;
|
||||
uint32 botTextLocalePriority[MAX_LOCALES];
|
||||
};
|
||||
|
||||
|
||||
@ -15,45 +15,39 @@
|
||||
* 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
|
||||
{
|
||||
public:
|
||||
PlayerbotsDatabaseScript() : DatabaseScript("PlayerbotsDatabaseScript") { }
|
||||
public:
|
||||
PlayerbotsDatabaseScript() : DatabaseScript("PlayerbotsDatabaseScript") {}
|
||||
|
||||
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>();
|
||||
@ -78,8 +73,8 @@ class PlayerbotsDatabaseScript : public DatabaseScript
|
||||
|
||||
class PlayerbotsMetricScript : public MetricScript
|
||||
{
|
||||
public:
|
||||
PlayerbotsMetricScript() : MetricScript("PlayerbotsMetricScript") { }
|
||||
public:
|
||||
PlayerbotsMetricScript() : MetricScript("PlayerbotsMetricScript") {}
|
||||
|
||||
void OnMetricLogging() override
|
||||
{
|
||||
@ -92,8 +87,8 @@ class PlayerbotsMetricScript : public MetricScript
|
||||
|
||||
class PlayerbotsPlayerScript : public PlayerScript
|
||||
{
|
||||
public:
|
||||
PlayerbotsPlayerScript() : PlayerScript("PlayerbotsPlayerScript") { }
|
||||
public:
|
||||
PlayerbotsPlayerScript() : PlayerScript("PlayerbotsPlayerScript") {}
|
||||
|
||||
void OnLogin(Player* player) override
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -200,8 +196,8 @@ class PlayerbotsPlayerScript : public PlayerScript
|
||||
|
||||
class PlayerbotsMiscScript : public MiscScript
|
||||
{
|
||||
public:
|
||||
PlayerbotsMiscScript() : MiscScript("PlayerbotsMiscScript", {MISCHOOK_ON_DESTRUCT_PLAYER}) { }
|
||||
public:
|
||||
PlayerbotsMiscScript() : MiscScript("PlayerbotsMiscScript", {MISCHOOK_ON_DESTRUCT_PLAYER}) {}
|
||||
|
||||
void OnDestructPlayer(Player* player) override
|
||||
{
|
||||
@ -219,8 +215,8 @@ class PlayerbotsMiscScript : public MiscScript
|
||||
|
||||
class PlayerbotsServerScript : public ServerScript
|
||||
{
|
||||
public:
|
||||
PlayerbotsServerScript() : ServerScript("PlayerbotsServerScript") { }
|
||||
public:
|
||||
PlayerbotsServerScript() : ServerScript("PlayerbotsServerScript") {}
|
||||
|
||||
void OnPacketReceived(WorldSession* session, WorldPacket const& packet) override
|
||||
{
|
||||
@ -232,8 +228,8 @@ class PlayerbotsServerScript : public ServerScript
|
||||
|
||||
class PlayerbotsWorldScript : public WorldScript
|
||||
{
|
||||
public:
|
||||
PlayerbotsWorldScript() : WorldScript("PlayerbotsWorldScript") { }
|
||||
public:
|
||||
PlayerbotsWorldScript() : WorldScript("PlayerbotsWorldScript") {}
|
||||
|
||||
void OnBeforeWorldInitialized() override
|
||||
{
|
||||
@ -251,8 +247,8 @@ class PlayerbotsWorldScript : public WorldScript
|
||||
|
||||
class PlayerbotsScript : public PlayerbotScript
|
||||
{
|
||||
public:
|
||||
PlayerbotsScript() : PlayerbotScript("PlayerbotsScript") { }
|
||||
public:
|
||||
PlayerbotsScript() : PlayerbotScript("PlayerbotsScript") {}
|
||||
|
||||
bool OnPlayerbotCheckLFGQueue(lfg::Lfg5Guids const& guidsList) override
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -81,7 +83,7 @@ struct ItemInfoEntry
|
||||
};
|
||||
|
||||
typedef std::vector<WeightScaleStat> WeightScaleStats;
|
||||
//typedef std::map<WeightScaleInfo, WeightScaleStats> WeightScaleList;
|
||||
// typedef std::map<WeightScaleInfo, WeightScaleStats> WeightScaleList;
|
||||
|
||||
struct WeightScale
|
||||
{
|
||||
@ -89,12 +91,12 @@ struct WeightScale
|
||||
WeightScaleStats stats;
|
||||
};
|
||||
|
||||
//typedef map<uint32, WeightScale> WeightScales;
|
||||
// typedef map<uint32, WeightScale> WeightScales;
|
||||
|
||||
class RandomItemPredicate
|
||||
{
|
||||
public:
|
||||
virtual ~RandomItemPredicate() { };
|
||||
public:
|
||||
virtual ~RandomItemPredicate(){};
|
||||
|
||||
virtual bool Apply(ItemTemplate const* proto) = 0;
|
||||
};
|
||||
@ -104,15 +106,18 @@ typedef std::map<RandomItemType, RandomItemList> RandomItemCache;
|
||||
|
||||
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
|
||||
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())
|
||||
{
|
||||
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;
|
||||
@ -120,7 +125,7 @@ class BotEquipKey
|
||||
uint32 quality;
|
||||
uint64 key;
|
||||
|
||||
private:
|
||||
private:
|
||||
uint64 GetKey();
|
||||
};
|
||||
|
||||
@ -128,7 +133,7 @@ typedef std::map<BotEquipKey, RandomItemList> BotEquipCache;
|
||||
|
||||
class RandomItemMgr
|
||||
{
|
||||
public:
|
||||
public:
|
||||
RandomItemMgr();
|
||||
virtual ~RandomItemMgr();
|
||||
static RandomItemMgr* instance()
|
||||
@ -137,14 +142,15 @@ class RandomItemMgr
|
||||
return &instance;
|
||||
}
|
||||
|
||||
public:
|
||||
public:
|
||||
void Init();
|
||||
void InitAfterAhBot();
|
||||
static bool HandleConsoleCommand(ChatHandler* handler, char const* args);
|
||||
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);
|
||||
@ -168,7 +174,7 @@ class RandomItemMgr
|
||||
bool IsTestItem(uint32 itemId) { return itemForTest.find(itemId) != itemForTest.end(); }
|
||||
std::vector<uint32> GetCachedEquipments(uint32 requiredLevel, uint32 inventoryType);
|
||||
|
||||
private:
|
||||
private:
|
||||
void BuildRandomItemCache();
|
||||
void BuildEquipCache();
|
||||
void BuildEquipCacheNew();
|
||||
@ -182,19 +188,20 @@ 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:
|
||||
|
||||
private:
|
||||
std::map<uint32, RandomItemCache> randomItemCache;
|
||||
std::map<RandomItemType, RandomItemPredicate*> predicates;
|
||||
BotEquipCache equipCache;
|
||||
std::map<EquipmentSlots, std::set<InventoryType>> viableSlots;
|
||||
std::map<uint32, std::map<uint32, uint32> > ammoCache;
|
||||
std::map<uint32, std::map<uint32, std::vector<uint32> > > potionCache;
|
||||
std::map<uint32, std::map<uint32, std::vector<uint32> > > foodCache;
|
||||
std::map<uint32, std::vector<uint32> > tradeCache;
|
||||
std::map<uint32, std::map<uint32, uint32>> ammoCache;
|
||||
std::map<uint32, std::map<uint32, std::vector<uint32>>> potionCache;
|
||||
std::map<uint32, std::map<uint32, std::vector<uint32>>> foodCache;
|
||||
std::map<uint32, std::vector<uint32>> tradeCache;
|
||||
std::map<uint32, float> rarityCache;
|
||||
std::map<uint8, WeightScale> m_weightScales[MAX_CLASSES];
|
||||
std::map<std::string, uint32 > weightStatLink;
|
||||
std::map<std::string, uint32 > weightRatingLink;
|
||||
std::map<std::string, uint32> weightStatLink;
|
||||
std::map<std::string, uint32> weightRatingLink;
|
||||
std::map<uint32, ItemInfoEntry> itemInfoCache;
|
||||
std::set<uint32> itemForTest;
|
||||
static std::set<uint32> itemCache;
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -26,14 +28,14 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
|
||||
availableRaces[CLASS_WARRIOR].push_back(RACE_UNDEAD_PLAYER);
|
||||
availableRaces[CLASS_WARRIOR].push_back(RACE_TAUREN);
|
||||
availableRaces[CLASS_WARRIOR].push_back(RACE_TROLL);
|
||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
{
|
||||
availableRaces[CLASS_WARRIOR].push_back(RACE_DRAENEI);
|
||||
}
|
||||
|
||||
availableRaces[CLASS_PALADIN].push_back(RACE_HUMAN);
|
||||
availableRaces[CLASS_PALADIN].push_back(RACE_DWARF);
|
||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
{
|
||||
availableRaces[CLASS_PALADIN].push_back(RACE_DRAENEI);
|
||||
availableRaces[CLASS_PALADIN].push_back(RACE_BLOODELF);
|
||||
@ -45,7 +47,7 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
|
||||
availableRaces[CLASS_ROGUE].push_back(RACE_GNOME);
|
||||
availableRaces[CLASS_ROGUE].push_back(RACE_ORC);
|
||||
availableRaces[CLASS_ROGUE].push_back(RACE_TROLL);
|
||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
{
|
||||
availableRaces[CLASS_ROGUE].push_back(RACE_BLOODELF);
|
||||
}
|
||||
@ -55,7 +57,7 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
|
||||
availableRaces[CLASS_PRIEST].push_back(RACE_NIGHTELF);
|
||||
availableRaces[CLASS_PRIEST].push_back(RACE_TROLL);
|
||||
availableRaces[CLASS_PRIEST].push_back(RACE_UNDEAD_PLAYER);
|
||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
{
|
||||
availableRaces[CLASS_PRIEST].push_back(RACE_DRAENEI);
|
||||
availableRaces[CLASS_PRIEST].push_back(RACE_BLOODELF);
|
||||
@ -65,7 +67,7 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
|
||||
availableRaces[CLASS_MAGE].push_back(RACE_GNOME);
|
||||
availableRaces[CLASS_MAGE].push_back(RACE_UNDEAD_PLAYER);
|
||||
availableRaces[CLASS_MAGE].push_back(RACE_TROLL);
|
||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
{
|
||||
availableRaces[CLASS_MAGE].push_back(RACE_DRAENEI);
|
||||
availableRaces[CLASS_MAGE].push_back(RACE_BLOODELF);
|
||||
@ -75,7 +77,7 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
|
||||
availableRaces[CLASS_WARLOCK].push_back(RACE_GNOME);
|
||||
availableRaces[CLASS_WARLOCK].push_back(RACE_UNDEAD_PLAYER);
|
||||
availableRaces[CLASS_WARLOCK].push_back(RACE_ORC);
|
||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
{
|
||||
availableRaces[CLASS_WARLOCK].push_back(RACE_BLOODELF);
|
||||
}
|
||||
@ -83,7 +85,7 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
|
||||
availableRaces[CLASS_SHAMAN].push_back(RACE_ORC);
|
||||
availableRaces[CLASS_SHAMAN].push_back(RACE_TAUREN);
|
||||
availableRaces[CLASS_SHAMAN].push_back(RACE_TROLL);
|
||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
{
|
||||
availableRaces[CLASS_SHAMAN].push_back(RACE_DRAENEI);
|
||||
}
|
||||
@ -93,7 +95,7 @@ RandomPlayerbotFactory::RandomPlayerbotFactory(uint32 accountId) : accountId(acc
|
||||
availableRaces[CLASS_HUNTER].push_back(RACE_ORC);
|
||||
availableRaces[CLASS_HUNTER].push_back(RACE_TAUREN);
|
||||
availableRaces[CLASS_HUNTER].push_back(RACE_TROLL);
|
||||
if(expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
if (expansion >= EXPANSION_THE_BURNING_CRUSADE)
|
||||
{
|
||||
availableRaces[CLASS_HUNTER].push_back(RACE_DRAENEI);
|
||||
availableRaces[CLASS_HUNTER].push_back(RACE_BLOODELF);
|
||||
@ -124,22 +126,25 @@ 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;
|
||||
}
|
||||
CharacterDatabase.DirectExecute("UPDATE playerbots_names SET in_use=1 WHERE name='{}'", name);
|
||||
|
||||
std::vector<uint8> skinColors, facialHairTypes;
|
||||
std::vector<std::pair<uint8,uint8>> faces, hairs;
|
||||
std::vector<std::pair<uint8, uint8>> faces, hairs;
|
||||
for (CharSectionsEntry const* charSection : sCharSectionsStore)
|
||||
{
|
||||
if (charSection->Race != race || charSection->Gender != gender)
|
||||
@ -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;
|
||||
@ -215,66 +227,57 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
|
||||
}
|
||||
}
|
||||
|
||||
//CONLANG NAME GENERATION
|
||||
// CONLANG NAME GENERATION
|
||||
LOG_ERROR("playerbots", "No more names left for random bots. Attempting conlang name generation.");
|
||||
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"}
|
||||
};
|
||||
// S C V K R U
|
||||
{"dtspkThfS", "bcCdfghjkmnNqqrrlsStTvwxyz", "aaeeiouA", "ppttkkbdg", "lmmnrr", "AEO"},
|
||||
{"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"}
|
||||
};
|
||||
{"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"}};
|
||||
|
||||
tries = 10;
|
||||
while (--tries)
|
||||
{
|
||||
botName.clear();
|
||||
//Build name from groupForms
|
||||
//Pick random start group
|
||||
botName = groupFormStart[gender][rand()%4];
|
||||
//Pick up to 2 and then up to 1 additional middle group
|
||||
for (int i = 0; i < rand()%3 + rand()%2; i++)
|
||||
// Build name from groupForms
|
||||
// Pick random start group
|
||||
botName = groupFormStart[gender][rand() % 4];
|
||||
// Pick up to 2 and then up to 1 additional middle group
|
||||
for (int i = 0; i < rand() % 3 + rand() % 2; i++)
|
||||
{
|
||||
botName += groupFormMid[gender][rand()%6];
|
||||
botName += groupFormMid[gender][rand() % 6];
|
||||
}
|
||||
//Pick up to 1 end group
|
||||
botName += rand()%2 ? groupFormEnd[gender][rand()%4] : "";
|
||||
//If name is single letter add random end group
|
||||
botName += (botName.size() < 2) ? groupFormEnd[gender][rand()%4] : "";
|
||||
// Pick up to 1 end group
|
||||
botName += rand() % 2 ? groupFormEnd[gender][rand() % 4] : "";
|
||||
// If name is single letter add random end group
|
||||
botName += (botName.size() < 2) ? groupFormEnd[gender][rand() % 4] : "";
|
||||
|
||||
//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++)
|
||||
// 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
|
||||
// Itterate over replace rules
|
||||
for (int i = 0; i < 17; i++)
|
||||
{
|
||||
int j = botName.find(replaceRule[0][i]);
|
||||
while ( j > -1)
|
||||
while (j > -1)
|
||||
{
|
||||
botName.replace(j,replaceRule[0][i].size(),replaceRule[1][i]);
|
||||
botName.replace(j, replaceRule[0][i].size(), replaceRule[1][i]);
|
||||
j = botName.find(replaceRule[0][i]);
|
||||
}
|
||||
}
|
||||
|
||||
//Capitalize first letter
|
||||
// Capitalize first letter
|
||||
botName[0] -= 32;
|
||||
|
||||
if (ObjectMgr::CheckPlayerName(botName) != CHAR_NAME_SUCCESS ||
|
||||
@ -286,11 +289,13 @@ std::string const RandomPlayerbotFactory::CreateRandomBotName(uint8 gender)
|
||||
return std::move(botName);
|
||||
}
|
||||
|
||||
//TRUE RANDOM NAME GENERATION
|
||||
// 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...");
|
||||
@ -374,7 +380,7 @@ void RandomPlayerbotFactory::CreateRandomBots()
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
password += (char) urand('!', 'z');
|
||||
password += (char)urand('!', 'z');
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -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);
|
||||
@ -697,10 +715,11 @@ void RandomPlayerbotFactory::CreateRandomArenaTeams(ArenaType type, uint32 count
|
||||
arenateam->SetEmblem(backgroundColor, emblemStyle, emblemColor, borderStyle, borderColor);
|
||||
|
||||
// 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_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->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;
|
||||
@ -19,9 +20,9 @@ enum ArenaType : uint8;
|
||||
|
||||
class RandomPlayerbotFactory
|
||||
{
|
||||
public:
|
||||
public:
|
||||
RandomPlayerbotFactory(uint32 accountId);
|
||||
virtual ~RandomPlayerbotFactory() { }
|
||||
virtual ~RandomPlayerbotFactory() {}
|
||||
|
||||
Player* CreateRandomBot(WorldSession* session, uint8 cls);
|
||||
static void CreateRandomBots();
|
||||
@ -29,7 +30,7 @@ class RandomPlayerbotFactory
|
||||
static void CreateRandomArenaTeams(ArenaType slot, uint32 count);
|
||||
static std::string const CreateRandomGuildName();
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string const CreateRandomBotName(uint8 gender);
|
||||
static std::string const CreateRandomArenaTeamName();
|
||||
|
||||
|
||||
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;
|
||||
@ -43,21 +45,27 @@ class WorldLocation;
|
||||
|
||||
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) { }
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsEmpty() { return !lastChangeTime; }
|
||||
|
||||
public:
|
||||
public:
|
||||
uint32 value;
|
||||
uint32 lastChangeTime;
|
||||
uint32 validIn;
|
||||
std::string data;
|
||||
};
|
||||
|
||||
//https://gist.github.com/bradley219/5373998
|
||||
// https://gist.github.com/bradley219/5373998
|
||||
|
||||
class botPIDImpl;
|
||||
class botPID
|
||||
@ -82,7 +90,7 @@ private:
|
||||
|
||||
class RandomPlayerbotMgr : public PlayerbotHolder
|
||||
{
|
||||
public:
|
||||
public:
|
||||
RandomPlayerbotMgr();
|
||||
virtual ~RandomPlayerbotMgr();
|
||||
static RandomPlayerbotMgr* instance()
|
||||
@ -94,10 +102,10 @@ class RandomPlayerbotMgr : public PlayerbotHolder
|
||||
void LogPlayerLocation();
|
||||
void UpdateAIInternal(uint32 elapsed, bool minimal = false) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void ScaleBotActivity();
|
||||
|
||||
public:
|
||||
public:
|
||||
uint32 activeBots = 0;
|
||||
static bool HandlePlayerbotConsoleCommand(ChatHandler* handler, char const* args);
|
||||
bool IsRandomBot(Player* bot);
|
||||
@ -150,22 +158,26 @@ 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; }
|
||||
void setActivityPercentage(float percentage) { activityMod = percentage / 100.0f; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void OnBotLoginInternal(Player* const bot) override;
|
||||
|
||||
private:
|
||||
//pid values are set in constructor
|
||||
private:
|
||||
// pid values are set in constructor
|
||||
botPID pid = botPID(1, 50, -50, 0, 0, 0);
|
||||
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;
|
||||
@ -178,7 +190,7 @@ class RandomPlayerbotMgr : public PlayerbotHolder
|
||||
void RandomTeleport(Player* bot, std::vector<WorldLocation>& locs, bool hearth = false);
|
||||
uint32 GetZoneLevel(uint16 mapId, float teleX, float teleY, float teleZ);
|
||||
void PrepareTeleportCache();
|
||||
typedef void(RandomPlayerbotMgr::*ConsoleCommandHandler)(Player*);
|
||||
typedef void (RandomPlayerbotMgr::*ConsoleCommandHandler)(Player*);
|
||||
|
||||
std::vector<Player*> players;
|
||||
uint32 processTicks;
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -15,7 +17,7 @@ float ServerFacade::GetDistance2d(Unit* unit, WorldObject* wo)
|
||||
return std::round(dist * 10.0f) / 10.0f;
|
||||
}
|
||||
|
||||
float ServerFacade::GetDistance2d(Unit *unit, float x, float y)
|
||||
float ServerFacade::GetDistance2d(Unit* unit, float x, float y)
|
||||
{
|
||||
float dist = unit->GetDistance2d(x, y);
|
||||
return std::round(dist * 10.0f) / 10.0f;
|
||||
@ -23,25 +25,19 @@ float ServerFacade::GetDistance2d(Unit *unit, float x, float y)
|
||||
|
||||
bool ServerFacade::IsDistanceLessThan(float dist1, float dist2)
|
||||
{
|
||||
//return dist1 - dist2 < sPlayerbotAIConfig->targetPosRecalcDistance;
|
||||
// return dist1 - dist2 < sPlayerbotAIConfig->targetPosRecalcDistance;
|
||||
return dist1 < dist2;
|
||||
}
|
||||
|
||||
bool ServerFacade::IsDistanceGreaterThan(float dist1, float dist2)
|
||||
{
|
||||
//return dist1 - dist2 > sPlayerbotAIConfig->targetPosRecalcDistance;
|
||||
// return dist1 - dist2 > sPlayerbotAIConfig->targetPosRecalcDistance;
|
||||
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
|
||||
@ -13,16 +14,16 @@ class WorldObject;
|
||||
|
||||
class ServerFacade
|
||||
{
|
||||
public:
|
||||
ServerFacade() { };
|
||||
virtual ~ServerFacade() { };
|
||||
public:
|
||||
ServerFacade(){};
|
||||
virtual ~ServerFacade(){};
|
||||
static ServerFacade* instance()
|
||||
{
|
||||
static ServerFacade instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
public:
|
||||
public:
|
||||
float GetDistance2d(Unit* unit, WorldObject* wo);
|
||||
float GetDistance2d(Unit* unit, float x, float y);
|
||||
bool IsDistanceLessThan(float dist1, float dist2);
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -11,7 +13,7 @@ uint32 TalentSpec::TalentListEntry::tabPage() const
|
||||
return talentTabInfo->TalentTabID == 41 ? 1 : talentTabInfo->tabpage;
|
||||
}
|
||||
|
||||
//Checks a talent link on basic validity.
|
||||
// Checks a talent link on basic validity.
|
||||
bool TalentSpec::CheckTalentLink(std::string const link, std::ostringstream* out)
|
||||
{
|
||||
std::string const validChar = "-";
|
||||
@ -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)
|
||||
{
|
||||
@ -73,7 +72,7 @@ TalentSpec::TalentSpec(Player* bot, std::string const link)
|
||||
ReadTalents(link);
|
||||
}
|
||||
|
||||
//Check the talentspec for errors.
|
||||
// Check the talentspec for errors.
|
||||
bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
|
||||
{
|
||||
for (auto& entry : talents)
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -137,17 +139,18 @@ bool TalentSpec::CheckTalents(uint32 level, std::ostringstream* out)
|
||||
return true;
|
||||
}
|
||||
|
||||
//Set the talents for the bots to the current spec.
|
||||
// Set the talents for the bots to the current spec.
|
||||
void TalentSpec::ApplyTalents(Player* bot, std::ostringstream* out)
|
||||
{
|
||||
for (auto& entry : talents) {
|
||||
for (auto& entry : talents)
|
||||
{
|
||||
if (entry.rank == 0)
|
||||
continue;
|
||||
bot->LearnTalent(entry.talentInfo->TalentID, entry.rank - 1);
|
||||
}
|
||||
}
|
||||
|
||||
//Returns a base talentlist for a class.
|
||||
// Returns a base talentlist for a class.
|
||||
void TalentSpec::GetTalents(uint32 classMask)
|
||||
{
|
||||
TalentListEntry entry;
|
||||
@ -185,7 +188,7 @@ void TalentSpec::GetTalents(uint32 classMask)
|
||||
SortTalents(talents, SORT_BY_DEFAULT);
|
||||
}
|
||||
|
||||
//Sorts a talent list by page, row, column.
|
||||
// Sorts a talent list by page, row, column.
|
||||
bool sortTalentMap(TalentSpec::TalentListEntry i, TalentSpec::TalentListEntry j, uint32* tabSort)
|
||||
{
|
||||
uint32 itab = i.tabPage();
|
||||
@ -208,38 +211,35 @@ 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.
|
||||
// Sort the talents.
|
||||
void TalentSpec::SortTalents(std::vector<TalentListEntry>& talents, uint32 sortBy)
|
||||
{
|
||||
switch (sortBy)
|
||||
{
|
||||
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);
|
||||
});
|
||||
uint32 tabSort[] = {0, 1, 2};
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Set the talent ranks to the current rank of the player.
|
||||
// Set the talent ranks to the current rank of the player.
|
||||
void TalentSpec::ReadTalents(Player* bot)
|
||||
{
|
||||
for (auto& entry : talents)
|
||||
@ -257,7 +257,7 @@ void TalentSpec::ReadTalents(Player* bot)
|
||||
}
|
||||
}
|
||||
|
||||
//Set the talent ranks to the ranks of the link.
|
||||
// Set the talent ranks to the ranks of the link.
|
||||
void TalentSpec::ReadTalents(std::string const link)
|
||||
{
|
||||
uint32 rank = 0;
|
||||
@ -308,7 +308,7 @@ void TalentSpec::ReadTalents(std::string const link)
|
||||
}
|
||||
}
|
||||
|
||||
//Returns only a specific tree from a talent list.
|
||||
// Returns only a specific tree from a talent list.
|
||||
std::vector<TalentSpec::TalentListEntry> TalentSpec::GetTalentTree(uint32 tabpage)
|
||||
{
|
||||
std::vector<TalentListEntry> retList;
|
||||
@ -320,12 +320,9 @@ 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.
|
||||
// Counts the point in a talent list.
|
||||
uint32 TalentSpec::GetTalentPoints(std::vector<TalentListEntry>& talents, int32 tabpage)
|
||||
{
|
||||
if (tabpage == -1)
|
||||
@ -339,7 +336,7 @@ uint32 TalentSpec::GetTalentPoints(std::vector<TalentListEntry>& talents, int32
|
||||
return tPoints;
|
||||
}
|
||||
|
||||
//Generates a wow-head link from a talent list.
|
||||
// Generates a wow-head link from a talent list.
|
||||
std::string const TalentSpec::GetTalentLink()
|
||||
{
|
||||
std::string link = "";
|
||||
@ -403,7 +400,7 @@ std::string const TalentSpec::FormatSpec(Player* bot)
|
||||
uint8 cls = bot->getClass();
|
||||
|
||||
std::ostringstream out;
|
||||
//out << chathelper:: specs[cls][highestTree()] << " (";
|
||||
// out << chathelper:: specs[cls][highestTree()] << " (";
|
||||
|
||||
uint32 c0 = GetTalentPoints(0);
|
||||
uint32 c1 = GetTalentPoints(1);
|
||||
@ -416,7 +413,7 @@ std::string const TalentSpec::FormatSpec(Player* bot)
|
||||
return out.str();
|
||||
}
|
||||
|
||||
//Removes talentpoints to match the level
|
||||
// Removes talentpoints to match the level
|
||||
void TalentSpec::CropTalents(uint32 level)
|
||||
{
|
||||
if (points <= LeveltoPoints(level))
|
||||
@ -436,8 +433,10 @@ void TalentSpec::CropTalents(uint32 level)
|
||||
SortTalents(talents, SORT_BY_DEFAULT);
|
||||
}
|
||||
|
||||
//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)
|
||||
// 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> deltaList = newList;
|
||||
|
||||
@ -466,35 +465,35 @@ bool TalentSpec::isEarlierVersionOf(TalentSpec& newSpec)
|
||||
return true;
|
||||
}
|
||||
|
||||
//Modifies current talents towards new talents up to a maxium of points.
|
||||
// Modifies current talents towards new talents up to a maxium of points.
|
||||
void TalentSpec::ShiftTalents(TalentSpec* currentSpec, uint32 level)
|
||||
{
|
||||
uint32 currentPoints = currentSpec->GetTalentPoints();
|
||||
if (points >= LeveltoPoints(level)) //We have no more points to spend. Better reset and crop
|
||||
if (points >= LeveltoPoints(level)) // We have no more points to spend. Better reset and crop
|
||||
{
|
||||
CropTalents(level);
|
||||
return;
|
||||
}
|
||||
|
||||
SortTalents(SORT_BY_POINTS_TREE); //Apply points first to the largest new tree.
|
||||
SortTalents(SORT_BY_POINTS_TREE); // Apply points first to the largest new tree.
|
||||
|
||||
std::vector<TalentSpec::TalentListEntry> deltaList = SubTalentList(currentSpec->talents, talents);
|
||||
|
||||
for (auto& entry : deltaList)
|
||||
{
|
||||
if (entry.rank < 0) //We have to remove talents. Might as well reset and crop the new list.
|
||||
if (entry.rank < 0) // We have to remove talents. Might as well reset and crop the new list.
|
||||
{
|
||||
CropTalents(level);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Start from the current spec.
|
||||
// Start from the current spec.
|
||||
talents = currentSpec->talents;
|
||||
|
||||
for (auto& entry : deltaList)
|
||||
{
|
||||
if (entry.rank + points > LeveltoPoints(level)) //Running out of points. Only apply what we have left.
|
||||
if (entry.rank + points > LeveltoPoints(level)) // Running out of points. Only apply what we have left.
|
||||
entry.rank = std::max(0, std::abs(int32(LeveltoPoints(level) - points)));
|
||||
|
||||
for (auto& subentry : talents)
|
||||
|
||||
@ -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
|
||||
@ -21,7 +22,7 @@ struct TalentTabEntry;
|
||||
// unused currently
|
||||
class TalentSpec
|
||||
{
|
||||
public:
|
||||
public:
|
||||
struct TalentListEntry
|
||||
{
|
||||
uint32 entry;
|
||||
@ -32,8 +33,8 @@ class TalentSpec
|
||||
uint32 tabPage() const;
|
||||
};
|
||||
|
||||
TalentSpec() { };
|
||||
virtual ~TalentSpec() { }
|
||||
TalentSpec(){};
|
||||
virtual ~TalentSpec() {}
|
||||
TalentSpec(uint32 classMask);
|
||||
TalentSpec(TalentSpec* base, std::string const link);
|
||||
TalentSpec(Player* bot);
|
||||
@ -56,7 +57,7 @@ class TalentSpec
|
||||
uint32 highestTree();
|
||||
std::string const FormatSpec(Player* bot);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
uint32 LeveltoPoints(uint32 level) const;
|
||||
uint32 PointstoLevel(uint32 points) const;
|
||||
void GetTalents(uint32 classMask);
|
||||
@ -67,12 +68,13 @@ 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
|
||||
{
|
||||
public:
|
||||
public:
|
||||
TalentPath(uint32 pathId, std::string const pathName, uint32 pathProbability)
|
||||
{
|
||||
id = pathId;
|
||||
@ -88,8 +90,8 @@ class TalentPath
|
||||
|
||||
class ClassSpecs
|
||||
{
|
||||
public:
|
||||
ClassSpecs() { };
|
||||
public:
|
||||
ClassSpecs(){};
|
||||
ClassSpecs(uint32 specsClassMask)
|
||||
{
|
||||
classMask = specsClassMask;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
478
src/TravelMgr.h
478
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;
|
||||
@ -24,12 +25,12 @@ struct QuestStatusData;
|
||||
|
||||
namespace G3D
|
||||
{
|
||||
class Vector2;
|
||||
class Vector3;
|
||||
class Vector4;
|
||||
}
|
||||
class Vector2;
|
||||
class Vector3;
|
||||
class Vector4;
|
||||
} // namespace G3D
|
||||
|
||||
//Constructor types for WorldPosition
|
||||
// Constructor types for WorldPosition
|
||||
enum WorldPositionConst
|
||||
{
|
||||
WP_RANDOM = 0,
|
||||
@ -65,7 +66,7 @@ enum TravelStatus
|
||||
|
||||
class QuestTravelDestination;
|
||||
|
||||
//A quest destination container for quick lookup of all destinations related to a quest.
|
||||
// A quest destination container for quick lookup of all destinations related to a quest.
|
||||
struct QuestContainer
|
||||
{
|
||||
std::vector<QuestTravelDestination*> questGivers;
|
||||
@ -75,16 +76,19 @@ struct QuestContainer
|
||||
|
||||
typedef std::pair<int32, int32> mGridCoord;
|
||||
|
||||
//Extension of WorldLocation with distance functions.
|
||||
// Extension of WorldLocation with distance functions.
|
||||
class WorldPosition : public WorldLocation
|
||||
{
|
||||
public:
|
||||
//Constructors
|
||||
WorldPosition() : WorldLocation() { };
|
||||
WorldPosition(WorldLocation const& loc) : WorldLocation(loc) { }
|
||||
WorldPosition(WorldPosition const& pos) : WorldLocation(pos), visitors(pos.visitors) { }
|
||||
public:
|
||||
// Constructors
|
||||
WorldPosition() : 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);
|
||||
@ -93,7 +97,7 @@ class WorldPosition : public WorldLocation
|
||||
WorldPosition(uint32 mapid, CellCoord cell);
|
||||
WorldPosition(uint32 mapid, mGridCoord grid);
|
||||
|
||||
//Setters
|
||||
// Setters
|
||||
void set(const WorldLocation& pos);
|
||||
void setMapId(uint32 id);
|
||||
void setX(float x);
|
||||
@ -101,20 +105,14 @@ 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
|
||||
// Getters
|
||||
operator bool() const;
|
||||
friend bool operator==(WorldPosition const& p1, const WorldPosition &p2);
|
||||
friend bool operator!=(WorldPosition const& p1, const WorldPosition &p2);
|
||||
friend bool operator==(WorldPosition const& p1, const WorldPosition& p2);
|
||||
friend bool operator!=(WorldPosition const& p1, const WorldPosition& p2);
|
||||
|
||||
WorldPosition& operator=(WorldPosition const&) = default;
|
||||
WorldPosition& operator+=(WorldPosition const& p1);
|
||||
@ -132,7 +130,7 @@ class WorldPosition : public WorldLocation
|
||||
std::string const to_string();
|
||||
|
||||
void printWKT(std::vector<WorldPosition> points, std::ostringstream& out, uint32 dim = 0, bool loop = false);
|
||||
void printWKT(std::ostringstream& out) { printWKT({ *this }, out); }
|
||||
void printWKT(std::ostringstream& out) { printWKT({*this}, out); }
|
||||
|
||||
uint32 getVisitors() { return visitors; }
|
||||
|
||||
@ -144,78 +142,83 @@ class WorldPosition : public WorldLocation
|
||||
WorldPosition offset(WorldPosition* center);
|
||||
float size();
|
||||
|
||||
//Slow distance function using possible map transfers.
|
||||
// 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>
|
||||
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>
|
||||
template <class T>
|
||||
std::pair<T, WorldPosition> closest(std::vector<T> list)
|
||||
{
|
||||
return closest(GetPosList(list));
|
||||
}
|
||||
|
||||
//Returns the closest point from the list.
|
||||
// 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.
|
||||
// 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.
|
||||
// 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.
|
||||
// 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,22 +227,19 @@ 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);
|
||||
|
||||
float mSign(WorldPosition* p1, WorldPosition* p2)
|
||||
{
|
||||
return(getX() - p2->getX()) * (p1->getY() - p2->getY()) - (p1->getX() - p2->getX()) * (getY() - p2->getY());
|
||||
return (getX() - p2->getX()) * (p1->getY() - p2->getY()) - (p1->getX() - p2->getX()) * (getY() - p2->getY());
|
||||
}
|
||||
|
||||
bool isInside(WorldPosition* p1, WorldPosition* p2, WorldPosition* p3);
|
||||
|
||||
//Map functions. Player independent.
|
||||
// Map functions. Player independent.
|
||||
MapEntry const* getMapEntry();
|
||||
uint32 getInstanceId();
|
||||
Map* getMap();
|
||||
@ -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
|
||||
// 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();
|
||||
@ -290,21 +282,21 @@ class WorldPosition : public WorldLocation
|
||||
|
||||
std::vector<WorldPosition> fromPointsArray(std::vector<G3D::Vector3> path);
|
||||
|
||||
//Pathfinding
|
||||
// Pathfinding
|
||||
std::vector<WorldPosition> getPathStepFrom(WorldPosition startPos, Unit* bot);
|
||||
std::vector<WorldPosition> getPathFromPath(std::vector<WorldPosition> startPath, Unit* bot, uint8 maxAttempt = 40);
|
||||
|
||||
std::vector<WorldPosition> getPathFrom(WorldPosition startPos, Unit* bot)
|
||||
{
|
||||
return getPathFromPath({ startPos }, bot);
|
||||
return getPathFromPath({startPos}, bot);
|
||||
}
|
||||
|
||||
std::vector<WorldPosition> getPathTo(WorldPosition endPos, Unit* bot)
|
||||
std::vector<WorldPosition> getPathTo(WorldPosition endPos, Unit* bot) { return endPos.getPathFrom(*this, bot); }
|
||||
|
||||
bool isPathTo(std::vector<WorldPosition> path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance)
|
||||
{
|
||||
return endPos.getPathFrom(*this, bot);
|
||||
}
|
||||
|
||||
bool isPathTo(std::vector<WorldPosition> path, float maxDistance = sPlayerbotAIConfig->targetPosRecalcDistance) { return !path.empty() && distance(path.back()) < maxDistance; };
|
||||
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)); }
|
||||
|
||||
@ -326,13 +318,13 @@ class WorldPosition : public WorldLocation
|
||||
|
||||
uint32 getUnitsAggro(GuidVector& units, Player* bot);
|
||||
|
||||
//Creatures
|
||||
// Creatures
|
||||
std::vector<CreatureData const*> getCreaturesNear(float radius = 0, uint32 entry = 0);
|
||||
|
||||
//GameObjects
|
||||
// GameObjects
|
||||
std::vector<GameObjectData const*> getGameObjectsNear(float radius = 0, uint32 entry = 0);
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 visitors = 0;
|
||||
};
|
||||
|
||||
@ -365,16 +357,21 @@ inline ByteBuffer& operator>>(ByteBuffer& b, [[maybe_unused]] WorldPosition& g)
|
||||
return b;
|
||||
}
|
||||
|
||||
//Generic creature finder
|
||||
// Generic creature finder
|
||||
class FindPointCreatureData
|
||||
{
|
||||
public:
|
||||
FindPointCreatureData(WorldPosition point1 = WorldPosition(), float radius1 = 0, uint32 entry1 = 0) { point = point1; radius = radius1; entry = entry1; }
|
||||
public:
|
||||
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; };
|
||||
|
||||
private:
|
||||
private:
|
||||
WorldPosition point;
|
||||
float radius;
|
||||
uint32 entry;
|
||||
@ -382,16 +379,21 @@ class FindPointCreatureData
|
||||
std::vector<CreatureData const*> data;
|
||||
};
|
||||
|
||||
//Generic gameObject finder
|
||||
// Generic gameObject finder
|
||||
class FindPointGameObjectData
|
||||
{
|
||||
public:
|
||||
FindPointGameObjectData(WorldPosition point1 = WorldPosition(), float radius1 = 0, uint32 entry1 = 0) { point = point1; radius = radius1; entry = entry1; }
|
||||
public:
|
||||
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; };
|
||||
|
||||
private:
|
||||
private:
|
||||
WorldPosition point;
|
||||
float radius;
|
||||
uint32 entry;
|
||||
@ -401,8 +403,8 @@ class FindPointGameObjectData
|
||||
|
||||
class GuidPosition : public ObjectGuid, public WorldPosition
|
||||
{
|
||||
public:
|
||||
GuidPosition() : ObjectGuid(), WorldPosition(), loadedFromDB(false) { }
|
||||
public:
|
||||
GuidPosition() : ObjectGuid(), WorldPosition(), loadedFromDB(false) {}
|
||||
GuidPosition(WorldObject* wo);
|
||||
GuidPosition(CreatureData const& creData);
|
||||
GuidPosition(GameObjectData const& goData);
|
||||
@ -418,18 +420,18 @@ class GuidPosition : public ObjectGuid, public WorldPosition
|
||||
|
||||
bool HasNpcFlag(NPCFlags flag);
|
||||
|
||||
bool isDead(); //For loaded grids check if the unit/object is unloaded/dead.
|
||||
bool isDead(); // For loaded grids check if the unit/object is unloaded/dead.
|
||||
|
||||
operator bool() const { return !IsEmpty(); }
|
||||
bool operator==(ObjectGuid const& guid) const { return GetRawValue() == guid.GetRawValue(); }
|
||||
bool operator!=(ObjectGuid const& guid) const { return GetRawValue() != guid.GetRawValue(); }
|
||||
bool operator<(ObjectGuid const& guid) const { return GetRawValue() < guid.GetRawValue(); }
|
||||
|
||||
private:
|
||||
private:
|
||||
bool loadedFromDB;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
std::vector<std::pair<T, WorldPosition>> GetPosList(std::vector<T> oList)
|
||||
{
|
||||
std::vector<std::pair<T, WorldPosition>> retList;
|
||||
@ -439,7 +441,7 @@ std::vector<std::pair<T, WorldPosition>> GetPosList(std::vector<T> oList)
|
||||
return std::move(retList);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
std::vector<std::pair<T, WorldPosition>> GetPosVector(std::vector<T> oList)
|
||||
{
|
||||
std::vector<std::pair<T, WorldPosition>> retList;
|
||||
@ -451,44 +453,28 @@ std::vector<std::pair<T, WorldPosition>> GetPosVector(std::vector<T> oList)
|
||||
|
||||
class mapTransfer
|
||||
{
|
||||
public:
|
||||
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)
|
||||
{
|
||||
@ -497,41 +483,35 @@ class mapTransfer
|
||||
|
||||
float fDist(WorldPosition start, WorldPosition end);
|
||||
|
||||
private:
|
||||
private:
|
||||
WorldPosition pointFrom;
|
||||
WorldPosition pointTo;
|
||||
float portalLength = 0.1f;
|
||||
};
|
||||
|
||||
//A destination for a bot to travel to and do something.
|
||||
// A destination for a bot to travel to and do something.
|
||||
class TravelDestination
|
||||
{
|
||||
public:
|
||||
TravelDestination() { }
|
||||
public:
|
||||
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,15 +542,21 @@ 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);
|
||||
std::vector<WorldPosition*> sortedPoints(WorldPosition* pos);
|
||||
std::vector<WorldPosition*> nextPoint(WorldPosition* pos, bool ignoreFull = true);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
std::vector<WorldPosition*> points;
|
||||
float radiusMin = 0;
|
||||
float radiusMax = 0;
|
||||
@ -591,10 +568,10 @@ class TravelDestination
|
||||
uint32 cooldownDelay = 60 * 1000;
|
||||
};
|
||||
|
||||
//A travel target that is always inactive and jumps to cooldown.
|
||||
// A travel target that is always inactive and jumps to cooldown.
|
||||
class NullTravelDestination : public TravelDestination
|
||||
{
|
||||
public:
|
||||
public:
|
||||
NullTravelDestination(uint32 cooldownDelay1 = 5 * 60 * 1000) : TravelDestination()
|
||||
{
|
||||
cooldownDelay = cooldownDelay1;
|
||||
@ -611,10 +588,10 @@ class NullTravelDestination : public TravelDestination
|
||||
bool isOut([[maybe_unused]] WorldPosition* pos, [[maybe_unused]] float radius = 0.f) override { return false; }
|
||||
};
|
||||
|
||||
//A travel target specifically related to a quest.
|
||||
// A travel target specifically related to a quest.
|
||||
class QuestTravelDestination : public TravelDestination
|
||||
{
|
||||
public:
|
||||
public:
|
||||
QuestTravelDestination(uint32 questId1, float radiusMin1, float radiusMax1);
|
||||
|
||||
Quest const* GetQuestTemplate() override { return questTemplate; }
|
||||
@ -625,17 +602,18 @@ class QuestTravelDestination : public TravelDestination
|
||||
int32 getEntry() override { return 0; }
|
||||
std::string const getTitle() override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
uint32 questId;
|
||||
Quest const* questTemplate;
|
||||
};
|
||||
|
||||
//A quest giver or taker.
|
||||
// A quest giver or taker.
|
||||
class QuestRelationTravelDestination : public QuestTravelDestination
|
||||
{
|
||||
public:
|
||||
QuestRelationTravelDestination(uint32 quest_id1, uint32 entry1, uint32 relation1, float radiusMin1, float radiusMax1) :
|
||||
QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
|
||||
public:
|
||||
QuestRelationTravelDestination(uint32 quest_id1, uint32 entry1, uint32 relation1, float radiusMin1,
|
||||
float radiusMax1)
|
||||
: QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
|
||||
{
|
||||
entry = entry1;
|
||||
relation = relation1;
|
||||
@ -647,17 +625,18 @@ class QuestRelationTravelDestination : public QuestTravelDestination
|
||||
std::string const getTitle() override;
|
||||
virtual uint32 getRelation() { return relation; }
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 relation;
|
||||
int32 entry;
|
||||
};
|
||||
|
||||
//A quest objective (creature/gameobject to grind/loot)
|
||||
// A quest objective (creature/gameobject to grind/loot)
|
||||
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)
|
||||
public:
|
||||
QuestObjectiveTravelDestination(uint32 quest_id1, uint32 entry1, uint32 objective1, float radiusMin1,
|
||||
float radiusMax1, uint32 itemId1 = 0)
|
||||
: QuestTravelDestination(quest_id1, radiusMin1, radiusMax1)
|
||||
{
|
||||
objective = objective1;
|
||||
entry = entry1;
|
||||
@ -674,16 +653,16 @@ class QuestObjectiveTravelDestination : public QuestTravelDestination
|
||||
int32 getEntry() override { return entry; }
|
||||
std::string const getTitle() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 objective;
|
||||
uint32 entry;
|
||||
uint32 itemId = 0;
|
||||
};
|
||||
|
||||
//A location with rpg target(s) based on race and level
|
||||
// A location with rpg target(s) based on race and level
|
||||
class RpgTravelDestination : public TravelDestination
|
||||
{
|
||||
public:
|
||||
public:
|
||||
RpgTravelDestination(uint32 entry1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1)
|
||||
{
|
||||
entry = entry1;
|
||||
@ -695,15 +674,16 @@ class RpgTravelDestination : public TravelDestination
|
||||
int32 getEntry() override { return 0; }
|
||||
std::string const getTitle() override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
uint32 entry;
|
||||
};
|
||||
|
||||
//A location with zone exploration target(s)
|
||||
// A location with zone exploration target(s)
|
||||
class ExploreTravelDestination : public TravelDestination
|
||||
{
|
||||
public:
|
||||
ExploreTravelDestination(uint32 areaId1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1)
|
||||
public:
|
||||
ExploreTravelDestination(uint32 areaId1, float radiusMin1, float radiusMax1)
|
||||
: TravelDestination(radiusMin1, radiusMax1)
|
||||
{
|
||||
areaId = areaId1;
|
||||
}
|
||||
@ -715,15 +695,15 @@ class ExploreTravelDestination : public TravelDestination
|
||||
virtual void setTitle(std::string newTitle) { title = newTitle; }
|
||||
virtual uint32 getAreaId() { return areaId; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
uint32 areaId;
|
||||
std::string title = "";
|
||||
};
|
||||
|
||||
//A location with zone exploration target(s)
|
||||
// A location with zone exploration target(s)
|
||||
class GrindTravelDestination : public TravelDestination
|
||||
{
|
||||
public:
|
||||
public:
|
||||
GrindTravelDestination(int32 entry1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1)
|
||||
{
|
||||
entry = entry1;
|
||||
@ -735,14 +715,14 @@ class GrindTravelDestination : public TravelDestination
|
||||
int32 getEntry() override { return entry; }
|
||||
std::string const getTitle() override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
int32 entry;
|
||||
};
|
||||
|
||||
//A location with a boss
|
||||
// A location with a boss
|
||||
class BossTravelDestination : public TravelDestination
|
||||
{
|
||||
public:
|
||||
public:
|
||||
BossTravelDestination(int32 entry1, float radiusMin1, float radiusMax1) : TravelDestination(radiusMin1, radiusMax1)
|
||||
{
|
||||
entry = entry1;
|
||||
@ -755,22 +735,23 @@ class BossTravelDestination : public TravelDestination
|
||||
int32 getEntry() override { return entry; }
|
||||
std::string const getTitle() override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
int32 entry;
|
||||
};
|
||||
|
||||
//Current target and location for the bot to travel to.
|
||||
//The flow is as follows:
|
||||
//PREPARE (wait until no loot is near)
|
||||
//TRAVEL (move towards target until close enough) (rpg and grind is disabled)
|
||||
//WORK (grind/rpg until the target is no longer active) (rpg and grind is enabled on quest mobs)
|
||||
//COOLDOWN (wait some time free to do what the bot wants)
|
||||
//EXPIRE (if any of the above actions take too long pick a new target)
|
||||
// Current target and location for the bot to travel to.
|
||||
// The flow is as follows:
|
||||
// PREPARE (wait until no loot is near)
|
||||
// TRAVEL (move towards target until close enough) (rpg and grind is disabled)
|
||||
// WORK (grind/rpg until the target is no longer active) (rpg and grind is enabled on quest mobs)
|
||||
// COOLDOWN (wait some time free to do what the bot wants)
|
||||
// EXPIRE (if any of the above actions take too long pick a new target)
|
||||
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())
|
||||
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())
|
||||
{
|
||||
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,54 +799,30 @@ 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:
|
||||
protected:
|
||||
TravelStatus m_status;
|
||||
|
||||
uint32 startTime;
|
||||
@ -892,11 +840,11 @@ class TravelTarget : AiObject
|
||||
WorldPosition* wPosition = nullptr;
|
||||
};
|
||||
|
||||
//General container for all travel destinations.
|
||||
// General container for all travel destinations.
|
||||
class TravelMgr
|
||||
{
|
||||
public:
|
||||
TravelMgr() { };
|
||||
public:
|
||||
TravelMgr(){};
|
||||
|
||||
static TravelMgr* instance()
|
||||
{
|
||||
@ -912,7 +860,7 @@ class TravelMgr
|
||||
{
|
||||
while (first != last && first_weight != last_weight)
|
||||
{
|
||||
std::discrete_distribution<int>dd(first_weight, last_weight);
|
||||
std::discrete_distribution<int> dd(first_weight, last_weight);
|
||||
auto i = dd(g);
|
||||
|
||||
if (i)
|
||||
@ -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)
|
||||
{
|
||||
@ -969,7 +918,7 @@ class TravelMgr
|
||||
void printGrid(uint32 mapId, int x, int y, std::string const type);
|
||||
void printObj(WorldObject* obj, std::string const type);
|
||||
|
||||
//protected:
|
||||
// protected:
|
||||
void logQuestError(uint32 errorNr, Quest* quest, uint32 objective = 0, uint32 unitId = 0, uint32 itemId = 0);
|
||||
|
||||
std::vector<uint32> avoidLoaded;
|
||||
@ -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()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
245
src/TravelNode.h
245
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>
|
||||
|
||||
//THEORY
|
||||
#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.
|
||||
@ -56,17 +62,26 @@ enum class TravelNodePathType : uint8
|
||||
teleportSpell = 5
|
||||
};
|
||||
|
||||
//A connection between two nodes.
|
||||
// A connection between two nodes.
|
||||
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);
|
||||
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);
|
||||
|
||||
//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
|
||||
// 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
|
||||
{
|
||||
if (pathType != (uint8)TravelNodePathType::walk)
|
||||
complete = true;
|
||||
@ -94,8 +109,8 @@ class TravelNodePath
|
||||
|
||||
float getDistance() { return distance; }
|
||||
float getSwimDistance() { return swimDistance; }
|
||||
float getExtraCost(){ return extraCost; }
|
||||
std::vector<uint8> getMaxLevelCreature(){ return maxLevelCreature; }
|
||||
float getExtraCost() { return extraCost; }
|
||||
std::vector<uint8> getMaxLevelCreature() { return maxLevelCreature; }
|
||||
|
||||
void setCalculated(bool calculated1 = true) { calculated = calculated1; }
|
||||
|
||||
@ -103,16 +118,10 @@ class TravelNodePath
|
||||
|
||||
std::string const print();
|
||||
|
||||
//Setters
|
||||
void setComplete(bool complete1)
|
||||
{
|
||||
complete = complete1;
|
||||
}
|
||||
// Setters
|
||||
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)
|
||||
{
|
||||
@ -121,43 +130,37 @@ class TravelNodePath
|
||||
extraCost = distance / speed;
|
||||
}
|
||||
|
||||
//void setPortal(bool portal1, uint32 portalId1 = 0) { portal = portal1; portalId = portalId1; }
|
||||
//void setTransport(bool transport1) { transport = transport1; }
|
||||
// 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);
|
||||
|
||||
float getCost(Player* bot = nullptr, uint32 cGold = 0);
|
||||
uint32 getPrice();
|
||||
|
||||
private:
|
||||
//Does the path have all the points to get to the destination?
|
||||
private:
|
||||
// Does the path have all the points to get to the destination?
|
||||
bool complete = false;
|
||||
|
||||
//List of WorldPositions to get to the destination.
|
||||
// List of WorldPositions to get to the destination.
|
||||
std::vector<WorldPosition> path = {};
|
||||
|
||||
//The extra (loading/transport) time it takes to take this path.
|
||||
// The extra (loading/transport) time it takes to take this path.
|
||||
float extraCost = 0;
|
||||
|
||||
bool calculated = false;
|
||||
|
||||
//Derived distance in yards
|
||||
// Derived distance in yards
|
||||
float distance = 0.1f;
|
||||
|
||||
//Calculated mobs level along the way.
|
||||
std::vector<uint8> maxLevelCreature = { 0, 0, 0 }; //mobs, horde, alliance
|
||||
// Calculated mobs level along the way.
|
||||
std::vector<uint8> maxLevelCreature = {0, 0, 0}; // mobs, horde, alliance
|
||||
|
||||
//Calculated swiming distances along the way.
|
||||
// Calculated swiming distances along the way.
|
||||
float swimDistance = 0;
|
||||
|
||||
TravelNodePathType pathType = TravelNodePathType::walk;
|
||||
@ -177,13 +180,13 @@ class TravelNodePath
|
||||
*/
|
||||
};
|
||||
|
||||
//A waypoint to travel from or to.
|
||||
//Each node knows which other nodes can be reached without help.
|
||||
// A waypoint to travel from or to.
|
||||
// Each node knows which other nodes can be reached without help.
|
||||
class TravelNode
|
||||
{
|
||||
public:
|
||||
//Constructors
|
||||
TravelNode() { };
|
||||
public:
|
||||
// Constructors
|
||||
TravelNode(){};
|
||||
|
||||
TravelNode(WorldPosition point1, std::string const nodeName1 = "Travel Node", bool important1 = false)
|
||||
{
|
||||
@ -199,11 +202,11 @@ class TravelNode
|
||||
important = baseNode->important;
|
||||
}
|
||||
|
||||
//Setters
|
||||
// Setters
|
||||
void setLinked(bool linked1) { linked = linked1; }
|
||||
void setPoint(WorldPosition point1) { point = point1; }
|
||||
|
||||
//Getters
|
||||
// Getters
|
||||
std::string const getName() { return nodeName; };
|
||||
WorldPosition* getPosition() { return &point; };
|
||||
std::unordered_map<TravelNode*, TravelNodePath>* getPaths() { return &paths; }
|
||||
@ -247,7 +250,7 @@ class TravelNode
|
||||
return false;
|
||||
}
|
||||
|
||||
//WorldLocation shortcuts
|
||||
// WorldLocation shortcuts
|
||||
uint32 getMapId() { return point.getMapId(); }
|
||||
float getX() { return point.getX(); }
|
||||
float getY() { return point.getY(); }
|
||||
@ -295,12 +298,12 @@ class TravelNode
|
||||
|
||||
bool isEqual(TravelNode* compareNode);
|
||||
|
||||
//Removes links to other nodes that can also be reached by passing another node.
|
||||
// Removes links to other nodes that can also be reached by passing another node.
|
||||
bool isUselessLink(TravelNode* farNode);
|
||||
void cropUselessLink(TravelNode* farNode);
|
||||
bool cropUselessLinks();
|
||||
|
||||
//Returns all nodes that can be reached from this node.
|
||||
// Returns all nodes that can be reached from this node.
|
||||
std::vector<TravelNode*> getNodeMap(bool importantOnly = false, std::vector<TravelNode*> ignoreNodes = {});
|
||||
|
||||
// Checks if it is even possible to route to this node.
|
||||
@ -315,36 +318,36 @@ class TravelNode
|
||||
|
||||
void print(bool printFailed = true);
|
||||
|
||||
protected:
|
||||
//Logical name of the node
|
||||
protected:
|
||||
// Logical name of the node
|
||||
std::string nodeName;
|
||||
//WorldPosition of the node.
|
||||
// WorldPosition of the node.
|
||||
WorldPosition point;
|
||||
|
||||
//List of paths to other nodes.
|
||||
// List of paths to other nodes.
|
||||
std::unordered_map<TravelNode*, TravelNodePath> paths;
|
||||
//List of links to other nodes.
|
||||
// List of links to other nodes.
|
||||
std::unordered_map<TravelNode*, TravelNodePath*> links;
|
||||
|
||||
//List of nodes and if there is 'any' route possible
|
||||
// List of nodes and if there is 'any' route possible
|
||||
std::unordered_map<TravelNode*, bool> routes;
|
||||
|
||||
//This node should not be removed
|
||||
// This node should not be removed
|
||||
bool important = false;
|
||||
|
||||
//This node has been checked for nearby links
|
||||
// This node has been checked for nearby links
|
||||
bool linked = false;
|
||||
|
||||
//This node is a (moving) transport.
|
||||
//bool transport = false;
|
||||
//Entry of transport.
|
||||
//uint32 transportId = 0;
|
||||
// This node is a (moving) transport.
|
||||
// bool transport = false;
|
||||
// Entry of transport.
|
||||
// uint32 transportId = 0;
|
||||
};
|
||||
|
||||
class PortalNode : public TravelNode
|
||||
{
|
||||
public:
|
||||
PortalNode(TravelNode* baseNode) : TravelNode(baseNode) { };
|
||||
public:
|
||||
PortalNode(TravelNode* baseNode) : TravelNode(baseNode){};
|
||||
|
||||
void SetPortal(TravelNode* baseNode, TravelNode* endNode, uint32 portalSpell)
|
||||
{
|
||||
@ -357,7 +360,7 @@ class PortalNode : public TravelNode
|
||||
};
|
||||
};
|
||||
|
||||
//Route step type
|
||||
// Route step type
|
||||
enum PathNodeType
|
||||
{
|
||||
NODE_PREPATH = 0,
|
||||
@ -376,11 +379,11 @@ struct PathNodePoint
|
||||
uint32 entry = 0;
|
||||
};
|
||||
|
||||
//A complete list of points the bots has to walk to or teleport to.
|
||||
// A complete list of points the bots has to walk to or teleport to.
|
||||
class TravelPath
|
||||
{
|
||||
public:
|
||||
TravelPath() { };
|
||||
public:
|
||||
TravelPath(){};
|
||||
TravelPath(std::vector<PathNodePoint> fullPath1) { fullPath = fullPath1; }
|
||||
TravelPath(std::vector<WorldPosition> path, PathNodeType type = NODE_PATH, uint32 entry = 0)
|
||||
{
|
||||
@ -388,14 +391,26 @@ 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(); }
|
||||
std::vector<PathNodePoint> getPath() { return fullPath; }
|
||||
WorldPosition getFront() {return fullPath.front().point; }
|
||||
WorldPosition getFront() { return fullPath.front().point; }
|
||||
WorldPosition getBack() { return fullPath.back().point; }
|
||||
|
||||
std::vector<WorldPosition> getPointPath()
|
||||
@ -407,20 +422,22 @@ 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();
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<PathNodePoint> fullPath;
|
||||
};
|
||||
|
||||
//An stored A* search that gives a complete route from one node to another.
|
||||
// An stored A* search that gives a complete route from one node to another.
|
||||
class TravelNodeRoute
|
||||
{
|
||||
public:
|
||||
TravelNodeRoute() { }
|
||||
public:
|
||||
TravelNodeRoute() {}
|
||||
TravelNodeRoute(std::vector<TravelNode*> nodes1) { nodes = nodes1; /*currentNode = route.begin();*/ }
|
||||
|
||||
bool isEmpty() { return nodes.empty(); }
|
||||
@ -430,19 +447,23 @@ 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); }
|
||||
private:
|
||||
std::vector<TravelNode*>::iterator findNode(TravelNode* node)
|
||||
{
|
||||
return std::find(nodes.begin(), nodes.end(), node);
|
||||
}
|
||||
std::vector<TravelNode*> nodes;
|
||||
};
|
||||
|
||||
//A node container to aid A* calculations with nodes.
|
||||
// A node container to aid A* calculations with nodes.
|
||||
class TravelNodeStub
|
||||
{
|
||||
public:
|
||||
public:
|
||||
TravelNodeStub(TravelNode* dataNode1) { dataNode = dataNode1; }
|
||||
|
||||
TravelNode* dataNode;
|
||||
@ -452,11 +473,11 @@ class TravelNodeStub
|
||||
uint32 currentGold = 0;
|
||||
};
|
||||
|
||||
//The container of all nodes.
|
||||
// The container of all nodes.
|
||||
class TravelNodeMap
|
||||
{
|
||||
public:
|
||||
TravelNodeMap() { };
|
||||
public:
|
||||
TravelNodeMap(){};
|
||||
TravelNodeMap(TravelNodeMap* baseMap);
|
||||
|
||||
static TravelNodeMap* instance()
|
||||
@ -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()
|
||||
{
|
||||
@ -483,11 +505,11 @@ class TravelNodeMap
|
||||
|
||||
void fullLinkNode(TravelNode* startNode, Unit* bot);
|
||||
|
||||
//Get all nodes
|
||||
// Get all nodes
|
||||
std::vector<TravelNode*> getNodes() { return m_nodes; }
|
||||
std::vector<TravelNode*> getNodes(WorldPosition pos, float range = -1);
|
||||
|
||||
//Find nearest node.
|
||||
// Find nearest node.
|
||||
TravelNode* getNode(TravelNode* sameNode)
|
||||
{
|
||||
for (auto& node : m_nodes)
|
||||
@ -506,7 +528,7 @@ class TravelNodeMap
|
||||
return getNode(pos, ppath, bot, range);
|
||||
}
|
||||
|
||||
//Get Random Node
|
||||
// Get Random Node
|
||||
TravelNode* getRandomNode(WorldPosition pos)
|
||||
{
|
||||
std::vector<TravelNode*> rNodes = getNodes(pos);
|
||||
@ -516,16 +538,17 @@ class TravelNodeMap
|
||||
return rNodes[urand(0, rNodes.size() - 1)];
|
||||
}
|
||||
|
||||
//Finds the best nodePath between two nodes
|
||||
// Finds the best nodePath between two nodes
|
||||
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);
|
||||
// Find the best node between two positions
|
||||
TravelNodeRoute getRoute(WorldPosition startPos, WorldPosition endPos, std::vector<WorldPosition>& startPath,
|
||||
Player* bot = nullptr);
|
||||
|
||||
//Find the full path between those locations
|
||||
// Find the full path between those locations
|
||||
static TravelPath getFullPath(WorldPosition startPos, WorldPosition endPos, Player* bot = nullptr);
|
||||
|
||||
//Manage/update nodes
|
||||
// Manage/update nodes
|
||||
void manageNodes(Unit* bot, bool mapFull = false);
|
||||
|
||||
void setHasToGen() { hasToGen = true; }
|
||||
@ -562,7 +585,7 @@ class TravelNodeMap
|
||||
std::shared_timed_mutex m_nMapMtx;
|
||||
std::unordered_map<ObjectGuid, std::unordered_map<uint32, TravelNode*>> teleportNodes;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<TravelNode*> m_nodes;
|
||||
|
||||
std::vector<std::pair<uint32, WorldPosition>> mapOffsets;
|
||||
|
||||
@ -13,39 +13,36 @@
|
||||
* 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;
|
||||
|
||||
class playerbots_commandscript : public CommandScript
|
||||
{
|
||||
public:
|
||||
playerbots_commandscript() : CommandScript("playerbots_commandscript") { }
|
||||
playerbots_commandscript() : CommandScript("playerbots_commandscript") {}
|
||||
|
||||
ChatCommandTable GetCommands() const override
|
||||
{
|
||||
static ChatCommandTable playerbotsDebugCommandTable =
|
||||
{
|
||||
{ "bg", HandleDebugBGCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
static ChatCommandTable playerbotsDebugCommandTable = {
|
||||
{"bg", HandleDebugBGCommand, SEC_GAMEMASTER, Console::Yes},
|
||||
};
|
||||
static ChatCommandTable playerbotsCommandTable =
|
||||
{
|
||||
{ "bot", HandlePlayerbotCommand, SEC_PLAYER, Console::No },
|
||||
{ "gtask", HandleGuildTaskCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
{ "pmon", HandlePerfMonCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
{ "rndbot", HandleRandomPlayerbotCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
{ "debug", playerbotsDebugCommandTable },
|
||||
static ChatCommandTable playerbotsCommandTable = {
|
||||
{"bot", HandlePlayerbotCommand, SEC_PLAYER, Console::No},
|
||||
{"gtask", HandleGuildTaskCommand, SEC_GAMEMASTER, Console::Yes},
|
||||
{"pmon", HandlePerfMonCommand, SEC_GAMEMASTER, Console::Yes},
|
||||
{"rndbot", HandleRandomPlayerbotCommand, SEC_GAMEMASTER, Console::Yes},
|
||||
{"debug", playerbotsDebugCommandTable},
|
||||
};
|
||||
|
||||
static ChatCommandTable commandTable =
|
||||
{
|
||||
{ "playerbots", playerbotsCommandTable },
|
||||
static ChatCommandTable commandTable = {
|
||||
{"playerbots", playerbotsCommandTable},
|
||||
};
|
||||
|
||||
return commandTable;
|
||||
@ -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);
|
||||
|
||||
@ -85,28 +86,19 @@ void NextAction::destroy(NextAction** actions)
|
||||
if (!actions)
|
||||
return;
|
||||
|
||||
for (uint32 i=0; actions[i]; i++)
|
||||
for (uint32 i = 0; actions[i]; i++)
|
||||
delete actions[i];
|
||||
|
||||
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
|
||||
@ -15,27 +16,28 @@ class Unit;
|
||||
|
||||
class NextAction
|
||||
{
|
||||
public:
|
||||
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
|
||||
public:
|
||||
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; }
|
||||
float getRelevance() {return relevance;}
|
||||
float getRelevance() { return relevance; }
|
||||
|
||||
static uint32 size(NextAction** actions);
|
||||
static NextAction** clone(NextAction** actions);
|
||||
static NextAction** merge(NextAction** what, NextAction** with);
|
||||
static NextAction** array(uint32 nil,...);
|
||||
static NextAction** array(uint32 nil, ...);
|
||||
static void destroy(NextAction** actions);
|
||||
|
||||
private:
|
||||
private:
|
||||
float relevance;
|
||||
std::string const name;
|
||||
};
|
||||
|
||||
class Action : public AiNamedObject
|
||||
{
|
||||
public:
|
||||
public:
|
||||
enum class ActionThreatType
|
||||
{
|
||||
None = 0,
|
||||
@ -43,8 +45,9 @@ class Action : public AiNamedObject
|
||||
Aoe = 2
|
||||
};
|
||||
|
||||
Action(PlayerbotAI* botAI, std::string const name = "action") : AiNamedObject(botAI, name), verbose(false) { } // verbose after ainamedobject - whipowill
|
||||
virtual ~Action(void) { }
|
||||
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; }
|
||||
virtual bool isPossible() { return true; }
|
||||
@ -53,8 +56,8 @@ class Action : public AiNamedObject
|
||||
virtual NextAction** getAlternatives() { return nullptr; }
|
||||
virtual NextAction** getContinuers() { return nullptr; }
|
||||
virtual ActionThreatType getThreatType() { return ActionThreatType::None; }
|
||||
void Update() { }
|
||||
void Reset() { }
|
||||
void Update() {}
|
||||
void Reset() {}
|
||||
virtual Unit* GetTarget();
|
||||
virtual Value<Unit*>* GetTargetValue();
|
||||
virtual std::string const GetTargetName() { return "self target"; }
|
||||
@ -62,16 +65,19 @@ class Action : public AiNamedObject
|
||||
void setRelevance(uint32 relevance1) { relevance = relevance1; };
|
||||
virtual float getRelevance() { return relevance; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
bool verbose;
|
||||
float relevance = 0;
|
||||
};
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
virtual ~ActionNode()
|
||||
{
|
||||
@ -85,10 +91,16 @@ 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:
|
||||
private:
|
||||
std::string const name;
|
||||
Action* action;
|
||||
NextAction** continuers;
|
||||
@ -98,20 +110,20 @@ class ActionNode
|
||||
|
||||
class ActionBasket
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ActionBasket(ActionNode* action, float relevance, bool skipPrerequisites, Event event);
|
||||
|
||||
virtual ~ActionBasket(void) { }
|
||||
virtual ~ActionBasket(void) {}
|
||||
|
||||
float getRelevance() {return relevance;}
|
||||
ActionNode* getAction() {return action;}
|
||||
float getRelevance() { return relevance; }
|
||||
ActionNode* getAction() { return action; }
|
||||
Event getEvent() { return event; }
|
||||
bool isSkipPrerequisites() { return skipPrerequisites; }
|
||||
void AmendRelevance(float k) { relevance *= k; }
|
||||
void setRelevance(float relevance) { this->relevance = relevance; }
|
||||
bool isExpired(uint32 msecs);
|
||||
|
||||
private:
|
||||
private:
|
||||
ActionNode* action;
|
||||
float relevance;
|
||||
bool skipPrerequisites;
|
||||
|
||||
@ -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
|
||||
@ -15,10 +16,10 @@ class PlayerbotAI;
|
||||
|
||||
class AiObject : public PlayerbotAIAware
|
||||
{
|
||||
public:
|
||||
public:
|
||||
AiObject(PlayerbotAI* botAI);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
Player* bot;
|
||||
Player* GetMaster();
|
||||
AiObjectContext* context;
|
||||
@ -27,13 +28,13 @@ class AiObject : public PlayerbotAIAware
|
||||
|
||||
class AiNamedObject : public AiObject
|
||||
{
|
||||
public:
|
||||
AiNamedObject(PlayerbotAI* botAI, std::string const name) : AiObject(botAI), name(name) { }
|
||||
public:
|
||||
AiNamedObject(PlayerbotAI* botAI, std::string const name) : AiObject(botAI), name(name) {}
|
||||
|
||||
public:
|
||||
public:
|
||||
virtual std::string const getName() { return name; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
std::string const name;
|
||||
};
|
||||
|
||||
@ -45,441 +46,441 @@ class AiNamedObject : public AiObject
|
||||
virtual NextAction* getNextAction() { return new NextAction(name, relevance); }
|
||||
|
||||
#define BEGIN_TRIGGER(clazz, super) \
|
||||
class clazz : public super \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : super(botAI) { } \
|
||||
bool IsActive() override; \
|
||||
|
||||
#define END_TRIGGER() \
|
||||
};
|
||||
|
||||
#define BUFF_TRIGGER(clazz, spell) \
|
||||
class clazz : public BuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffTrigger(botAI, spell) { } \
|
||||
}
|
||||
|
||||
#define BUFF_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public BuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffTrigger(botAI, spell) { } \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define BUFF_PARTY_TRIGGER(clazz, spell) \
|
||||
class clazz : public BuffOnPartyTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, spell) { } \
|
||||
}
|
||||
|
||||
#define BUFF_PARTY_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public BuffOnPartyTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, spell) { } \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define DEBUFF_TRIGGER(clazz, spell) \
|
||||
class clazz : public DebuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell) { } \
|
||||
}
|
||||
|
||||
#define DEBUFF_CHECKISOWNER_TRIGGER(clazz, spell) \
|
||||
class clazz : public DebuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell, 1, true) { } \
|
||||
}
|
||||
|
||||
#define DEBUFF_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public DebuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell) { } \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define DEBUFF_ENEMY_TRIGGER(clazz, spell) \
|
||||
class clazz : public DebuffOnAttackerTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, spell) { } \
|
||||
}
|
||||
|
||||
#define DEBUFF_ENEMY_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public DebuffOnAttackerTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, spell) { } \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define CURE_TRIGGER(clazz, spell, dispel) \
|
||||
class clazz : public NeedCureTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : NeedCureTrigger(botAI, spell, dispel) { } \
|
||||
}
|
||||
|
||||
#define CURE_PARTY_TRIGGER(clazz, spell, dispel) \
|
||||
class clazz : public PartyMemberNeedCureTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, spell, dispel) { } \
|
||||
}
|
||||
|
||||
#define CAN_CAST_TRIGGER(clazz, spell) \
|
||||
class clazz : public SpellCanBeCastTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SpellCanBeCastTrigger(botAI, spell) { } \
|
||||
}
|
||||
|
||||
#define CAN_CAST_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public SpellCanBeCastTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SpellCanBeCastTrigger(botAI, spell) { } \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define CD_TRIGGER(clazz, spell) \
|
||||
class clazz : public SpellNoCooldownTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SpellNoCooldownTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define INTERRUPT_TRIGGER(clazz, spell) \
|
||||
class clazz : public InterruptSpellTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, spell) { } \
|
||||
}
|
||||
|
||||
#define INTERRUPT_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public InterruptSpellTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, spell) { } \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define HAS_AURA_TRIGGER(clazz, spell) \
|
||||
class clazz : public HasAuraTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : HasAuraTrigger(botAI, spell) { } \
|
||||
}
|
||||
|
||||
#define HAS_AURA_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public HasAuraTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : HasAuraTrigger(botAI, spell) { } \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define SNARE_TRIGGER(clazz, spell) \
|
||||
class clazz : public SnareTargetTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, spell) { } \
|
||||
}
|
||||
|
||||
#define SNARE_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public SnareTargetTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, spell) { } \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define PROTECT_TRIGGER(clazz, spell) \
|
||||
class clazz : public ProtectPartyMemberTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : ProtectPartyMemberTrigger(botAI) { } \
|
||||
}
|
||||
|
||||
#define DEFLECT_TRIGGER(clazz, spell) \
|
||||
class clazz : public DeflectSpellTrigger \
|
||||
class clazz : public super \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DeflectSpellTrigger(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : super(botAI) {} \
|
||||
bool IsActive() override;
|
||||
|
||||
#define END_TRIGGER() \
|
||||
} \
|
||||
;
|
||||
|
||||
#define BUFF_TRIGGER(clazz, spell) \
|
||||
class clazz : public BuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define BUFF_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public BuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define BUFF_PARTY_TRIGGER(clazz, spell) \
|
||||
class clazz : public BuffOnPartyTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define BUFF_PARTY_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public BuffOnPartyTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define DEBUFF_TRIGGER(clazz, spell) \
|
||||
class clazz : public DebuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define DEBUFF_CHECKISOWNER_TRIGGER(clazz, spell) \
|
||||
class clazz : public DebuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell, 1, true) {} \
|
||||
}
|
||||
|
||||
#define DEBUFF_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public DebuffTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define DEBUFF_ENEMY_TRIGGER(clazz, spell) \
|
||||
class clazz : public DebuffOnAttackerTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define DEBUFF_ENEMY_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public DebuffOnAttackerTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DebuffOnAttackerTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define CURE_TRIGGER(clazz, spell, dispel) \
|
||||
class clazz : public NeedCureTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : NeedCureTrigger(botAI, spell, dispel) {} \
|
||||
}
|
||||
|
||||
#define CURE_PARTY_TRIGGER(clazz, spell, dispel) \
|
||||
class clazz : public PartyMemberNeedCureTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, spell, dispel) {} \
|
||||
}
|
||||
|
||||
#define CAN_CAST_TRIGGER(clazz, spell) \
|
||||
class clazz : public SpellCanBeCastTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SpellCanBeCastTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define CAN_CAST_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public SpellCanBeCastTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SpellCanBeCastTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define CD_TRIGGER(clazz, spell) \
|
||||
class clazz : public SpellNoCooldownTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SpellNoCooldownTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define INTERRUPT_TRIGGER(clazz, spell) \
|
||||
class clazz : public InterruptSpellTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define INTERRUPT_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public InterruptSpellTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define HAS_AURA_TRIGGER(clazz, spell) \
|
||||
class clazz : public HasAuraTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : HasAuraTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define HAS_AURA_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public HasAuraTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : HasAuraTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define SNARE_TRIGGER(clazz, spell) \
|
||||
class clazz : public SnareTargetTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define SNARE_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public SnareTargetTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : SnareTargetTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
|
||||
#define PROTECT_TRIGGER(clazz, spell) \
|
||||
class clazz : public ProtectPartyMemberTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : ProtectPartyMemberTrigger(botAI) {} \
|
||||
}
|
||||
|
||||
#define DEFLECT_TRIGGER(clazz, spell) \
|
||||
class clazz : public DeflectSpellTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : DeflectSpellTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define BOOST_TRIGGER(clazz, spell) \
|
||||
class clazz : public BoostTrigger \
|
||||
{ \
|
||||
class clazz : public BoostTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BoostTrigger(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : BoostTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define BOOST_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public BoostTrigger \
|
||||
{ \
|
||||
class clazz : public BoostTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BoostTrigger(botAI, spell) { } \
|
||||
clazz(PlayerbotAI* botAI) : BoostTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
}
|
||||
|
||||
#define INTERRUPT_HEALER_TRIGGER(clazz, spell) \
|
||||
class clazz : public InterruptEnemyHealerTrigger \
|
||||
{ \
|
||||
class clazz : public InterruptEnemyHealerTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define INTERRUPT_HEALER_TRIGGER_A(clazz, spell) \
|
||||
class clazz : public InterruptEnemyHealerTrigger \
|
||||
{ \
|
||||
class clazz : public InterruptEnemyHealerTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, spell) { } \
|
||||
clazz(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, spell) {} \
|
||||
bool IsActive() override; \
|
||||
}
|
||||
}
|
||||
|
||||
#define CC_TRIGGER(clazz, spell) \
|
||||
class clazz : public HasCcTargetTrigger \
|
||||
{ \
|
||||
class clazz : public HasCcTargetTrigger \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : HasCcTargetTrigger(botAI, spell) {} \
|
||||
}
|
||||
|
||||
//
|
||||
// ACTIONS
|
||||
//
|
||||
|
||||
#define MELEE_ACTION(clazz, spell) \
|
||||
class clazz : public CastMeleeSpellAction \
|
||||
{ \
|
||||
class clazz : public CastMeleeSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define MELEE_ACTION_U(clazz, spell, useful) \
|
||||
class clazz : public CastMeleeSpellAction \
|
||||
{ \
|
||||
class clazz : public CastMeleeSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, spell) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, spell) {} \
|
||||
bool isUseful() override { return useful; } \
|
||||
}
|
||||
}
|
||||
|
||||
#define SPELL_ACTION(clazz, spell) \
|
||||
class clazz : public CastSpellAction \
|
||||
{ \
|
||||
class clazz : public CastSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define SPELL_ACTION_U(clazz, spell, useful) \
|
||||
class clazz : public CastSpellAction \
|
||||
{ \
|
||||
class clazz : public CastSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, spell) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellAction(botAI, spell) {} \
|
||||
bool isUseful() override { return useful; } \
|
||||
}
|
||||
}
|
||||
|
||||
#define HEAL_ACTION(clazz, spell) \
|
||||
class clazz : public CastHealingSpellAction \
|
||||
{ \
|
||||
class clazz : public CastHealingSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define HEAL_ACTION_U(clazz, spell, useful) \
|
||||
class clazz : public CastHealingSpellAction \
|
||||
{ \
|
||||
class clazz : public CastHealingSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, spell) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastHealingSpellAction(botAI, spell) {} \
|
||||
bool isUseful() override { return useful; } \
|
||||
}
|
||||
}
|
||||
|
||||
#define HEAL_PARTY_ACTION(clazz, spell, estAmount, manaEfficiency) \
|
||||
class clazz : public HealPartyMemberAction \
|
||||
{ \
|
||||
class clazz : public HealPartyMemberAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, spell, estAmount, manaEfficiency) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, spell, estAmount, manaEfficiency) {} \
|
||||
}
|
||||
|
||||
#define AOE_HEAL_ACTION(clazz, spell, estAmount, manaEfficiency) \
|
||||
class clazz : public CastAoeHealSpellAction \
|
||||
{ \
|
||||
class clazz : public CastAoeHealSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastAoeHealSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastAoeHealSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define BUFF_ACTION(clazz, spell) \
|
||||
class clazz : public CastBuffSpellAction \
|
||||
{ \
|
||||
class clazz : public CastBuffSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define BUFF_ACTION_U(clazz, spell, useful) \
|
||||
class clazz : public CastBuffSpellAction \
|
||||
{ \
|
||||
class clazz : public CastBuffSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, spell) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, spell) {} \
|
||||
bool isUseful() override { return useful; } \
|
||||
}
|
||||
}
|
||||
|
||||
#define BUFF_PARTY_ACTION(clazz, spell) \
|
||||
class clazz : public BuffOnPartyAction \
|
||||
{ \
|
||||
class clazz : public BuffOnPartyAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define CURE_ACTION(clazz, spell) \
|
||||
class clazz : public CastCureSpellAction \
|
||||
{ \
|
||||
class clazz : public CastCureSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastCureSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastCureSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define CURE_PARTY_ACTION(clazz, spell, dispel) \
|
||||
class clazz : public CurePartyMemberAction \
|
||||
{ \
|
||||
class clazz : public CurePartyMemberAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, spell, dispel) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CurePartyMemberAction(botAI, spell, dispel) {} \
|
||||
}
|
||||
|
||||
#define RESS_ACTION(clazz, spell) \
|
||||
class clazz : public ResurrectPartyMemberAction \
|
||||
{ \
|
||||
class clazz : public ResurrectPartyMemberAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : ResurrectPartyMemberAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define DEBUFF_ACTION(clazz, spell) \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define DEBUFF_CHECKISOWNER_ACTION(clazz, spell) \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell, true) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell, true) {} \
|
||||
}
|
||||
|
||||
#define DEBUFF_ACTION_U(clazz, spell, useful) \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) {} \
|
||||
bool isUseful() override { return useful; } \
|
||||
}
|
||||
}
|
||||
|
||||
#define DEBUFF_ACTION_R(clazz, spell, distance) \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) \
|
||||
class clazz : public CastDebuffSpellAction \
|
||||
{ \
|
||||
range = distance; \
|
||||
} \
|
||||
}
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, spell) { range = distance; } \
|
||||
}
|
||||
|
||||
#define DEBUFF_ENEMY_ACTION(clazz, spell) \
|
||||
class clazz : public CastDebuffSpellOnAttackerAction \
|
||||
{ \
|
||||
class clazz : public CastDebuffSpellOnAttackerAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastDebuffSpellOnAttackerAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define REACH_ACTION(clazz, spell, range) \
|
||||
class clazz : public CastReachTargetSpellAction \
|
||||
{ \
|
||||
class clazz : public CastReachTargetSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastReachTargetSpellAction(botAI, spell, range) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastReachTargetSpellAction(botAI, spell, range) {} \
|
||||
}
|
||||
|
||||
#define REACH_ACTION_U(clazz, spell, range, useful) \
|
||||
class clazz : public CastReachTargetSpellAction \
|
||||
{ \
|
||||
class clazz : public CastReachTargetSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastReachTargetSpellAction(botAI, spell, range) { } \
|
||||
clazz(PlayerbotAI* botAI) : CastReachTargetSpellAction(botAI, spell, range) {} \
|
||||
bool isUseful() override { return useful; } \
|
||||
}
|
||||
}
|
||||
|
||||
#define ENEMY_HEALER_ACTION(clazz, spell) \
|
||||
class clazz : public CastSpellOnEnemyHealerAction \
|
||||
{ \
|
||||
class clazz : public CastSpellOnEnemyHealerAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, spell) { } \
|
||||
}
|
||||
|
||||
clazz(PlayerbotAI* botAI) : CastSpellOnEnemyHealerAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define SNARE_ACTION(clazz, spell) \
|
||||
class clazz : public CastSnareSpellAction \
|
||||
{ \
|
||||
class clazz : public CastSnareSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define CC_ACTION(clazz, spell) \
|
||||
class clazz : public CastCrowdControlSpellAction \
|
||||
{ \
|
||||
class clazz : public CastCrowdControlSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastCrowdControlSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastCrowdControlSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define PROTECT_ACTION(clazz, spell) \
|
||||
class clazz : public CastProtectSpellAction \
|
||||
{ \
|
||||
class clazz : public CastProtectSpellAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : CastProtectSpellAction(botAI, spell) { } \
|
||||
}
|
||||
clazz(PlayerbotAI* botAI) : CastProtectSpellAction(botAI, spell) {} \
|
||||
}
|
||||
|
||||
#define END_RANGED_SPELL_ACTION() \
|
||||
};
|
||||
} \
|
||||
;
|
||||
|
||||
#define BEGIN_SPELL_ACTION(clazz, name) \
|
||||
class clazz : public CastSpellAction \
|
||||
{ \
|
||||
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 \
|
||||
{ \
|
||||
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 \
|
||||
{ \
|
||||
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 \
|
||||
{ \
|
||||
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 \
|
||||
{ \
|
||||
class clazz : public BuffOnPartyAction \
|
||||
{ \
|
||||
public: \
|
||||
clazz(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, name) { }
|
||||
clazz(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, name) {}
|
||||
|
||||
//
|
||||
// Action node
|
||||
@ -487,32 +488,26 @@ class clazz : public BuffOnPartyAction \
|
||||
|
||||
// node_name , action, prerequisite
|
||||
#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, \
|
||||
static ActionNode* name(PlayerbotAI* botAI) \
|
||||
{ \
|
||||
return new ActionNode(spell, /*P*/ NextAction::array(0, new NextAction(pre), nullptr), /*A*/ nullptr, \
|
||||
/*C*/ nullptr); \
|
||||
}
|
||||
}
|
||||
|
||||
// node_name , action, alternative
|
||||
#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), \
|
||||
static ActionNode* name(PlayerbotAI* botAI) \
|
||||
{ \
|
||||
return new ActionNode(spell, /*P*/ nullptr, /*A*/ NextAction::array(0, new NextAction(alt), nullptr), \
|
||||
/*C*/ nullptr); \
|
||||
}
|
||||
}
|
||||
|
||||
// node_name , action, continuer
|
||||
#define ACTION_NODE_C(name, spell, con) \
|
||||
static ActionNode* name(PlayerbotAI* botAI) \
|
||||
{ \
|
||||
return new ActionNode(spell, \
|
||||
/*P*/ nullptr, \
|
||||
/*A*/ nullptr, \
|
||||
static ActionNode* name(PlayerbotAI* botAI) \
|
||||
{ \
|
||||
return new ActionNode(spell, /*P*/ nullptr, /*A*/ nullptr, \
|
||||
/*C*/ NextAction::array(0, new NextAction(con), nullptr)); \
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -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,16 +16,13 @@
|
||||
#include "Trigger.h"
|
||||
#include "Value.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
class PlayerbotAI;
|
||||
|
||||
class AiObjectContext : public PlayerbotAIAware
|
||||
{
|
||||
public:
|
||||
public:
|
||||
AiObjectContext(PlayerbotAI* botAI);
|
||||
virtual ~AiObjectContext() { }
|
||||
virtual ~AiObjectContext() {}
|
||||
|
||||
virtual Strategy* GetStrategy(std::string const name);
|
||||
virtual std::set<std::string> GetSiblingStrategy(std::string const name);
|
||||
@ -29,19 +30,19 @@ class AiObjectContext : public PlayerbotAIAware
|
||||
virtual Action* GetAction(std::string const name);
|
||||
virtual UntypedValue* GetUntypedValue(std::string const name);
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
Value<T>* GetValue(std::string const name)
|
||||
{
|
||||
return dynamic_cast<Value<T>*>(GetUntypedValue(name));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
Value<T>* GetValue(std::string const name, std::string const param)
|
||||
{
|
||||
return GetValue<T>((std::string(name) + "::" + param));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
Value<T>* GetValue(std::string const name, int32 param)
|
||||
{
|
||||
std::ostringstream out;
|
||||
@ -63,7 +64,7 @@ class AiObjectContext : public PlayerbotAIAware
|
||||
|
||||
std::vector<std::string> performanceStack;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
NamedObjectContextList<Strategy> strategyContexts;
|
||||
NamedObjectContextList<Action> actionContexts;
|
||||
NamedObjectContextList<Trigger> triggerContexts;
|
||||
|
||||
@ -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,11 +49,9 @@ 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)
|
||||
void CustomStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
|
||||
{
|
||||
if (actionLines.empty())
|
||||
{
|
||||
@ -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,28 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU 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
|
||||
{
|
||||
public:
|
||||
public:
|
||||
CustomStrategy(PlayerbotAI* botAI);
|
||||
|
||||
void InitTriggers(std::vector<TriggerNode*> &triggers) override;
|
||||
void InitTriggers(std::vector<TriggerNode*>& triggers) override;
|
||||
std::string const getName() override { return std::string("custom::" + qualifier); }
|
||||
void Reset();
|
||||
|
||||
static std::map<std::string, std::string> actionLinesCache;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<std::string> actionLines;
|
||||
void LoadActionLines(uint32 owner);
|
||||
};
|
||||
|
||||
@ -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,12 +174,13 @@ 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())
|
||||
{
|
||||
for (std::vector<Multiplier*>::iterator i = multipliers.begin(); i!= multipliers.end(); i++)
|
||||
for (std::vector<Multiplier*>::iterator i = multipliers.begin(); i != multipliers.end(); i++)
|
||||
{
|
||||
Multiplier* multiplier = *i;
|
||||
relevance *= multiplier->GetValue(action);
|
||||
@ -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)
|
||||
// {
|
||||
@ -312,13 +316,14 @@ ActionNode* Engine::CreateActionNode(std::string const name)
|
||||
return node;
|
||||
}
|
||||
|
||||
return new ActionNode (name,
|
||||
return new ActionNode(name,
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
}
|
||||
|
||||
bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event, char const* pushType)
|
||||
bool Engine::MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event,
|
||||
char const* pushType)
|
||||
{
|
||||
bool pushed = false;
|
||||
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();
|
||||
@ -671,13 +673,13 @@ void Engine::ChangeStrategy(std::string const names)
|
||||
switch (name[0])
|
||||
{
|
||||
case '+':
|
||||
addStrategy(name+1);
|
||||
addStrategy(name + 1);
|
||||
break;
|
||||
case '-':
|
||||
removeStrategy(name+1);
|
||||
removeStrategy(name + 1);
|
||||
break;
|
||||
case '~':
|
||||
toggleStrategy(name+1);
|
||||
toggleStrategy(name + 1);
|
||||
break;
|
||||
case '?':
|
||||
botAI->TellMaster(ListStrategies());
|
||||
|
||||
@ -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;
|
||||
@ -31,8 +32,8 @@ enum ActionResult
|
||||
|
||||
class ActionExecutionListener
|
||||
{
|
||||
public:
|
||||
virtual ~ActionExecutionListener() { };
|
||||
public:
|
||||
virtual ~ActionExecutionListener(){};
|
||||
|
||||
virtual bool Before(Action* action, Event event) = 0;
|
||||
virtual bool AllowExecution(Action* action, Event event) = 0;
|
||||
@ -42,7 +43,7 @@ class ActionExecutionListener
|
||||
|
||||
class ActionExecutionListeners : public ActionExecutionListener
|
||||
{
|
||||
public:
|
||||
public:
|
||||
virtual ~ActionExecutionListeners();
|
||||
|
||||
bool Before(Action* action, Event event) override;
|
||||
@ -50,23 +51,17 @@ 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:
|
||||
private:
|
||||
std::list<ActionExecutionListener*> listeners;
|
||||
};
|
||||
|
||||
class Engine : public PlayerbotAIAware
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Engine(PlayerbotAI* botAI, AiObjectContext* factory);
|
||||
|
||||
void Init();
|
||||
@ -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);
|
||||
private:
|
||||
bool MultiplyAndPush(NextAction** actions, float forceRelevance, bool skipPrerequisites, Event event,
|
||||
const char* pushType);
|
||||
void Reset();
|
||||
void ProcessTriggers(bool minimal);
|
||||
void PushDefaultActions();
|
||||
@ -114,7 +104,7 @@ class Engine : public PlayerbotAIAware
|
||||
|
||||
ActionExecutionListeners actionExecutionListeners;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
Queue queue;
|
||||
std::vector<TriggerNode*> triggers;
|
||||
std::vector<Multiplier*> multipliers;
|
||||
|
||||
@ -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
|
||||
@ -12,23 +13,29 @@ class Player;
|
||||
|
||||
class Event
|
||||
{
|
||||
public:
|
||||
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) { }
|
||||
public:
|
||||
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, ObjectGuid object, Player* owner = nullptr);
|
||||
virtual ~Event() { }
|
||||
virtual ~Event() {}
|
||||
|
||||
std::string const GetSource() { return source; }
|
||||
std::string const getParam() { return param; }
|
||||
WorldPacket& getPacket() { return packet; }
|
||||
ObjectGuid getObject();
|
||||
Player* getOwner() { return owner; }
|
||||
bool operator! () const { return source.empty(); }
|
||||
bool operator!() const { return source.empty(); }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
std::string source;
|
||||
std::string param;
|
||||
WorldPacket packet;
|
||||
|
||||
@ -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,28 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU 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;
|
||||
|
||||
class ExternalEventHelper
|
||||
{
|
||||
public:
|
||||
ExternalEventHelper(AiObjectContext* aiObjectContext) : aiObjectContext(aiObjectContext) { }
|
||||
public:
|
||||
ExternalEventHelper(AiObjectContext* aiObjectContext) : aiObjectContext(aiObjectContext) {}
|
||||
|
||||
bool ParseChatCommand(std::string const command, Player* owner = nullptr);
|
||||
void HandlePacket(std::map<uint16, std::string>& handlers, WorldPacket const& packet, Player* owner = nullptr);
|
||||
bool HandleCommand(std::string const name, std::string const param, Player* owner = nullptr);
|
||||
|
||||
private:
|
||||
private:
|
||||
AiObjectContext* aiObjectContext;
|
||||
};
|
||||
|
||||
|
||||
@ -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
|
||||
@ -25,16 +26,16 @@ enum IterateItemsMask : uint32
|
||||
|
||||
class IterateItemsVisitor
|
||||
{
|
||||
public:
|
||||
IterateItemsVisitor() { }
|
||||
public:
|
||||
IterateItemsVisitor() {}
|
||||
|
||||
virtual bool Visit(Item* item) = 0;
|
||||
};
|
||||
|
||||
class FindItemVisitor : public IterateItemsVisitor
|
||||
{
|
||||
public:
|
||||
FindItemVisitor() : IterateItemsVisitor(), result() { }
|
||||
public:
|
||||
FindItemVisitor() : IterateItemsVisitor(), result() {}
|
||||
|
||||
bool Visit(Item* item) override
|
||||
{
|
||||
@ -47,28 +48,28 @@ class FindItemVisitor : public IterateItemsVisitor
|
||||
|
||||
std::vector<Item*>& GetResult() { return result; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual bool Accept(ItemTemplate const* proto) = 0;
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<Item*> result;
|
||||
};
|
||||
|
||||
class FindUsableItemVisitor : public FindItemVisitor
|
||||
{
|
||||
public:
|
||||
FindUsableItemVisitor(Player* bot) : FindItemVisitor(), bot(bot) { }
|
||||
public:
|
||||
FindUsableItemVisitor(Player* bot) : FindItemVisitor(), bot(bot) {}
|
||||
|
||||
bool Visit(Item* item) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
Player* bot;
|
||||
};
|
||||
|
||||
class FindItemsByQualityVisitor : public IterateItemsVisitor
|
||||
{
|
||||
public:
|
||||
FindItemsByQualityVisitor(uint32 quality, uint32 count) : IterateItemsVisitor(), quality(quality), count(count) { }
|
||||
public:
|
||||
FindItemsByQualityVisitor(uint32 quality, uint32 count) : IterateItemsVisitor(), quality(quality), count(count) {}
|
||||
|
||||
bool Visit(Item* item) override
|
||||
{
|
||||
@ -82,12 +83,9 @@ class FindItemsByQualityVisitor : public IterateItemsVisitor
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Item*>& GetResult()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
std::vector<Item*>& GetResult() { return result; }
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 quality;
|
||||
uint32 count;
|
||||
std::vector<Item*> result;
|
||||
@ -95,8 +93,8 @@ class FindItemsByQualityVisitor : public IterateItemsVisitor
|
||||
|
||||
class FindItemsToTradeByQualityVisitor : public FindItemsByQualityVisitor
|
||||
{
|
||||
public:
|
||||
FindItemsToTradeByQualityVisitor(uint32 quality, uint32 count) : FindItemsByQualityVisitor(quality, count) { }
|
||||
public:
|
||||
FindItemsToTradeByQualityVisitor(uint32 quality, uint32 count) : FindItemsByQualityVisitor(quality, count) {}
|
||||
|
||||
bool Visit(Item* item) override
|
||||
{
|
||||
@ -109,9 +107,11 @@ class FindItemsToTradeByQualityVisitor : public FindItemsByQualityVisitor
|
||||
|
||||
class FindItemsToTradeByClassVisitor : public IterateItemsVisitor
|
||||
{
|
||||
public:
|
||||
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,12 +128,9 @@ class FindItemsToTradeByClassVisitor : public IterateItemsVisitor
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Item*>& GetResult()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
std::vector<Item*>& GetResult() { return result; }
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 itemClass;
|
||||
uint32 itemSubClass;
|
||||
uint32 count;
|
||||
@ -142,8 +139,8 @@ class FindItemsToTradeByClassVisitor : public IterateItemsVisitor
|
||||
|
||||
class QueryItemCountVisitor : public IterateItemsVisitor
|
||||
{
|
||||
public:
|
||||
QueryItemCountVisitor(uint32 itemId) : count(0), itemId(itemId) { }
|
||||
public:
|
||||
QueryItemCountVisitor(uint32 itemId) : count(0), itemId(itemId) {}
|
||||
|
||||
bool Visit(Item* item) override
|
||||
{
|
||||
@ -155,15 +152,15 @@ class QueryItemCountVisitor : public IterateItemsVisitor
|
||||
|
||||
uint32 GetCount() { return count; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
uint32 count;
|
||||
uint32 itemId;
|
||||
};
|
||||
|
||||
class QueryNamedItemCountVisitor : public QueryItemCountVisitor
|
||||
{
|
||||
public:
|
||||
QueryNamedItemCountVisitor(std::string const name) : QueryItemCountVisitor(0), name(name) { }
|
||||
public:
|
||||
QueryNamedItemCountVisitor(std::string const name) : QueryItemCountVisitor(0), name(name) {}
|
||||
|
||||
bool Visit(Item* item) override
|
||||
{
|
||||
@ -174,56 +171,50 @@ class QueryNamedItemCountVisitor : public QueryItemCountVisitor
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string const name;
|
||||
};
|
||||
|
||||
class FindNamedItemVisitor : public FindItemVisitor
|
||||
{
|
||||
public:
|
||||
FindNamedItemVisitor([[maybe_unused]] Player* bot, std::string const name) : FindItemVisitor(), name(name) { }
|
||||
public:
|
||||
FindNamedItemVisitor([[maybe_unused]] Player* bot, std::string const name) : FindItemVisitor(), name(name) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override
|
||||
{
|
||||
return proto && proto->Name1.c_str() && strstri(proto->Name1.c_str(), name.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string const name;
|
||||
};
|
||||
|
||||
class FindItemByIdVisitor : public FindItemVisitor
|
||||
{
|
||||
public:
|
||||
FindItemByIdVisitor(uint32 id) : FindItemVisitor(), id(id) { }
|
||||
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:
|
||||
private:
|
||||
uint32 id;
|
||||
};
|
||||
|
||||
class FindItemByIdsVisitor : public FindItemVisitor
|
||||
{
|
||||
public:
|
||||
FindItemByIdsVisitor(ItemIds ids) : FindItemVisitor(), ids(ids) { }
|
||||
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:
|
||||
private:
|
||||
ItemIds ids;
|
||||
};
|
||||
|
||||
class ListItemsVisitor : public IterateItemsVisitor
|
||||
{
|
||||
public:
|
||||
ListItemsVisitor() : IterateItemsVisitor() { }
|
||||
public:
|
||||
ListItemsVisitor() : IterateItemsVisitor() {}
|
||||
|
||||
std::map<uint32, uint32> items;
|
||||
std::map<uint32, bool> soulbound;
|
||||
@ -243,7 +234,7 @@ class ListItemsVisitor : public IterateItemsVisitor
|
||||
|
||||
class ItemCountByQuality : public IterateItemsVisitor
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ItemCountByQuality() : IterateItemsVisitor()
|
||||
{
|
||||
for (uint32 i = 0; i < MAX_ITEM_QUALITY; ++i)
|
||||
@ -256,63 +247,66 @@ class ItemCountByQuality : public IterateItemsVisitor
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
public:
|
||||
std::map<uint32, uint32> count;
|
||||
};
|
||||
|
||||
class FindPotionVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindPotionVisitor(Player* bot, uint32 effectId) : FindUsableItemVisitor(bot), effectId(effectId) { }
|
||||
public:
|
||||
FindPotionVisitor(Player* bot, uint32 effectId) : FindUsableItemVisitor(bot), effectId(effectId) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 effectId;
|
||||
};
|
||||
|
||||
class FindFoodVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindFoodVisitor(Player* bot, uint32 spellCategory, bool conjured = false) : FindUsableItemVisitor(bot),
|
||||
spellCategory(spellCategory), conjured(conjured) { }
|
||||
public:
|
||||
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());
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 spellCategory;
|
||||
bool conjured;
|
||||
};
|
||||
|
||||
class FindMountVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindMountVisitor(Player* bot) : FindUsableItemVisitor(bot) { }
|
||||
public:
|
||||
FindMountVisitor(Player* bot) : FindUsableItemVisitor(bot) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 effectId;
|
||||
};
|
||||
|
||||
class FindPetVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindPetVisitor(Player* bot) : FindUsableItemVisitor(bot) { }
|
||||
public:
|
||||
FindPetVisitor(Player* bot) : FindUsableItemVisitor(bot) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override;
|
||||
};
|
||||
|
||||
class FindAmmoVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindAmmoVisitor(Player* bot, uint32 weaponType) : FindUsableItemVisitor(bot), weaponType(weaponType) { }
|
||||
public:
|
||||
FindAmmoVisitor(Player* bot, uint32 weaponType) : FindUsableItemVisitor(bot), weaponType(weaponType) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto)override
|
||||
bool Accept(ItemTemplate const* proto) override
|
||||
{
|
||||
if (proto->Class == ITEM_CLASS_PROJECTILE)
|
||||
{
|
||||
@ -338,14 +332,14 @@ class FindAmmoVisitor : public FindUsableItemVisitor
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
uint32 weaponType;
|
||||
};
|
||||
|
||||
class FindQuestItemVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindQuestItemVisitor(Player* bot) : FindUsableItemVisitor(bot) { }
|
||||
public:
|
||||
FindQuestItemVisitor(Player* bot) : FindUsableItemVisitor(bot) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override
|
||||
{
|
||||
@ -359,8 +353,8 @@ class FindQuestItemVisitor : public FindUsableItemVisitor
|
||||
|
||||
class FindRecipeVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindRecipeVisitor(Player* bot, SkillType skill = SKILL_NONE) : FindUsableItemVisitor(bot), skill(skill) { };
|
||||
public:
|
||||
FindRecipeVisitor(Player* bot, SkillType skill = SKILL_NONE) : FindUsableItemVisitor(bot), skill(skill){};
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override
|
||||
{
|
||||
@ -395,29 +389,30 @@ class FindRecipeVisitor : public FindUsableItemVisitor
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
SkillType skill;
|
||||
};
|
||||
|
||||
class FindItemUsageVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
public:
|
||||
FindItemUsageVisitor(Player* bot, ItemUsage usage = ITEM_USAGE_NONE);
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
AiObjectContext* context;
|
||||
ItemUsage usage;
|
||||
};
|
||||
|
||||
class FindUsableNamedItemVisitor : public FindUsableItemVisitor
|
||||
{
|
||||
public:
|
||||
FindUsableNamedItemVisitor(Player* bot, std::string name): FindUsableItemVisitor(bot), name(name) {}
|
||||
public:
|
||||
FindUsableNamedItemVisitor(Player* bot, std::string name) : FindUsableItemVisitor(bot), name(name) {}
|
||||
|
||||
bool Accept(ItemTemplate const* proto) override;
|
||||
private:
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -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
|
||||
@ -12,9 +13,9 @@ class PlayerbotAI;
|
||||
|
||||
class Multiplier : public AiNamedObject
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Multiplier(PlayerbotAI* botAI, std::string const name) : AiNamedObject(botAI, name) {}
|
||||
virtual ~Multiplier() { }
|
||||
virtual ~Multiplier() {}
|
||||
|
||||
virtual float GetValue([[maybe_unused]] Action* action) { return 1.0f; }
|
||||
};
|
||||
|
||||
@ -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)
|
||||
@ -24,7 +26,7 @@ std::string const Qualified::MultiQualify(std::vector<std::string> qualifiers)
|
||||
std::vector<std::string> Qualified::getMultiQualifiers(std::string const qualifier1)
|
||||
{
|
||||
std::istringstream iss(qualifier1);
|
||||
return { std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{} };
|
||||
return {std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};
|
||||
}
|
||||
|
||||
int32 Qualified::getMultiQualifier(std::string const qualifier1, uint32 pos)
|
||||
|
||||
@ -1,36 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU 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
|
||||
{
|
||||
public:
|
||||
Qualified() { };
|
||||
Qualified(std::string const qualifier) : qualifier(qualifier) { }
|
||||
Qualified(int32 qualifier1)
|
||||
{
|
||||
Qualify(qualifier1);
|
||||
}
|
||||
public:
|
||||
Qualified(){};
|
||||
Qualified(std::string const qualifier) : qualifier(qualifier) {}
|
||||
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; }
|
||||
|
||||
@ -38,18 +33,18 @@ class Qualified
|
||||
static std::vector<std::string> getMultiQualifiers(std::string const qualifier1);
|
||||
static int32 getMultiQualifier(std::string const qualifier1, uint32 pos);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
std::string qualifier;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class NamedObjectFactory
|
||||
{
|
||||
protected:
|
||||
typedef T*(*ActionCreator)(PlayerbotAI* botAI);
|
||||
protected:
|
||||
typedef T* (*ActionCreator)(PlayerbotAI* botAI);
|
||||
std::unordered_map<std::string, ActionCreator> creators;
|
||||
|
||||
public:
|
||||
public:
|
||||
T* create(std::string name, PlayerbotAI* botAI)
|
||||
{
|
||||
size_t found = name.find("::");
|
||||
@ -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;
|
||||
@ -88,15 +84,14 @@ class NamedObjectFactory
|
||||
template <class T>
|
||||
class NamedObjectContext : public NamedObjectFactory<T>
|
||||
{
|
||||
public:
|
||||
NamedObjectContext(bool shared = false, bool supportsSiblings = false) :
|
||||
NamedObjectFactory<T>(), shared(shared), supportsSiblings(supportsSiblings) { }
|
||||
|
||||
virtual ~NamedObjectContext()
|
||||
public:
|
||||
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())
|
||||
@ -146,7 +141,7 @@ class NamedObjectContext : public NamedObjectFactory<T>
|
||||
return keys;
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
std::unordered_map<std::string, T*> created;
|
||||
bool shared;
|
||||
bool supportsSiblings;
|
||||
@ -155,7 +150,7 @@ class NamedObjectContext : public NamedObjectFactory<T>
|
||||
template <class T>
|
||||
class NamedObjectContextList
|
||||
{
|
||||
public:
|
||||
public:
|
||||
virtual ~NamedObjectContextList()
|
||||
{
|
||||
for (typename std::vector<NamedObjectContext<T>*>::iterator i = contexts.begin(); i != contexts.end(); i++)
|
||||
@ -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)
|
||||
{
|
||||
@ -246,26 +238,23 @@ class NamedObjectContextList
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<NamedObjectContext<T>*> contexts;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class NamedObjectFactoryList
|
||||
{
|
||||
public:
|
||||
public:
|
||||
virtual ~NamedObjectFactoryList()
|
||||
{
|
||||
for (typename std::list<NamedObjectFactory<T>*>::iterator i = factories.begin(); i != factories.end(); i++)
|
||||
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)
|
||||
T* GetContextObject(std::string const& name, PlayerbotAI* botAI)
|
||||
{
|
||||
for (typename std::list<NamedObjectFactory<T>*>::iterator i = factories.begin(); i != factories.end(); i++)
|
||||
{
|
||||
@ -276,7 +265,7 @@ class NamedObjectFactoryList
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
std::list<NamedObjectFactory<T>*> factories;
|
||||
};
|
||||
|
||||
|
||||
@ -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,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_PASSIVEMULTIPLIER_H
|
||||
#define _PLAYERBOT_PASSIVEMULTIPLIER_H
|
||||
|
||||
#include "Multiplier.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Multiplier.h"
|
||||
|
||||
class Action;
|
||||
class PlayerbotAI;
|
||||
|
||||
class PassiveMultiplier : public Multiplier
|
||||
{
|
||||
public:
|
||||
public:
|
||||
PassiveMultiplier(PlayerbotAI* botAI);
|
||||
|
||||
float GetValue(Action* action) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
static std::vector<std::string> allowedActions;
|
||||
static std::vector<std::string> allowedParts;
|
||||
};
|
||||
|
||||
@ -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 "Queue.h"
|
||||
|
||||
#include "AiObjectContext.h"
|
||||
#include "Log.h"
|
||||
#include "PlayerbotAIConfig.h"
|
||||
|
||||
void Queue::Push(ActionBasket *action)
|
||||
void Queue::Push(ActionBasket* action)
|
||||
{
|
||||
if (action)
|
||||
{
|
||||
@ -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,26 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU 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
|
||||
{
|
||||
public:
|
||||
Queue(void) { }
|
||||
~Queue(void) { }
|
||||
public:
|
||||
Queue(void) {}
|
||||
~Queue(void) {}
|
||||
|
||||
void Push(ActionBasket *action);
|
||||
void Push(ActionBasket* action);
|
||||
ActionNode* Pop();
|
||||
ActionBasket* Peek();
|
||||
uint32 Size();
|
||||
void RemoveExpired();
|
||||
|
||||
private:
|
||||
private:
|
||||
std::list<ActionBasket*> actions;
|
||||
};
|
||||
|
||||
|
||||
@ -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 "Strategy.h"
|
||||
|
||||
#include "Playerbots.h"
|
||||
|
||||
class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ActionNodeFactoryInternal()
|
||||
{
|
||||
creators["melee"] = &melee;
|
||||
@ -23,10 +25,10 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
creators["flee"] = &flee;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
static ActionNode* melee([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("melee",
|
||||
return new ActionNode("melee",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
@ -34,7 +36,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* healthstone([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("healthstone",
|
||||
return new ActionNode("healthstone",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("healing potion"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
@ -42,7 +44,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* follow_master_random([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("be near",
|
||||
return new ActionNode("be near",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("follow"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
@ -50,7 +52,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* attack_anything([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("attack anything",
|
||||
return new ActionNode("attack anything",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
@ -58,7 +60,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* move_random([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("move random",
|
||||
return new ActionNode("move random",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("stay line"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
@ -66,7 +68,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* move_to_loot([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("move to loot",
|
||||
return new ActionNode("move to loot",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
@ -74,7 +76,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* food([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("food",
|
||||
return new ActionNode("food",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
@ -82,7 +84,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* drink([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("drink",
|
||||
return new ActionNode("drink",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
@ -90,7 +92,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* mana_potion([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("mana potion",
|
||||
return new ActionNode("mana potion",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("drink"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
@ -98,7 +100,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* healing_potion([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("healing potion",
|
||||
return new ActionNode("healing potion",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ NextAction::array(0, new NextAction("food"), nullptr),
|
||||
/*C*/ nullptr);
|
||||
@ -106,7 +108,7 @@ class ActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
|
||||
|
||||
static ActionNode* flee([[maybe_unused]] PlayerbotAI* botAI)
|
||||
{
|
||||
return new ActionNode ("flee",
|
||||
return new ActionNode("flee",
|
||||
/*P*/ nullptr,
|
||||
/*A*/ nullptr,
|
||||
/*C*/ nullptr);
|
||||
@ -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
|
||||
{
|
||||
@ -54,20 +55,20 @@ static float ACTION_EMERGENCY = 90.0f;
|
||||
|
||||
class Strategy : public PlayerbotAIAware
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Strategy(PlayerbotAI* botAI);
|
||||
virtual ~Strategy() { }
|
||||
virtual ~Strategy() {}
|
||||
|
||||
virtual NextAction** getDefaultActions() { return nullptr; }
|
||||
virtual void InitTriggers([[maybe_unused]] std::vector<TriggerNode*> &triggers) { }
|
||||
virtual void InitMultipliers([[maybe_unused]] std::vector<Multiplier*> &multipliers) { }
|
||||
virtual void InitTriggers([[maybe_unused]] std::vector<TriggerNode*>& triggers) {}
|
||||
virtual void InitMultipliers([[maybe_unused]] std::vector<Multiplier*>& multipliers) {}
|
||||
virtual std::string const getName() = 0;
|
||||
virtual uint32 GetType() const { return STRATEGY_TYPE_GENERIC; }
|
||||
virtual ActionNode* GetAction(std::string const name);
|
||||
void Update() { }
|
||||
void Reset() { }
|
||||
void Update() {}
|
||||
void Reset() {}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
NamedObjectFactoryList<ActionNode> actionNodeFactories;
|
||||
};
|
||||
|
||||
|
||||
@ -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"
|
||||
@ -50,7 +51,7 @@
|
||||
|
||||
class StrategyContext : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
StrategyContext()
|
||||
{
|
||||
creators["racials"] = &StrategyContext::racials;
|
||||
@ -115,7 +116,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
|
||||
creators["combat formation"] = &StrategyContext::combat_formation;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
static Strategy* behind(PlayerbotAI* botAI) { return new SetBehindCombatStrategy(botAI); }
|
||||
static Strategy* ranged(PlayerbotAI* botAI) { return new RangedCombatStrategy(botAI); }
|
||||
static Strategy* close(PlayerbotAI* botAI) { return new MeleeCombatStrategy(botAI); }
|
||||
@ -171,7 +172,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
|
||||
static Strategy* debug_spell(PlayerbotAI* botAI) { return new DebugSpellStrategy(botAI); }
|
||||
static Strategy* maintenance(PlayerbotAI* botAI) { return new MaintenanceStrategy(botAI); }
|
||||
static Strategy* group(PlayerbotAI* botAI) { return new GroupStrategy(botAI); }
|
||||
static Strategy* guild (PlayerbotAI* botAI) { return new GuildStrategy(botAI); }
|
||||
static Strategy* guild(PlayerbotAI* botAI) { return new GuildStrategy(botAI); }
|
||||
static Strategy* grind(PlayerbotAI* botAI) { return new GrindingStrategy(botAI); }
|
||||
static Strategy* avoid_aoe(PlayerbotAI* botAI) { return new AvoidAoeStrategy(botAI); }
|
||||
static Strategy* move_random(PlayerbotAI* ai) { return new MoveRandomStrategy(ai); }
|
||||
@ -180,7 +181,7 @@ class StrategyContext : public NamedObjectContext<Strategy>
|
||||
|
||||
class MovementStrategyContext : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
MovementStrategyContext() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["follow"] = &MovementStrategyContext::follow_master;
|
||||
@ -190,17 +191,17 @@ class MovementStrategyContext : public NamedObjectContext<Strategy>
|
||||
creators["guard"] = &MovementStrategyContext::guard;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
static Strategy* guard(PlayerbotAI* botAI) { return new GuardStrategy(botAI); }
|
||||
static Strategy* follow_master(PlayerbotAI* botAI) { return new FollowMasterStrategy(botAI); }
|
||||
static Strategy* stay(PlayerbotAI* botAI) { return new StayStrategy(botAI); }
|
||||
static Strategy* runaway(PlayerbotAI* botAI) { return new RunawayStrategy(botAI); }
|
||||
static Strategy* flee_from_adds(PlayerbotAI* botAI) { return new FleeFromAddsStrategy(botAI); }
|
||||
};
|
||||
};
|
||||
|
||||
class AssistStrategyContext : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
class AssistStrategyContext : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
AssistStrategyContext() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["dps assist"] = &AssistStrategyContext::dps_assist;
|
||||
@ -208,7 +209,7 @@ class MovementStrategyContext : public NamedObjectContext<Strategy>
|
||||
creators["tank assist"] = &AssistStrategyContext::tank_assist;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
static Strategy* dps_assist(PlayerbotAI* botAI) { return new DpsAssistStrategy(botAI); }
|
||||
static Strategy* dps_aoe(PlayerbotAI* botAI) { return new DpsAoeStrategy(botAI); }
|
||||
static Strategy* tank_assist(PlayerbotAI* botAI) { return new TankAssistStrategy(botAI); }
|
||||
@ -216,18 +217,16 @@ class MovementStrategyContext : public NamedObjectContext<Strategy>
|
||||
|
||||
class QuestStrategyContext : public NamedObjectContext<Strategy>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
QuestStrategyContext() : NamedObjectContext<Strategy>(false, true)
|
||||
{
|
||||
creators["quest"] = &QuestStrategyContext::quest;
|
||||
creators["accept all quests"] = &QuestStrategyContext::accept_all_quests;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
static Strategy* quest(PlayerbotAI* botAI) { return new DefaultQuestStrategy(botAI); }
|
||||
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,66 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU 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;
|
||||
|
||||
class Trigger : public AiNamedObject
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Trigger(PlayerbotAI* botAI, std::string const name = "trigger", int32 checkInterval = 1);
|
||||
|
||||
virtual ~Trigger() { }
|
||||
virtual ~Trigger() {}
|
||||
|
||||
virtual Event Check();
|
||||
virtual void ExternalEvent([[maybe_unused]] std::string const param, [[maybe_unused]] Player* owner = nullptr) { }
|
||||
virtual void ExternalEvent([[maybe_unused]] WorldPacket& packet, [[maybe_unused]] Player* owner = nullptr) { }
|
||||
virtual void ExternalEvent([[maybe_unused]] std::string const param, [[maybe_unused]] Player* owner = nullptr) {}
|
||||
virtual void ExternalEvent([[maybe_unused]] WorldPacket& packet, [[maybe_unused]] Player* owner = nullptr) {}
|
||||
virtual bool IsActive() { return false; }
|
||||
virtual NextAction** getHandlers() { return nullptr; }
|
||||
void Update() { }
|
||||
virtual void Reset() { }
|
||||
void Update() {}
|
||||
virtual void Reset() {}
|
||||
virtual Unit* GetTarget();
|
||||
virtual Value<Unit*>* GetTargetValue();
|
||||
virtual std::string const GetTargetName() { return "self target"; }
|
||||
|
||||
bool needCheck();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
int32 checkInterval;
|
||||
uint32 lastCheckTime;
|
||||
};
|
||||
|
||||
class TriggerNode
|
||||
{
|
||||
public:
|
||||
TriggerNode(std::string const name, NextAction** handlers = nullptr) : trigger(nullptr), handlers(handlers), name(name) { } // reorder args - whipowill
|
||||
|
||||
virtual ~TriggerNode()
|
||||
public:
|
||||
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:
|
||||
private:
|
||||
Trigger* trigger;
|
||||
NextAction** handlers;
|
||||
std::string const name;
|
||||
|
||||
@ -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,24 +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_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;
|
||||
|
||||
class FleeInfo
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Position fromPos;
|
||||
float radius;
|
||||
float angle;
|
||||
@ -30,51 +31,61 @@ struct CreatureData;
|
||||
|
||||
class UntypedValue : public AiNamedObject
|
||||
{
|
||||
public:
|
||||
UntypedValue(PlayerbotAI* botAI, std::string const name) : AiNamedObject(botAI, name) { }
|
||||
virtual ~UntypedValue() { }
|
||||
virtual void Update() { }
|
||||
virtual void Reset() { }
|
||||
public:
|
||||
UntypedValue(PlayerbotAI* botAI, std::string const name) : AiNamedObject(botAI, name) {}
|
||||
virtual ~UntypedValue() {}
|
||||
virtual void Update() {}
|
||||
virtual void Reset() {}
|
||||
virtual std::string const Format() { return "?"; }
|
||||
virtual std::string const Save() { return "?"; }
|
||||
virtual bool Load([[maybe_unused]] std::string const value) { return false; }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
template <class T>
|
||||
class Value
|
||||
{
|
||||
public:
|
||||
virtual ~Value() { }
|
||||
public:
|
||||
virtual ~Value() {}
|
||||
virtual T Get() = 0;
|
||||
virtual T LazyGet() = 0;
|
||||
virtual T& RefGet() = 0;
|
||||
virtual void Reset() { }
|
||||
virtual void Reset() {}
|
||||
virtual void Set(T value) = 0;
|
||||
operator T() { return Get(); }
|
||||
};
|
||||
|
||||
template<class T>
|
||||
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) { }
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CalculatedValue() { }
|
||||
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();
|
||||
@ -114,7 +130,7 @@ class CalculatedValue : public UntypedValue, public Value<T>
|
||||
void Update() override {}
|
||||
void Reset() override { lastCheckTime = 0; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual T Calculate() = 0;
|
||||
|
||||
uint32 checkInterval;
|
||||
@ -125,7 +141,7 @@ class CalculatedValue : public UntypedValue, public Value<T>
|
||||
template <class T>
|
||||
class SingleCalculatedValue : public CalculatedValue<T>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
SingleCalculatedValue(PlayerbotAI* botAI, std::string const name = "value") : CalculatedValue<T>(botAI, name)
|
||||
{
|
||||
this->Reset();
|
||||
@ -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();
|
||||
@ -148,20 +165,18 @@ class SingleCalculatedValue : public CalculatedValue<T>
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
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)
|
||||
public:
|
||||
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()
|
||||
{
|
||||
@ -206,17 +218,20 @@ class MemoryCalculatedValue : public CalculatedValue<T>
|
||||
lastChangeTime = time(0);
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
T lastValue;
|
||||
uint32 minChangeInterval = 0;
|
||||
time_t lastChangeTime;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
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) { }
|
||||
public:
|
||||
LogCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1)
|
||||
: MemoryCalculatedValue<T>(botAI, name, checkInterval)
|
||||
{
|
||||
}
|
||||
|
||||
bool UpdateChange() override
|
||||
{
|
||||
@ -238,53 +253,58 @@ class LogCalculatedValue : public MemoryCalculatedValue<T>
|
||||
valueLog.clear();
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
std::list<std::pair<T, time_t>> valueLog;
|
||||
uint8 logLength = 10;
|
||||
};
|
||||
};
|
||||
|
||||
class Uint8CalculatedValue : public CalculatedValue<uint8>
|
||||
{
|
||||
public:
|
||||
Uint8CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1) :
|
||||
CalculatedValue<uint8>(botAI, name, checkInterval) { }
|
||||
public:
|
||||
Uint8CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", uint32 checkInterval = 1)
|
||||
: CalculatedValue<uint8>(botAI, name, checkInterval)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const Format() override;
|
||||
};
|
||||
|
||||
class Uint32CalculatedValue : public CalculatedValue<uint32>
|
||||
{
|
||||
public:
|
||||
Uint32CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1) :
|
||||
CalculatedValue<uint32>(botAI, name, checkInterval) { }
|
||||
public:
|
||||
Uint32CalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1)
|
||||
: CalculatedValue<uint32>(botAI, name, checkInterval)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const Format() override;
|
||||
};
|
||||
|
||||
class FloatCalculatedValue : public CalculatedValue<float>
|
||||
{
|
||||
public:
|
||||
FloatCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1) :
|
||||
CalculatedValue<float>(botAI, name, checkInterval) { }
|
||||
public:
|
||||
FloatCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int checkInterval = 1)
|
||||
: CalculatedValue<float>(botAI, name, checkInterval)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const Format() override;
|
||||
};
|
||||
|
||||
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
|
||||
public:
|
||||
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*>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
UnitCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1);
|
||||
|
||||
std::string const Format() override;
|
||||
@ -293,7 +313,7 @@ class UnitCalculatedValue : public CalculatedValue<Unit*>
|
||||
|
||||
class CDPairCalculatedValue : public CalculatedValue<CreatureData const*>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
CDPairCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1);
|
||||
|
||||
std::string const Format() override;
|
||||
@ -301,7 +321,7 @@ class CDPairCalculatedValue : public CalculatedValue<CreatureData const*>
|
||||
|
||||
class CDPairListCalculatedValue : public CalculatedValue<std::vector<CreatureData const*>>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
CDPairListCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1);
|
||||
|
||||
std::string const Format() override;
|
||||
@ -309,7 +329,7 @@ class CDPairListCalculatedValue : public CalculatedValue<std::vector<CreatureDat
|
||||
|
||||
class ObjectGuidCalculatedValue : public CalculatedValue<ObjectGuid>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ObjectGuidCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1);
|
||||
|
||||
std::string const Format() override;
|
||||
@ -317,41 +337,42 @@ class ObjectGuidCalculatedValue : public CalculatedValue<ObjectGuid>
|
||||
|
||||
class ObjectGuidListCalculatedValue : public CalculatedValue<GuidVector>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ObjectGuidListCalculatedValue(PlayerbotAI* botAI, std::string const name = "value", int32 checkInterval = 1);
|
||||
|
||||
std::string const Format() override;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
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) { }
|
||||
public:
|
||||
ManualSetValue(PlayerbotAI* botAI, T defaultValue, std::string const name = "value")
|
||||
: UntypedValue(botAI, name), value(defaultValue), defaultValue(defaultValue)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ManualSetValue() { }
|
||||
virtual ~ManualSetValue() {}
|
||||
|
||||
T Get() override { return value; }
|
||||
T LazyGet() override { return value; }
|
||||
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:
|
||||
protected:
|
||||
T value;
|
||||
T defaultValue;
|
||||
};
|
||||
|
||||
class UnitManualSetValue : public ManualSetValue<Unit*>
|
||||
{
|
||||
public:
|
||||
UnitManualSetValue(PlayerbotAI* botAI, Unit* defaultValue, std::string const name = "value") :
|
||||
ManualSetValue<Unit*>(botAI, defaultValue, name) { }
|
||||
public:
|
||||
UnitManualSetValue(PlayerbotAI* botAI, Unit* defaultValue, std::string const name = "value")
|
||||
: ManualSetValue<Unit*>(botAI, defaultValue, name)
|
||||
{
|
||||
}
|
||||
|
||||
std::string const Format() override;
|
||||
Unit* Get() override;
|
||||
@ -359,30 +380,39 @@ 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) { }
|
||||
public:
|
||||
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) { }
|
||||
public:
|
||||
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) { }
|
||||
public:
|
||||
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) { }
|
||||
public:
|
||||
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"
|
||||
|
||||
@ -16,7 +18,7 @@ bool AcceptBgInvitationAction::Execute(Event event)
|
||||
|
||||
WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20);
|
||||
packet << type << unk2 << (uint32)bgTypeId_ << unk << action;
|
||||
//packet << bgTypeId_ << action;
|
||||
// packet << bgTypeId_ << action;
|
||||
bot->GetSession()->HandleBattleFieldPortOpcode(packet);
|
||||
|
||||
botAI->ResetStrategies();
|
||||
|
||||
@ -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
|
||||
@ -11,8 +12,8 @@ class PlayerbotAI;
|
||||
|
||||
class AcceptBgInvitationAction : public Action
|
||||
{
|
||||
public:
|
||||
AcceptBgInvitationAction(PlayerbotAI* botAI) : Action(botAI, "accept bg invitatio") { }
|
||||
public:
|
||||
AcceptBgInvitationAction(PlayerbotAI* botAI) : Action(botAI, "accept bg invitatio") {}
|
||||
|
||||
bool Execute(Event event) 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 "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
|
||||
@ -11,8 +12,8 @@ class PlayerbotAI;
|
||||
|
||||
class AcceptDuelAction : public Action
|
||||
{
|
||||
public:
|
||||
AcceptDuelAction(PlayerbotAI* botAI) : Action(botAI, "accept duel") { }
|
||||
public:
|
||||
AcceptDuelAction(PlayerbotAI* botAI) : Action(botAI, "accept duel") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
@ -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)
|
||||
@ -41,8 +43,8 @@ bool AcceptInvitationAction::Execute(Event event)
|
||||
|
||||
if (sRandomPlayerbotMgr->IsRandomBot(bot))
|
||||
botAI->SetMaster(inviter);
|
||||
//else
|
||||
//sPlayerbotDbStore->Save(botAI);
|
||||
// else
|
||||
// sPlayerbotDbStore->Save(botAI);
|
||||
|
||||
botAI->ResetStrategies();
|
||||
botAI->ChangeStrategy("+follow,-lfg,-bg", BOT_STATE_NON_COMBAT);
|
||||
@ -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
|
||||
@ -12,8 +13,8 @@ class PlayerbotAI;
|
||||
|
||||
class AcceptInvitationAction : public SummonAction
|
||||
{
|
||||
public:
|
||||
AcceptInvitationAction(PlayerbotAI* botAI) : SummonAction(botAI, "accept invitation") { }
|
||||
public:
|
||||
AcceptInvitationAction(PlayerbotAI* botAI) : SummonAction(botAI, "accept invitation") {}
|
||||
|
||||
bool Execute(Event event) 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 "AcceptQuestAction.h"
|
||||
|
||||
#include "Event.h"
|
||||
#include "Playerbots.h"
|
||||
|
||||
@ -112,7 +114,7 @@ bool AcceptQuestShareAction::Execute(Event event)
|
||||
bot->SetDivider(ObjectGuid::Empty);
|
||||
}
|
||||
|
||||
if (bot->CanAddQuest( qInfo, false))
|
||||
if (bot->CanAddQuest(qInfo, false))
|
||||
{
|
||||
bot->AddQuest(qInfo, master);
|
||||
|
||||
@ -125,7 +127,7 @@ bool AcceptQuestShareAction::Execute(Event event)
|
||||
|
||||
if (qInfo->GetSrcSpell() > 0)
|
||||
{
|
||||
bot->CastSpell( bot, qInfo->GetSrcSpell(), true);
|
||||
bot->CastSpell(bot, qInfo->GetSrcSpell(), true);
|
||||
}
|
||||
|
||||
botAI->TellMaster("Quest accepted");
|
||||
|
||||
@ -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
|
||||
@ -13,24 +14,26 @@ class WorldObject;
|
||||
|
||||
class AcceptAllQuestsAction : public QuestAction
|
||||
{
|
||||
public:
|
||||
AcceptAllQuestsAction(PlayerbotAI* botAI, std::string const name = "accept all quests") : QuestAction(botAI, name) { }
|
||||
public:
|
||||
AcceptAllQuestsAction(PlayerbotAI* botAI, std::string const name = "accept all quests") : QuestAction(botAI, name)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void ProcessQuest(Quest const* quest, Object* questGiver) override;
|
||||
};
|
||||
|
||||
class AcceptQuestAction : public AcceptAllQuestsAction
|
||||
{
|
||||
public:
|
||||
AcceptQuestAction(PlayerbotAI* botAI) : AcceptAllQuestsAction(botAI, "accept quest") { }
|
||||
public:
|
||||
AcceptQuestAction(PlayerbotAI* botAI) : AcceptAllQuestsAction(botAI, "accept quest") {}
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
class AcceptQuestShareAction : public Action
|
||||
{
|
||||
public:
|
||||
AcceptQuestShareAction(PlayerbotAI* botAI) : Action(botAI, "accept quest share") { }
|
||||
public:
|
||||
AcceptQuestShareAction(PlayerbotAI* botAI) : Action(botAI, "accept quest share") {}
|
||||
bool Execute(Event event) 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
|
||||
@ -11,8 +12,8 @@ class PlayerbotAI;
|
||||
|
||||
class AcceptResurrectAction : public Action
|
||||
{
|
||||
public:
|
||||
AcceptResurrectAction(PlayerbotAI* botAI) : Action(botAI, "accept resurrect") { }
|
||||
public:
|
||||
AcceptResurrectAction(PlayerbotAI* botAI) : Action(botAI, "accept resurrect") {}
|
||||
|
||||
bool Execute(Event event) override;
|
||||
};
|
||||
|
||||
@ -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,17 +57,15 @@
|
||||
#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;
|
||||
|
||||
class ActionContext : public NamedObjectContext<Action>
|
||||
{
|
||||
public:
|
||||
public:
|
||||
ActionContext()
|
||||
{
|
||||
creators["mark rti"] = &ActionContext::mark_rti;
|
||||
@ -205,7 +206,7 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
creators["blade salvo"] = &ActionContext::blade_salvo;
|
||||
creators["glaive throw"] = &ActionContext::glaive_throw;
|
||||
|
||||
//Rpg
|
||||
// Rpg
|
||||
creators["rpg stay"] = &ActionContext::rpg_stay;
|
||||
creators["rpg work"] = &ActionContext::rpg_work;
|
||||
creators["rpg emote"] = &ActionContext::rpg_emote;
|
||||
@ -231,10 +232,9 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
|
||||
creators["toggle pet spell"] = &ActionContext::toggle_pet_spell;
|
||||
creators["pet attack"] = &ActionContext::pet_attack;
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
static Action* give_water(PlayerbotAI* botAI) { return new GiveWaterAction(botAI); }
|
||||
static Action* give_food(PlayerbotAI* botAI) { return new GiveFoodAction(botAI); }
|
||||
static Action* ra(PlayerbotAI* botAI) { return new RemoveAuraAction(botAI); }
|
||||
@ -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); }
|
||||
@ -375,7 +378,7 @@ class ActionContext : public NamedObjectContext<Action>
|
||||
static Action* glaive_throw(PlayerbotAI* botAI) { return new CastGlaiveThrowAction(botAI); }
|
||||
static Action* blade_salvo(PlayerbotAI* botAI) { return new CastBladeSalvoAction(botAI); }
|
||||
|
||||
//Rpg
|
||||
// Rpg
|
||||
static Action* rpg_stay(PlayerbotAI* botAI) { return new RpgStayAction(botAI); }
|
||||
static Action* rpg_work(PlayerbotAI* botAI) { return new RpgWorkAction(botAI); }
|
||||
static Action* rpg_emote(PlayerbotAI* botAI) { return new RpgEmoteAction(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