From feda619066eedfa610e0ab562c380c0e1c6643f6 Mon Sep 17 00:00:00 2001 From: Yunfan Li <56597220+liyunfan1223@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:11:03 +0800 Subject: [PATCH] Engine optimization for better performance and mem usage (#1462) * Optimize loot * World channel talk * General improvement * Engine rebuild for performance and memory usage * Fix crash with AutoDoQuest = 0 --- src/LootObjectStack.cpp | 79 ++++--- src/LootObjectStack.h | 2 +- src/PlayerbotAI.cpp | 3 + src/PlayerbotAIConfig.cpp | 7 +- src/strategy/AiObjectContext.cpp | 121 +++++++---- src/strategy/AiObjectContext.h | 29 ++- src/strategy/Engine.cpp | 21 +- src/strategy/Engine.h | 1 + src/strategy/NamedObjectContext.h | 194 +++++++++++------- src/strategy/Strategy.h | 2 +- src/strategy/Trigger.cpp | 3 +- src/strategy/Trigger.h | 2 +- .../deathknight/DKAiObjectContext.cpp | 51 ++++- src/strategy/deathknight/DKAiObjectContext.h | 11 + src/strategy/druid/DruidAiObjectContext.cpp | 38 +++- src/strategy/druid/DruidAiObjectContext.h | 11 + src/strategy/hunter/HunterAiObjectContext.cpp | 46 ++++- src/strategy/hunter/HunterAiObjectContext.h | 11 + src/strategy/mage/MageAiObjectContext.cpp | 38 +++- src/strategy/mage/MageAiObjectContext.h | 11 + .../paladin/PaladinAiObjectContext.cpp | 68 +++++- src/strategy/paladin/PaladinAiObjectContext.h | 11 + src/strategy/priest/PriestAiObjectContext.cpp | 44 +++- src/strategy/priest/PriestAiObjectContext.h | 11 + src/strategy/rogue/RogueAiObjectContext.cpp | 38 +++- src/strategy/rogue/RogueAiObjectContext.h | 12 ++ src/strategy/rpg/NewRpgBaseAction.cpp | 6 +- src/strategy/shaman/ShamanAiObjectContext.cpp | 36 +++- src/strategy/shaman/ShamanAiObjectContext.h | 11 + src/strategy/values/GrindTargetValue.cpp | 16 +- src/strategy/values/NearestCorpsesValue.h | 2 +- src/strategy/values/SharedValueContext.h | 7 +- .../warlock/WarlockAiObjectContext.cpp | 67 +++++- src/strategy/warlock/WarlockAiObjectContext.h | 11 + .../warrior/WarriorAiObjectContext.cpp | 36 +++- src/strategy/warrior/WarriorAiObjectContext.h | 11 + 36 files changed, 831 insertions(+), 237 deletions(-) diff --git a/src/LootObjectStack.cpp b/src/LootObjectStack.cpp index e1d2bc46..adce7f39 100644 --- a/src/LootObjectStack.cpp +++ b/src/LootObjectStack.cpp @@ -6,6 +6,8 @@ #include "LootObjectStack.h" #include "LootMgr.h" +#include "Object.h" +#include "ObjectAccessor.h" #include "Playerbots.h" #include "Unit.h" @@ -287,7 +289,7 @@ bool LootObject::IsLootPossible(Player* bot) if (reqItem && !bot->HasItemCount(reqItem, 1)) return false; - if (abs(worldObj->GetPositionZ() - bot->GetPositionZ()) > INTERACTION_DISTANCE -2.0f) + if (abs(worldObj->GetPositionZ() - bot->GetPositionZ()) > INTERACTION_DISTANCE - 2.0f) return false; Creature* creature = botAI->GetCreature(guid); @@ -299,7 +301,7 @@ bool LootObject::IsLootPossible(Player* bot) // Prevent bot from running to chests that are unlootable (e.g. Gunship Armory before completing the event) GameObject* go = botAI->GetGameObject(guid); - if (go && go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE)) + if (go && go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE)) return false; if (skillId == SKILL_NONE) @@ -317,29 +319,17 @@ bool LootObject::IsLootPossible(Player* bot) uint32 skillValue = uint32(bot->GetSkillValue(skillId)); if (reqSkillValue > skillValue) return false; - - if (skillId == SKILL_MINING && - !bot->HasItemCount(756, 1) && - !bot->HasItemCount(778, 1) && - !bot->HasItemCount(1819, 1) && - !bot->HasItemCount(1893, 1) && - !bot->HasItemCount(1959, 1) && - !bot->HasItemCount(2901, 1) && - !bot->HasItemCount(9465, 1) && - !bot->HasItemCount(20723, 1) && - !bot->HasItemCount(40772, 1) && - !bot->HasItemCount(40892, 1) && - !bot->HasItemCount(40893, 1)) + + if (skillId == SKILL_MINING && !bot->HasItemCount(756, 1) && !bot->HasItemCount(778, 1) && + !bot->HasItemCount(1819, 1) && !bot->HasItemCount(1893, 1) && !bot->HasItemCount(1959, 1) && + !bot->HasItemCount(2901, 1) && !bot->HasItemCount(9465, 1) && !bot->HasItemCount(20723, 1) && + !bot->HasItemCount(40772, 1) && !bot->HasItemCount(40892, 1) && !bot->HasItemCount(40893, 1)) { return false; // Bot is missing a mining pick } - - if (skillId == SKILL_SKINNING && - !bot->HasItemCount(7005, 1) && - !bot->HasItemCount(40772, 1) && - !bot->HasItemCount(40893, 1) && - !bot->HasItemCount(12709, 1) && - !bot->HasItemCount(19901, 1)) + + if (skillId == SKILL_SKINNING && !bot->HasItemCount(7005, 1) && !bot->HasItemCount(40772, 1) && + !bot->HasItemCount(40893, 1) && !bot->HasItemCount(12709, 1) && !bot->HasItemCount(19901, 1)) { return false; // Bot is missing a skinning knife } @@ -376,42 +366,45 @@ void LootObjectStack::Clear() { availableLoot.clear(); } bool LootObjectStack::CanLoot(float maxDistance) { - std::vector ordered = OrderByDistance(maxDistance); - return !ordered.empty(); + LootObject nearest = GetNearest(maxDistance); + return !nearest.IsEmpty(); } LootObject LootObjectStack::GetLoot(float maxDistance) { - std::vector ordered = OrderByDistance(maxDistance); - return ordered.empty() ? LootObject() : *ordered.begin(); + LootObject nearest = GetNearest(maxDistance); + return nearest.IsEmpty() ? LootObject() : nearest; } -std::vector LootObjectStack::OrderByDistance(float maxDistance) + +LootObject LootObjectStack::GetNearest(float maxDistance) { availableLoot.shrink(time(nullptr) - 30); - std::map sortedMap; + LootObject nearest; + float nearestDistance = std::numeric_limits::max(); + LootTargetList safeCopy(availableLoot); for (LootTargetList::iterator i = safeCopy.begin(); i != safeCopy.end(); i++) { ObjectGuid guid = i->guid; - LootObject lootObject(bot, guid); - if (!lootObject.IsLootPossible(bot)) // Ensure loot object is valid - continue; - WorldObject* worldObj = lootObject.GetWorldObject(bot); - if (!worldObj) // Prevent null pointer dereference - { + WorldObject* worldObj = ObjectAccessor::GetWorldObject(*bot, guid); + if (!worldObj) continue; - } float distance = bot->GetDistance(worldObj); - if (!maxDistance || distance <= maxDistance) - sortedMap[distance] = lootObject; + + if (distance >= nearestDistance || (maxDistance && distance > maxDistance)) + continue; + + LootObject lootObject(bot, guid); + + if (!lootObject.IsLootPossible(bot)) + continue; + + nearestDistance = distance; + nearest = lootObject; } - std::vector result; - for (auto& [_, lootObject] : sortedMap) - result.push_back(lootObject); - - return result; -} + return nearest; +} \ No newline at end of file diff --git a/src/LootObjectStack.h b/src/LootObjectStack.h index b17e7fcc..9ff7dd99 100644 --- a/src/LootObjectStack.h +++ b/src/LootObjectStack.h @@ -78,7 +78,7 @@ public: LootObject GetLoot(float maxDistance = 0); private: - std::vector OrderByDistance(float maxDistance = 0); + LootObject GetNearest(float maxDistance = 0); Player* bot; LootTargetList availableLoot; diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 5b2b707f..d2e0f293 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -1049,6 +1049,9 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) default: return; } + + if (chanName == "World") + return; // do not reply to self but always try to reply to real player if (guid1 != bot->GetGUID()) diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index cd03c7f1..db1419a4 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -627,12 +627,7 @@ bool PlayerbotAIConfig::Initialize() sPlayerbotTextMgr->LoadBotTextChance(); PlayerbotFactory::Init(); - if (!sPlayerbotAIConfig->autoDoQuests) - { - LOG_INFO("server.loading", "Loading Quest Detail Data..."); - sTravelMgr->LoadQuestTravelTable(); - } - + AiObjectContext::BuildAllSharedContexts(); if (sPlayerbotAIConfig->randomBotSuggestDungeons) { diff --git a/src/strategy/AiObjectContext.cpp b/src/strategy/AiObjectContext.cpp index c308a7cd..dd025c2e 100644 --- a/src/strategy/AiObjectContext.cpp +++ b/src/strategy/AiObjectContext.cpp @@ -8,39 +8,89 @@ #include "ActionContext.h" #include "ChatActionContext.h" #include "ChatTriggerContext.h" +#include "DKAiObjectContext.h" +#include "DruidAiObjectContext.h" +#include "HunterAiObjectContext.h" +#include "MageAiObjectContext.h" +#include "PaladinAiObjectContext.h" #include "Playerbots.h" -#include "RaidUlduarTriggerContext.h" +#include "PriestAiObjectContext.h" #include "RaidUlduarActionContext.h" +#include "RaidUlduarTriggerContext.h" +#include "RogueAiObjectContext.h" +#include "ShamanAiObjectContext.h" #include "SharedValueContext.h" #include "StrategyContext.h" #include "TriggerContext.h" #include "ValueContext.h" +#include "WarlockAiObjectContext.h" +#include "WarriorAiObjectContext.h" #include "WorldPacketActionContext.h" #include "WorldPacketTriggerContext.h" -#include "raids/RaidStrategyContext.h" -#include "raids/blackwinglair/RaidBwlActionContext.h" -#include "raids/blackwinglair/RaidBwlTriggerContext.h" -#include "raids/naxxramas/RaidNaxxActionContext.h" -#include "raids/naxxramas/RaidNaxxTriggerContext.h" -#include "raids/icecrown/RaidIccActionContext.h" -#include "raids/icecrown/RaidIccTriggerContext.h" -#include "raids/obsidiansanctum/RaidOsActionContext.h" -#include "raids/obsidiansanctum/RaidOsTriggerContext.h" -#include "raids/eyeofeternity/RaidEoEActionContext.h" -#include "raids/vaultofarchavon/RaidVoATriggerContext.h" -#include "raids/onyxia/RaidOnyxiaActionContext.h" -#include "raids/onyxia/RaidOnyxiaTriggerContext.h" -#include "raids/vaultofarchavon/RaidVoAActionContext.h" -#include "raids/eyeofeternity/RaidEoETriggerContext.h" -#include "raids/moltencore/RaidMcActionContext.h" -#include "raids/moltencore/RaidMcTriggerContext.h" -#include "raids/aq20/RaidAq20ActionContext.h" -#include "raids/aq20/RaidAq20TriggerContext.h" #include "dungeons/DungeonStrategyContext.h" #include "dungeons/wotlk/WotlkDungeonActionContext.h" #include "dungeons/wotlk/WotlkDungeonTriggerContext.h" +#include "raids/RaidStrategyContext.h" +#include "raids/aq20/RaidAq20ActionContext.h" +#include "raids/aq20/RaidAq20TriggerContext.h" +#include "raids/blackwinglair/RaidBwlActionContext.h" +#include "raids/blackwinglair/RaidBwlTriggerContext.h" +#include "raids/eyeofeternity/RaidEoEActionContext.h" +#include "raids/eyeofeternity/RaidEoETriggerContext.h" +#include "raids/icecrown/RaidIccActionContext.h" +#include "raids/icecrown/RaidIccTriggerContext.h" +#include "raids/moltencore/RaidMcActionContext.h" +#include "raids/moltencore/RaidMcTriggerContext.h" +#include "raids/naxxramas/RaidNaxxActionContext.h" +#include "raids/naxxramas/RaidNaxxTriggerContext.h" +#include "raids/obsidiansanctum/RaidOsActionContext.h" +#include "raids/obsidiansanctum/RaidOsTriggerContext.h" +#include "raids/onyxia/RaidOnyxiaActionContext.h" +#include "raids/onyxia/RaidOnyxiaTriggerContext.h" +#include "raids/vaultofarchavon/RaidVoAActionContext.h" +#include "raids/vaultofarchavon/RaidVoATriggerContext.h" -AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) +SharedNamedObjectContextList AiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList AiObjectContext::sharedActionContexts; +SharedNamedObjectContextList AiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList AiObjectContext::sharedValueContexts; + +AiObjectContext::AiObjectContext(PlayerbotAI* botAI, SharedNamedObjectContextList& sharedStrategyContext, + SharedNamedObjectContextList& sharedActionContext, + SharedNamedObjectContextList& sharedTriggerContext, + SharedNamedObjectContextList& sharedValueContext) + : PlayerbotAIAware(botAI), + strategyContexts(sharedStrategyContext), + actionContexts(sharedActionContext), + triggerContexts(sharedTriggerContext), + valueContexts(sharedValueContext) +{ +} + +void AiObjectContext::BuildAllSharedContexts() +{ + AiObjectContext::BuildSharedContexts(); + PriestAiObjectContext::BuildSharedContexts(); + MageAiObjectContext::BuildSharedContexts(); + WarlockAiObjectContext::BuildSharedContexts(); + WarriorAiObjectContext::BuildSharedContexts(); + ShamanAiObjectContext::BuildSharedContexts(); + PaladinAiObjectContext::BuildSharedContexts(); + DruidAiObjectContext::BuildSharedContexts(); + HunterAiObjectContext::BuildSharedContexts(); + RogueAiObjectContext::BuildSharedContexts(); + DKAiObjectContext::BuildSharedContexts(); +} + +void AiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void AiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) { strategyContexts.Add(new StrategyContext()); strategyContexts.Add(new MovementStrategyContext()); @@ -48,7 +98,10 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) strategyContexts.Add(new QuestStrategyContext()); strategyContexts.Add(new RaidStrategyContext()); strategyContexts.Add(new DungeonStrategyContext()); +} +void AiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ actionContexts.Add(new ActionContext()); actionContexts.Add(new ChatActionContext()); actionContexts.Add(new WorldPacketActionContext()); @@ -77,7 +130,10 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) actionContexts.Add(new WotlkDungeonFoSActionContext()); actionContexts.Add(new WotlkDungeonPoSActionContext()); actionContexts.Add(new WotlkDungeonToCActionContext()); +} +void AiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ triggerContexts.Add(new TriggerContext()); triggerContexts.Add(new ChatTriggerContext()); triggerContexts.Add(new WorldPacketTriggerContext()); @@ -106,26 +162,11 @@ AiObjectContext::AiObjectContext(PlayerbotAI* botAI) : PlayerbotAIAware(botAI) triggerContexts.Add(new WotlkDungeonFoSTriggerContext()); triggerContexts.Add(new WotlkDungeonPoSTriggerContext()); triggerContexts.Add(new WotlkDungeonToCTriggerContext()); +} +void AiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ valueContexts.Add(new ValueContext()); - - valueContexts.Add(sSharedValueContext); -} - -void AiObjectContext::Update() -{ - strategyContexts.Update(); - triggerContexts.Update(); - actionContexts.Update(); - valueContexts.Update(); -} - -void AiObjectContext::Reset() -{ - strategyContexts.Reset(); - triggerContexts.Reset(); - actionContexts.Reset(); - valueContexts.Reset(); } std::vector AiObjectContext::Save() @@ -218,5 +259,3 @@ std::string const AiObjectContext::FormatValues() return out.str(); } - -void AiObjectContext::AddShared(NamedObjectContext* sharedValues) { valueContexts.Add(sharedValues); } diff --git a/src/strategy/AiObjectContext.h b/src/strategy/AiObjectContext.h index 07fa78a6..cfa7d4db 100644 --- a/src/strategy/AiObjectContext.h +++ b/src/strategy/AiObjectContext.h @@ -19,10 +19,19 @@ class PlayerbotAI; +typedef Strategy* (*StrategyCreator)(PlayerbotAI* botAI); +typedef Action* (*ActionCreator)(PlayerbotAI* botAI); +typedef Trigger* (*TriggerCreator)(PlayerbotAI* botAI); +typedef UntypedValue* (*ValueCreator)(PlayerbotAI* botAI); + class AiObjectContext : public PlayerbotAIAware { public: - AiObjectContext(PlayerbotAI* botAI); + AiObjectContext(PlayerbotAI* botAI, + SharedNamedObjectContextList& sharedStrategyContext = sharedStrategyContexts, + SharedNamedObjectContextList& sharedActionContext = sharedActionContexts, + SharedNamedObjectContextList& sharedTriggerContext = sharedTriggerContexts, + SharedNamedObjectContextList& sharedValueContext = sharedValueContexts); virtual ~AiObjectContext() {} virtual Strategy* GetStrategy(std::string const name); @@ -56,20 +65,30 @@ public: std::set GetSupportedActions(); std::string const FormatValues(); - virtual void Update(); - virtual void Reset(); - virtual void AddShared(NamedObjectContext* sharedValues); - std::vector Save(); void Load(std::vector data); std::vector performanceStack; + static void BuildAllSharedContexts(); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + protected: NamedObjectContextList strategyContexts; NamedObjectContextList actionContexts; NamedObjectContextList triggerContexts; NamedObjectContextList valueContexts; + +private: + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/Engine.cpp b/src/strategy/Engine.cpp index 39524596..15055f0e 100644 --- a/src/strategy/Engine.cpp +++ b/src/strategy/Engine.cpp @@ -11,6 +11,7 @@ #include "Playerbots.h" #include "Queue.h" #include "Strategy.h" +#include "Timer.h" Engine::Engine(PlayerbotAI* botAI, AiObjectContext* factory) : PlayerbotAIAware(botAI), aiObjectContext(factory) { @@ -108,6 +109,8 @@ void Engine::Reset() } multipliers.clear(); + + actionNodeFactories.creators.clear(); } void Engine::Init() @@ -120,9 +123,10 @@ void Engine::Init() strategyTypeMask |= strategy->GetType(); strategy->InitMultipliers(multipliers); strategy->InitTriggers(triggers); - - Event emptyEvent; - MultiplyAndPush(strategy->getDefaultActions(), 0.0f, false, emptyEvent, "default"); + for (auto &iter : strategy->actionNodeFactories.creators) + { + actionNodeFactories.creators[iter.first] = iter.second; + } } if (testMode) @@ -248,11 +252,9 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal) ActionNode* Engine::CreateActionNode(std::string const name) { - for (std::map::iterator i = strategies.begin(); i != strategies.end(); i++) - { - if (ActionNode* node = i->second->GetAction(name)) - return node; - } + ActionNode* node = actionNodeFactories.GetContextObject(name, botAI); + if (node) + return node; return new ActionNode(name, /*P*/ nullptr, @@ -432,6 +434,7 @@ bool Engine::HasStrategy(std::string const name) { return strategies.find(name) void Engine::ProcessTriggers(bool minimal) { std::unordered_map fires; + uint32 now = getMSTime(); for (std::vector::iterator i = triggers.begin(); i != triggers.end(); i++) { TriggerNode* node = *i; @@ -451,7 +454,7 @@ void Engine::ProcessTriggers(bool minimal) if (fires.find(trigger) != fires.end()) continue; - if (testMode || trigger->needCheck()) + if (testMode || trigger->needCheck(now)) { if (minimal && node->getFirstRelevance() < 100) continue; diff --git a/src/strategy/Engine.h b/src/strategy/Engine.h index c3a5d743..8a662997 100644 --- a/src/strategy/Engine.h +++ b/src/strategy/Engine.h @@ -114,6 +114,7 @@ protected: float lastRelevance; std::string lastAction; uint32 strategyTypeMask; + NamedObjectFactoryList actionNodeFactories; }; #endif diff --git a/src/strategy/NamedObjectContext.h b/src/strategy/NamedObjectContext.h index 78797b0a..c7ecffc6 100644 --- a/src/strategy/NamedObjectContext.h +++ b/src/strategy/NamedObjectContext.h @@ -29,7 +29,8 @@ public: std::string const getQualifier() { return qualifier; } - static std::string const MultiQualify(std::vector qualifiers, const std::string& separator, const std::string_view brackets = "{}"); + static std::string const MultiQualify(std::vector qualifiers, const std::string& separator, + const std::string_view brackets = "{}"); static std::vector getMultiQualifiers(std::string const qualifier1); static int32 getMultiQualifier(std::string const qualifier1, uint32 pos); @@ -40,9 +41,9 @@ protected: template class NamedObjectFactory { -protected: - typedef T* (*ActionCreator)(PlayerbotAI* botAI); - std::unordered_map creators; +public: + typedef T* (*ObjectCreator)(PlayerbotAI* botAI); + std::unordered_map creators; public: T* create(std::string name, PlayerbotAI* botAI) @@ -58,7 +59,7 @@ public: if (creators.find(name) == creators.end()) return nullptr; - ActionCreator creator = creators[name]; + ObjectCreator creator = creators[name]; if (!creator) return nullptr; @@ -73,7 +74,7 @@ public: std::set supports() { std::set keys; - for (typename std::unordered_map::iterator it = creators.begin(); + for (typename std::unordered_map::iterator it = creators.begin(); it != creators.end(); it++) keys.insert(it->first); @@ -111,24 +112,6 @@ public: created.clear(); } - void Update() - { - for (typename std::unordered_map::iterator i = created.begin(); i != created.end(); i++) - { - if (i->second) - i->second->Update(); - } - } - - void Reset() - { - for (typename std::unordered_map::iterator i = created.begin(); i != created.end(); i++) - { - if (i->second) - i->second->Reset(); - } - } - bool IsShared() { return shared; } bool IsSupportsSiblings() { return supportsSiblings; } @@ -147,53 +130,93 @@ protected: bool supportsSiblings; }; +template +class SharedNamedObjectContextList +{ +public: + typedef T* (*ObjectCreator)(PlayerbotAI* botAI); + std::unordered_map creators; + std::vector*> contexts; + + ~SharedNamedObjectContextList() + { + for (typename std::vector*>::iterator i = contexts.begin(); i != contexts.end(); i++) + delete *i; + } + + void Add(NamedObjectContext* context) + { + contexts.push_back(context); + for (const auto& iter : context->creators) + { + creators[iter.first] = iter.second; + } + } +}; + template class NamedObjectContextList { public: - virtual ~NamedObjectContextList() + typedef T* (*ObjectCreator)(PlayerbotAI* botAI); + const std::unordered_map& creators; + const std::vector*>& contexts; + std::unordered_map created; + + NamedObjectContextList(const SharedNamedObjectContextList& shared) + : creators(shared.creators), contexts(shared.contexts) { - for (typename std::vector*>::iterator i = contexts.begin(); i != contexts.end(); i++) - { - NamedObjectContext* context = *i; - if (!context->IsShared()) - delete context; - } } - void Add(NamedObjectContext* context) { contexts.push_back(context); } + ~NamedObjectContextList() + { + for (typename std::unordered_map::iterator i = created.begin(); i != created.end(); i++) + { + if (i->second) + delete i->second; + } + + created.clear(); + } + + T* create(std::string name, PlayerbotAI* botAI) + { + size_t found = name.find("::"); + std::string qualifier; + if (found != std::string::npos) + { + qualifier = name.substr(found + 2); + name = name.substr(0, found); + } + + if (creators.find(name) == creators.end()) + return nullptr; + + ObjectCreator creator = creators.at(name); + if (!creator) + return nullptr; + + T* object = (*creator)(botAI); + Qualified* q = dynamic_cast(object); + if (q && found != std::string::npos) + q->Qualify(qualifier); + + return object; + } T* GetContextObject(std::string const name, PlayerbotAI* botAI) { - for (typename std::vector*>::iterator i = contexts.begin(); i != contexts.end(); i++) + if (created.find(name) == created.end()) { - if (T* object = (*i)->create(name, botAI)) - return object; - } - - return nullptr; - } - - void Update() - { - for (typename std::vector*>::iterator i = contexts.begin(); i != contexts.end(); i++) - { - if (!(*i)->IsShared()) - (*i)->Update(); - } - } - - void Reset() - { - for (typename std::vector*>::iterator i = contexts.begin(); i != contexts.end(); i++) - { - (*i)->Reset(); + if (T* object = create(name, botAI)) + return created[name] = object; } + return created[name]; } std::set GetSiblings(std::string const name) { - for (typename std::vector*>::iterator i = contexts.begin(); i != contexts.end(); i++) + for (auto i = contexts.begin(); i != contexts.end(); i++) { if (!(*i)->IsSupportsSiblings()) continue; @@ -213,7 +236,7 @@ public: std::set supports() { std::set result; - for (typename std::vector*>::iterator i = contexts.begin(); i != contexts.end(); i++) + for (auto i = contexts.begin(); i != contexts.end(); i++) { std::set supported = (*i)->supports(); @@ -227,46 +250,69 @@ public: std::set GetCreated() { std::set result; - for (typename std::vector*>::iterator i = contexts.begin(); i != contexts.end(); i++) + for (typename std::unordered_map::iterator i = created.begin(); i != created.end(); i++) { - std::set createdKeys = (*i)->GetCreated(); - - for (std::set::iterator j = createdKeys.begin(); j != createdKeys.end(); j++) - result.insert(*j); + result.insert(i->first); } return result; } - -private: - std::vector*> contexts; }; template class NamedObjectFactoryList { public: + typedef T* (*ObjectCreator)(PlayerbotAI* botAI); + std::vector*> factories; + std::unordered_map creators; + virtual ~NamedObjectFactoryList() { - for (typename std::list*>::iterator i = factories.begin(); i != factories.end(); i++) + for (typename std::vector*>::iterator i = factories.begin(); i != factories.end(); i++) delete *i; } - void Add(NamedObjectFactory* context) { factories.push_front(context); } - - T* GetContextObject(std::string const& name, PlayerbotAI* botAI) + T* create(std::string name, PlayerbotAI* botAI) { - for (typename std::list*>::iterator i = factories.begin(); i != factories.end(); i++) + size_t found = name.find("::"); + std::string qualifier; + if (found != std::string::npos) { - if (T* object = (*i)->create(name, botAI)) - return object; + qualifier = name.substr(found + 2); + name = name.substr(0, found); } - return nullptr; + if (creators.find(name) == creators.end()) + return nullptr; + + ObjectCreator creator = creators[name]; + if (!creator) + return nullptr; + + T* object = (*creator)(botAI); + Qualified* q = dynamic_cast(object); + if (q && found != std::string::npos) + q->Qualify(qualifier); + + return object; } -private: - std::list*> factories; + void Add(NamedObjectFactory* context) + { + factories.push_back(context); + for (const auto& iter : context->creators) + { + creators[iter.first] = iter.second; + } + } + + T* GetContextObject(std::string const name, PlayerbotAI* botAI) + { + if (T* object = create(name, botAI)) + return object; + return nullptr; + } }; #endif diff --git a/src/strategy/Strategy.h b/src/strategy/Strategy.h index 47edd397..1206490c 100644 --- a/src/strategy/Strategy.h +++ b/src/strategy/Strategy.h @@ -69,7 +69,7 @@ public: void Update() {} void Reset() {} -protected: +public: NamedObjectFactoryList actionNodeFactories; }; diff --git a/src/strategy/Trigger.cpp b/src/strategy/Trigger.cpp index b2c97499..89f61696 100644 --- a/src/strategy/Trigger.cpp +++ b/src/strategy/Trigger.cpp @@ -32,12 +32,11 @@ Value* Trigger::GetTargetValue() { return context->GetValue(GetTar Unit* Trigger::GetTarget() { return GetTargetValue()->Get(); } -bool Trigger::needCheck() +bool Trigger::needCheck(uint32 now) { if (checkInterval < 2) return true; - uint32 now = getMSTime(); if (!lastCheckTime || now - lastCheckTime >= checkInterval) { lastCheckTime = now; diff --git a/src/strategy/Trigger.h b/src/strategy/Trigger.h index ce2dd06d..af8d0528 100644 --- a/src/strategy/Trigger.h +++ b/src/strategy/Trigger.h @@ -30,7 +30,7 @@ public: virtual Value* GetTargetValue(); virtual std::string const GetTargetName() { return "self target"; } - bool needCheck(); + bool needCheck(uint32 now); protected: int32 checkInterval; diff --git a/src/strategy/deathknight/DKAiObjectContext.cpp b/src/strategy/deathknight/DKAiObjectContext.cpp index c02ff82b..a26f96c0 100644 --- a/src/strategy/deathknight/DKAiObjectContext.cpp +++ b/src/strategy/deathknight/DKAiObjectContext.cpp @@ -108,14 +108,20 @@ private: static Trigger* blood_strike(PlayerbotAI* botAI) { return new BloodStrikeTrigger(botAI); } static Trigger* plague_strike(PlayerbotAI* botAI) { return new PlagueStrikeDebuffTrigger(botAI); } static Trigger* plague_strike_3s(PlayerbotAI* botAI) { return new PlagueStrike3sDebuffTrigger(botAI); } - static Trigger* dd_cd_and_plague_strike_3s(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "plague strike 3s"); } + static Trigger* dd_cd_and_plague_strike_3s(PlayerbotAI* botAI) + { + return new TwoTriggers(botAI, "death and decay cooldown", "plague strike 3s"); + } static Trigger* plague_strike_on_attacker(PlayerbotAI* botAI) { return new PlagueStrikeDebuffOnAttackerTrigger(botAI); } static Trigger* icy_touch(PlayerbotAI* botAI) { return new IcyTouchDebuffTrigger(botAI); } static Trigger* icy_touch_3s(PlayerbotAI* botAI) { return new IcyTouch3sDebuffTrigger(botAI); } - static Trigger* dd_cd_and_icy_touch_3s(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "icy touch 3s"); } + static Trigger* dd_cd_and_icy_touch_3s(PlayerbotAI* botAI) + { + return new TwoTriggers(botAI, "death and decay cooldown", "icy touch 3s"); + } static Trigger* death_coil(PlayerbotAI* botAI) { return new DeathCoilTrigger(botAI); } static Trigger* icy_touch_on_attacker(PlayerbotAI* botAI) { return new IcyTouchDebuffOnAttackerTrigger(botAI); } static Trigger* improved_icy_talons(PlayerbotAI* botAI) { return new ImprovedIcyTalonsTrigger(botAI); } @@ -140,7 +146,10 @@ private: static Trigger* no_rune(PlayerbotAI* botAI) { return new NoRuneTrigger(botAI); } static Trigger* freezing_fog(PlayerbotAI* botAI) { return new FreezingFogTrigger(botAI); } static Trigger* no_desolation(PlayerbotAI* botAI) { return new DesolationTrigger(botAI); } - static Trigger* dd_cd_and_no_desolation(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "death and decay cooldown", "no desolation"); } + static Trigger* dd_cd_and_no_desolation(PlayerbotAI* botAI) + { + return new TwoTriggers(botAI, "death and decay cooldown", "no desolation"); + } static Trigger* death_and_decay_cooldown(PlayerbotAI* botAI) { return new DeathAndDecayCooldownTrigger(botAI); } static Trigger* army_of_the_dead(PlayerbotAI* botAI) { return new ArmyOfTheDeadTrigger(botAI); } }; @@ -265,11 +274,45 @@ private: } }; -DKAiObjectContext::DKAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList DKAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList DKAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList DKAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList DKAiObjectContext::sharedValueContexts; + +DKAiObjectContext::DKAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void DKAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void DKAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new DeathKnightStrategyFactoryInternal()); strategyContexts.Add(new DeathKnightCombatStrategyFactoryInternal()); strategyContexts.Add(new DeathKnightDKBuffStrategyFactoryInternal()); +} + +void DKAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new DeathKnightAiObjectContextInternal()); +} + +void DKAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new DeathKnightTriggerFactoryInternal()); } + +void DKAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} diff --git a/src/strategy/deathknight/DKAiObjectContext.h b/src/strategy/deathknight/DKAiObjectContext.h index 7729868b..b45a778a 100644 --- a/src/strategy/deathknight/DKAiObjectContext.h +++ b/src/strategy/deathknight/DKAiObjectContext.h @@ -14,6 +14,17 @@ class DKAiObjectContext : public AiObjectContext { public: DKAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/druid/DruidAiObjectContext.cpp b/src/strategy/druid/DruidAiObjectContext.cpp index cec9eeb0..3866e1cd 100644 --- a/src/strategy/druid/DruidAiObjectContext.cpp +++ b/src/strategy/druid/DruidAiObjectContext.cpp @@ -8,7 +8,6 @@ #include "BearTankDruidStrategy.h" #include "CasterDruidStrategy.h" #include "CatDpsDruidStrategy.h" -#include "OffhealDruidCatStrategy.h" #include "DruidActions.h" #include "DruidBearActions.h" #include "DruidCatActions.h" @@ -18,6 +17,7 @@ #include "GenericDruidStrategy.h" #include "HealDruidStrategy.h" #include "MeleeDruidStrategy.h" +#include "OffhealDruidCatStrategy.h" #include "Playerbots.h" class DruidStrategyFactoryInternal : public NamedObjectContext @@ -324,10 +324,44 @@ private: static Action* force_of_nature(PlayerbotAI* ai) { return new CastForceOfNatureAction(ai); } }; -DruidAiObjectContext::DruidAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList DruidAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList DruidAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList DruidAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList DruidAiObjectContext::sharedValueContexts; + +DruidAiObjectContext::DruidAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void DruidAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void DruidAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new DruidStrategyFactoryInternal()); strategyContexts.Add(new DruidDruidStrategyFactoryInternal()); +} + +void DruidAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new DruidAiObjectContextInternal()); +} + +void DruidAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new DruidTriggerFactoryInternal()); } + +void DruidAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} diff --git a/src/strategy/druid/DruidAiObjectContext.h b/src/strategy/druid/DruidAiObjectContext.h index 22d00e18..7c1c7c8e 100644 --- a/src/strategy/druid/DruidAiObjectContext.h +++ b/src/strategy/druid/DruidAiObjectContext.h @@ -14,6 +14,17 @@ class DruidAiObjectContext : public AiObjectContext { public: DruidAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/hunter/HunterAiObjectContext.cpp b/src/strategy/hunter/HunterAiObjectContext.cpp index b8e2e41f..904e7a9f 100644 --- a/src/strategy/hunter/HunterAiObjectContext.cpp +++ b/src/strategy/hunter/HunterAiObjectContext.cpp @@ -4,16 +4,17 @@ */ #include "HunterAiObjectContext.h" + #include "BeastMasteryHunterStrategy.h" -#include "MarksmanshipHunterStrategy.h" -#include "SurvivalHunterStrategy.h" #include "GenericHunterNonCombatStrategy.h" #include "GenericHunterStrategy.h" #include "HunterActions.h" #include "HunterBuffStrategies.h" #include "HunterTriggers.h" +#include "MarksmanshipHunterStrategy.h" #include "NamedObjectContext.h" #include "Playerbots.h" +#include "SurvivalHunterStrategy.h" class HunterStrategyFactoryInternal : public NamedObjectContext { @@ -105,7 +106,10 @@ public: private: static Trigger* auto_shot(PlayerbotAI* botAI) { return new AutoShotTrigger(botAI); } static Trigger* scare_beast(PlayerbotAI* botAI) { return new ScareBeastTrigger(botAI); } - static Trigger* concussive_shot_on_snare_target(PlayerbotAI* botAI) { return new ConsussiveShotSnareTrigger(botAI); } + static Trigger* concussive_shot_on_snare_target(PlayerbotAI* botAI) + { + return new ConsussiveShotSnareTrigger(botAI); + } static Trigger* pet_not_happy(PlayerbotAI* botAI) { return new HunterPetNotHappy(botAI); } static Trigger* serpent_sting_on_attacker(PlayerbotAI* botAI) { return new SerpentStingOnAttackerTrigger(botAI); } static Trigger* trueshot_aura(PlayerbotAI* botAI) { return new TrueshotAuraTrigger(botAI); } @@ -258,10 +262,44 @@ private: static Action* intimidation(PlayerbotAI* ai) { return new CastIntimidationAction(ai); } }; -HunterAiObjectContext::HunterAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList HunterAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList HunterAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList HunterAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList HunterAiObjectContext::sharedValueContexts; + +HunterAiObjectContext::HunterAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void HunterAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void HunterAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new HunterStrategyFactoryInternal()); strategyContexts.Add(new HunterBuffStrategyFactoryInternal()); +} + +void HunterAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new HunterAiObjectContextInternal()); +} + +void HunterAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new HunterTriggerFactoryInternal()); } + +void HunterAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} diff --git a/src/strategy/hunter/HunterAiObjectContext.h b/src/strategy/hunter/HunterAiObjectContext.h index e06e8f54..5acd3ba2 100644 --- a/src/strategy/hunter/HunterAiObjectContext.h +++ b/src/strategy/hunter/HunterAiObjectContext.h @@ -14,6 +14,17 @@ class HunterAiObjectContext : public AiObjectContext { public: HunterAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/mage/MageAiObjectContext.cpp b/src/strategy/mage/MageAiObjectContext.cpp index 2d09f1a0..ba1e4e2d 100644 --- a/src/strategy/mage/MageAiObjectContext.cpp +++ b/src/strategy/mage/MageAiObjectContext.cpp @@ -24,7 +24,7 @@ public: creators["nc"] = &MageStrategyFactoryInternal::nc; creators["pull"] = &MageStrategyFactoryInternal::pull; creators["fire aoe"] = &MageStrategyFactoryInternal::fire_aoe; - creators["frostfire aoe"] = &MageStrategyFactoryInternal::frostfire_aoe; + creators["frostfire aoe"] = &MageStrategyFactoryInternal::frostfire_aoe; creators["frost aoe"] = &MageStrategyFactoryInternal::frost_aoe; creators["arcane aoe"] = &MageStrategyFactoryInternal::arcane_aoe; creators["cure"] = &MageStrategyFactoryInternal::cure; @@ -268,11 +268,45 @@ private: static Action* blink_back(PlayerbotAI* botAI) { return new CastBlinkBackAction(botAI); } }; -MageAiObjectContext::MageAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList MageAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList MageAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList MageAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList MageAiObjectContext::sharedValueContexts; + +MageAiObjectContext::MageAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void MageAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void MageAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new MageStrategyFactoryInternal()); strategyContexts.Add(new MageCombatStrategyFactoryInternal()); strategyContexts.Add(new MageBuffStrategyFactoryInternal()); +} + +void MageAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new MageAiObjectContextInternal()); +} + +void MageAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new MageTriggerFactoryInternal()); } + +void MageAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} \ No newline at end of file diff --git a/src/strategy/mage/MageAiObjectContext.h b/src/strategy/mage/MageAiObjectContext.h index 3388faf9..435b43d0 100644 --- a/src/strategy/mage/MageAiObjectContext.h +++ b/src/strategy/mage/MageAiObjectContext.h @@ -14,6 +14,17 @@ class MageAiObjectContext : public AiObjectContext { public: MageAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/paladin/PaladinAiObjectContext.cpp b/src/strategy/paladin/PaladinAiObjectContext.cpp index 4dbcb0af..74869bb1 100644 --- a/src/strategy/paladin/PaladinAiObjectContext.cpp +++ b/src/strategy/paladin/PaladinAiObjectContext.cpp @@ -8,8 +8,8 @@ #include "DpsPaladinStrategy.h" #include "GenericPaladinNonCombatStrategy.h" #include "HealPaladinStrategy.h" -#include "OffhealRetPaladinStrategy.h" #include "NamedObjectContext.h" +#include "OffhealRetPaladinStrategy.h" #include "PaladinActions.h" #include "PaladinBuffStrategies.h" #include "PaladinTriggers.h" @@ -207,9 +207,15 @@ private: static Trigger* sacred_shield_on_main_tank(PlayerbotAI* ai) { return new SacredShieldOnMainTankTrigger(ai); } static Trigger* blessing_of_kings_on_party(PlayerbotAI* botAI) { return new BlessingOfKingsOnPartyTrigger(botAI); } - static Trigger* blessing_of_wisdom_on_party(PlayerbotAI* botAI) { return new BlessingOfWisdomOnPartyTrigger(botAI); } + static Trigger* blessing_of_wisdom_on_party(PlayerbotAI* botAI) + { + return new BlessingOfWisdomOnPartyTrigger(botAI); + } static Trigger* blessing_of_might_on_party(PlayerbotAI* botAI) { return new BlessingOfMightOnPartyTrigger(botAI); } - static Trigger* blessing_of_sanctuary_on_party(PlayerbotAI* botAI) { return new BlessingOfSanctuaryOnPartyTrigger(botAI); } + static Trigger* blessing_of_sanctuary_on_party(PlayerbotAI* botAI) + { + return new BlessingOfSanctuaryOnPartyTrigger(botAI); + } static Trigger* avenging_wrath(PlayerbotAI* botAI) { return new AvengingWrathTrigger(botAI); } }; @@ -317,10 +323,22 @@ private: static Action* blessing_of_wisdom(PlayerbotAI* botAI) { return new CastBlessingOfWisdomAction(botAI); } static Action* blessing_of_kings(PlayerbotAI* botAI) { return new CastBlessingOfKingsAction(botAI); } static Action* divine_storm(PlayerbotAI* botAI) { return new CastDivineStormAction(botAI); } - static Action* blessing_of_kings_on_party(PlayerbotAI* botAI) { return new CastBlessingOfKingsOnPartyAction(botAI); } - static Action* blessing_of_might_on_party(PlayerbotAI* botAI) { return new CastBlessingOfMightOnPartyAction(botAI); } - static Action* blessing_of_wisdom_on_party(PlayerbotAI* botAI) { return new CastBlessingOfWisdomOnPartyAction(botAI); } - static Action* blessing_of_sanctuary_on_party(PlayerbotAI* botAI) { return new CastBlessingOfSanctuaryOnPartyAction(botAI); } + static Action* blessing_of_kings_on_party(PlayerbotAI* botAI) + { + return new CastBlessingOfKingsOnPartyAction(botAI); + } + static Action* blessing_of_might_on_party(PlayerbotAI* botAI) + { + return new CastBlessingOfMightOnPartyAction(botAI); + } + static Action* blessing_of_wisdom_on_party(PlayerbotAI* botAI) + { + return new CastBlessingOfWisdomOnPartyAction(botAI); + } + static Action* blessing_of_sanctuary_on_party(PlayerbotAI* botAI) + { + return new CastBlessingOfSanctuaryOnPartyAction(botAI); + } static Action* redemption(PlayerbotAI* botAI) { return new CastRedemptionAction(botAI); } static Action* crusader_strike(PlayerbotAI* botAI) { return new CastCrusaderStrikeAction(botAI); } static Action* crusader_aura(PlayerbotAI* botAI) { return new CastCrusaderAuraAction(botAI); } @@ -394,12 +412,46 @@ private: static Action* cancel_divine_sacrifice(PlayerbotAI* ai) { return new CastCancelDivineSacrificeAction(ai); } }; -PaladinAiObjectContext::PaladinAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList PaladinAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList PaladinAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList PaladinAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList PaladinAiObjectContext::sharedValueContexts; + +PaladinAiObjectContext::PaladinAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void PaladinAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void PaladinAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new PaladinStrategyFactoryInternal()); strategyContexts.Add(new PaladinCombatStrategyFactoryInternal()); strategyContexts.Add(new PaladinBuffStrategyFactoryInternal()); strategyContexts.Add(new PaladinResistanceStrategyFactoryInternal()); +} + +void PaladinAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new PaladinAiObjectContextInternal()); +} + +void PaladinAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new PaladinTriggerFactoryInternal()); } + +void PaladinAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} \ No newline at end of file diff --git a/src/strategy/paladin/PaladinAiObjectContext.h b/src/strategy/paladin/PaladinAiObjectContext.h index c865a8fc..e8b867ae 100644 --- a/src/strategy/paladin/PaladinAiObjectContext.h +++ b/src/strategy/paladin/PaladinAiObjectContext.h @@ -14,6 +14,17 @@ class PaladinAiObjectContext : public AiObjectContext { public: PaladinAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/priest/PriestAiObjectContext.cpp b/src/strategy/priest/PriestAiObjectContext.cpp index 4f057718..444ed3a1 100644 --- a/src/strategy/priest/PriestAiObjectContext.cpp +++ b/src/strategy/priest/PriestAiObjectContext.cpp @@ -175,8 +175,7 @@ public: creators["power word: shield on party"] = &PriestAiObjectContextInternal::power_word_shield_on_party; creators["power word: shield on almost full health below"] = &PriestAiObjectContextInternal::power_word_shield_on_almost_full_health_below; - creators["power word: shield on not full"] = - &PriestAiObjectContextInternal::power_word_shield_on_not_full; + creators["power word: shield on not full"] = &PriestAiObjectContextInternal::power_word_shield_on_not_full; creators["renew"] = &PriestAiObjectContextInternal::renew; creators["renew on party"] = &PriestAiObjectContextInternal::renew_on_party; creators["greater heal"] = &PriestAiObjectContextInternal::greater_heal; @@ -289,10 +288,7 @@ private: { return new CastPowerWordShieldOnAlmostFullHealthBelowAction(ai); } - static Action* power_word_shield_on_not_full(PlayerbotAI* ai) - { - return new CastPowerWordShieldOnNotFullAction(ai); - } + static Action* power_word_shield_on_not_full(PlayerbotAI* ai) { return new CastPowerWordShieldOnNotFullAction(ai); } static Action* renew(PlayerbotAI* botAI) { return new CastRenewAction(botAI); } static Action* renew_on_party(PlayerbotAI* botAI) { return new CastRenewOnPartyAction(botAI); } static Action* greater_heal(PlayerbotAI* botAI) { return new CastGreaterHealAction(botAI); } @@ -352,10 +348,44 @@ private: static Action* guardian_spirit_on_party(PlayerbotAI* ai) { return new CastGuardianSpiritOnPartyAction(ai); } }; -PriestAiObjectContext::PriestAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList PriestAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList PriestAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList PriestAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList PriestAiObjectContext::sharedValueContexts; + +PriestAiObjectContext::PriestAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void PriestAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void PriestAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new PriestStrategyFactoryInternal()); strategyContexts.Add(new PriestCombatStrategyFactoryInternal()); +} + +void PriestAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new PriestAiObjectContextInternal()); +} + +void PriestAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new PriestTriggerFactoryInternal()); } + +void PriestAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} \ No newline at end of file diff --git a/src/strategy/priest/PriestAiObjectContext.h b/src/strategy/priest/PriestAiObjectContext.h index 81c491b7..bb6efb4e 100644 --- a/src/strategy/priest/PriestAiObjectContext.h +++ b/src/strategy/priest/PriestAiObjectContext.h @@ -14,6 +14,17 @@ class PriestAiObjectContext : public AiObjectContext { public: PriestAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/rogue/RogueAiObjectContext.cpp b/src/strategy/rogue/RogueAiObjectContext.cpp index a63b97e1..39941bed 100644 --- a/src/strategy/rogue/RogueAiObjectContext.cpp +++ b/src/strategy/rogue/RogueAiObjectContext.cpp @@ -5,6 +5,7 @@ #include "RogueAiObjectContext.h" +#include "AiObjectContext.h" #include "AssassinationRogueStrategy.h" #include "DpsRogueStrategy.h" #include "GenericRogueNonCombatStrategy.h" @@ -185,10 +186,45 @@ private: static Action* killing_spree(PlayerbotAI* ai) { return new CastKillingSpreeAction(ai); } }; -RogueAiObjectContext::RogueAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList RogueAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList RogueAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList RogueAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList RogueAiObjectContext::sharedValueContexts; + +RogueAiObjectContext::RogueAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, + sharedTriggerContexts, sharedValueContexts) { +} + +void RogueAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void RogueAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new RogueStrategyFactoryInternal()); strategyContexts.Add(new RogueCombatStrategyFactoryInternal()); +} + +void RogueAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new RogueAiObjectContextInternal()); +} + +void RogueAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new RogueTriggerFactoryInternal()); } + +void RogueAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} \ No newline at end of file diff --git a/src/strategy/rogue/RogueAiObjectContext.h b/src/strategy/rogue/RogueAiObjectContext.h index e641623f..f1b3f98b 100644 --- a/src/strategy/rogue/RogueAiObjectContext.h +++ b/src/strategy/rogue/RogueAiObjectContext.h @@ -7,6 +7,7 @@ #define _PLAYERBOT_ROGUEAIOBJECTCONTEXT_H #include "AiObjectContext.h" +#include "Strategy.h" class PlayerbotAI; @@ -14,6 +15,17 @@ class RogueAiObjectContext : public AiObjectContext { public: RogueAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/rpg/NewRpgBaseAction.cpp b/src/strategy/rpg/NewRpgBaseAction.cpp index bd2a8221..5e71c5c5 100644 --- a/src/strategy/rpg/NewRpgBaseAction.cpp +++ b/src/strategy/rpg/NewRpgBaseAction.cpp @@ -84,7 +84,7 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest) float rx, ry, rz; bool found = false; int attempt = 3; - while (--attempt) + while (attempt--) { float angle = bot->GetAngle(&dest); float delta = urand(1, 100) <= 75 ? (rand_norm() - 0.5) * M_PI * 0.5 : (rand_norm() - 0.5) * M_PI * 2; @@ -163,8 +163,8 @@ bool NewRpgBaseAction::MoveRandomNear(float moveStep, MovementPriority priority) const float x = bot->GetPositionX(); const float y = bot->GetPositionY(); const float z = bot->GetPositionZ(); - int attempts = 5; - while (--attempts) + int attempts = 1; + while (attempts--) { float angle = (float)rand_norm() * 2 * static_cast(M_PI); float dx = x + distance * cos(angle); diff --git a/src/strategy/shaman/ShamanAiObjectContext.cpp b/src/strategy/shaman/ShamanAiObjectContext.cpp index 9e79f792..182251d1 100644 --- a/src/strategy/shaman/ShamanAiObjectContext.cpp +++ b/src/strategy/shaman/ShamanAiObjectContext.cpp @@ -328,11 +328,45 @@ private: static Action* feral_spirit(PlayerbotAI* ai) { return new CastFeralSpiritAction(ai); } }; -ShamanAiObjectContext::ShamanAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList ShamanAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList ShamanAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList ShamanAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList ShamanAiObjectContext::sharedValueContexts; + +ShamanAiObjectContext::ShamanAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void ShamanAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void ShamanAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new ShamanStrategyFactoryInternal()); strategyContexts.Add(new ShamanCombatStrategyFactoryInternal()); strategyContexts.Add(new ShamanBuffStrategyFactoryInternal()); +} + +void ShamanAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new ShamanAiObjectContextInternal()); +} + +void ShamanAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new ShamanATriggerFactoryInternal()); } + +void ShamanAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} \ No newline at end of file diff --git a/src/strategy/shaman/ShamanAiObjectContext.h b/src/strategy/shaman/ShamanAiObjectContext.h index ad1c0af4..d168f7af 100644 --- a/src/strategy/shaman/ShamanAiObjectContext.h +++ b/src/strategy/shaman/ShamanAiObjectContext.h @@ -14,6 +14,17 @@ class ShamanAiObjectContext : public AiObjectContext { public: ShamanAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/values/GrindTargetValue.cpp b/src/strategy/values/GrindTargetValue.cpp index 1737b7a7..cd368741 100644 --- a/src/strategy/values/GrindTargetValue.cpp +++ b/src/strategy/values/GrindTargetValue.cpp @@ -192,16 +192,16 @@ bool GrindTargetValue::needForQuest(Unit* target) return true; } } + } + } - if (CreatureTemplate const* data = sObjectMgr->GetCreatureTemplate(target->GetEntry())) + if (CreatureTemplate const* data = sObjectMgr->GetCreatureTemplate(target->GetEntry())) + { + if (uint32 lootId = data->lootid) + { + if (LootTemplates_Creature.HaveQuestLootForPlayer(lootId, bot)) { - if (uint32 lootId = data->lootid) - { - if (LootTemplates_Creature.HaveQuestLootForPlayer(lootId, bot)) - { - return true; - } - } + return true; } } } diff --git a/src/strategy/values/NearestCorpsesValue.h b/src/strategy/values/NearestCorpsesValue.h index 9bda863b..6453bb09 100644 --- a/src/strategy/values/NearestCorpsesValue.h +++ b/src/strategy/values/NearestCorpsesValue.h @@ -15,7 +15,7 @@ class NearestCorpsesValue : public NearestUnitsValue { public: NearestCorpsesValue(PlayerbotAI* botAI, float range = sPlayerbotAIConfig->sightDistance) - : NearestUnitsValue(botAI, "nearest corpses", range) + : NearestUnitsValue(botAI, "nearest corpses", range, true) { } diff --git a/src/strategy/values/SharedValueContext.h b/src/strategy/values/SharedValueContext.h index 5edb41f4..54c3f309 100644 --- a/src/strategy/values/SharedValueContext.h +++ b/src/strategy/values/SharedValueContext.h @@ -50,9 +50,12 @@ public: template Value* getGlobalValue(std::string const name) { - NamedObjectContextList valueContexts; - valueContexts.Add(this); + // should never reach here + SharedNamedObjectContextList sValueContexts; + sValueContexts.Add(this); + NamedObjectContextList valueContexts(sValueContexts); PlayerbotAI* botAI = new PlayerbotAI(); + UntypedValue* value = valueContexts.GetContextObject(name, botAI); delete botAI; return dynamic_cast*>(value); diff --git a/src/strategy/warlock/WarlockAiObjectContext.cpp b/src/strategy/warlock/WarlockAiObjectContext.cpp index 155ded9f..acd92a6d 100644 --- a/src/strategy/warlock/WarlockAiObjectContext.cpp +++ b/src/strategy/warlock/WarlockAiObjectContext.cpp @@ -4,16 +4,17 @@ */ #include "WarlockAiObjectContext.h" + #include "AfflictionWarlockStrategy.h" #include "DemonologyWarlockStrategy.h" #include "DestructionWarlockStrategy.h" -#include "TankWarlockStrategy.h" #include "GenericTriggers.h" #include "GenericWarlockNonCombatStrategy.h" #include "NamedObjectContext.h" #include "Playerbots.h" #include "PullStrategy.h" #include "Strategy.h" +#include "TankWarlockStrategy.h" #include "UseItemAction.h" #include "WarlockActions.h" #include "WarlockTriggers.h" @@ -22,14 +23,14 @@ class WarlockStrategyFactoryInternal : public NamedObjectContext { public: WarlockStrategyFactoryInternal() - { + { creators["nc"] = &WarlockStrategyFactoryInternal::nc; creators["pull"] = &WarlockStrategyFactoryInternal::pull; creators["boost"] = &WarlockStrategyFactoryInternal::boost; creators["cc"] = &WarlockStrategyFactoryInternal::cc; creators["pet"] = &WarlockStrategyFactoryInternal::pet; creators["spellstone"] = &WarlockStrategyFactoryInternal::spellstone; - creators["firestone"] = &WarlockStrategyFactoryInternal::firestone; + creators["firestone"] = &WarlockStrategyFactoryInternal::firestone; creators["meta melee"] = &WarlockStrategyFactoryInternal::meta_melee_aoe; creators["tank"] = &WarlockStrategyFactoryInternal::tank; creators["aoe"] = &WarlockStrategyFactoryInternal::aoe; @@ -196,7 +197,10 @@ private: static Trigger* immolate(PlayerbotAI* botAI) { return new ImmolateTrigger(botAI); } static Trigger* immolate_on_attacker(PlayerbotAI* ai) { return new ImmolateOnAttackerTrigger(ai); } static Trigger* unstable_affliction(PlayerbotAI* ai) { return new UnstableAfflictionTrigger(ai); } - static Trigger* unstable_affliction_on_attacker(PlayerbotAI* ai) { return new UnstableAfflictionOnAttackerTrigger(ai); } + static Trigger* unstable_affliction_on_attacker(PlayerbotAI* ai) + { + return new UnstableAfflictionOnAttackerTrigger(ai); + } static Trigger* haunt(PlayerbotAI* ai) { return new HauntTrigger(ai); } static Trigger* decimation(PlayerbotAI* ai) { return new DecimationTrigger(ai); } static Trigger* life_tap(PlayerbotAI* ai) { return new LifeTapTrigger(ai); } @@ -287,7 +291,7 @@ public: creators["curse of exhaustion"] = &WarlockAiObjectContextInternal::curse_of_exhaustion; creators["curse of tongues"] = &WarlockAiObjectContextInternal::curse_of_tongues; creators["curse of weakness"] = &WarlockAiObjectContextInternal::curse_of_weakness; - } + } private: static Action* conflagrate(PlayerbotAI* botAI) { return new CastConflagrateAction(botAI); } @@ -328,13 +332,19 @@ private: static Action* devour_magic_purge(PlayerbotAI* botAI) { return new CastDevourMagicPurgeAction(botAI); } static Action* devour_magic_cleanse(PlayerbotAI* botAI) { return new CastDevourMagicCleanseAction(botAI); } static Action* seed_of_corruption(PlayerbotAI* botAI) { return new CastSeedOfCorruptionAction(botAI); } - static Action* seed_of_corruption_on_attacker(PlayerbotAI* botAI) { return new CastSeedOfCorruptionOnAttackerAction(botAI); } + static Action* seed_of_corruption_on_attacker(PlayerbotAI* botAI) + { + return new CastSeedOfCorruptionOnAttackerAction(botAI); + } static Action* rain_of_fire(PlayerbotAI* botAI) { return new CastRainOfFireAction(botAI); } static Action* hellfire(PlayerbotAI* botAI) { return new CastHellfireAction(botAI); } static Action* shadowfury(PlayerbotAI* botAI) { return new CastShadowfuryAction(botAI); } static Action* life_tap(PlayerbotAI* botAI) { return new CastLifeTapAction(botAI); } static Action* unstable_affliction(PlayerbotAI* ai) { return new CastUnstableAfflictionAction(ai); } - static Action* unstable_affliction_on_attacker(PlayerbotAI* ai) { return new CastUnstableAfflictionOnAttackerAction(ai); } + static Action* unstable_affliction_on_attacker(PlayerbotAI* ai) + { + return new CastUnstableAfflictionOnAttackerAction(ai); + } static Action* haunt(PlayerbotAI* ai) { return new CastHauntAction(ai); } static Action* demonic_empowerment(PlayerbotAI* ai) { return new CastDemonicEmpowermentAction(ai); } static Action* metamorphosis(PlayerbotAI* ai) { return new CastMetamorphosisAction(ai); } @@ -345,11 +355,14 @@ private: static Action* shadowflame(PlayerbotAI* botAI) { return new CastShadowflameAction(botAI); } static Action* immolation_aura(PlayerbotAI* botAI) { return new CastImmolationAuraAction(botAI); } static Action* chaos_bolt(PlayerbotAI* botAI) { return new CastChaosBoltAction(botAI); } - static Action* soulshatter(PlayerbotAI* botAI) { return new CastSoulshatterAction(botAI);} + static Action* soulshatter(PlayerbotAI* botAI) { return new CastSoulshatterAction(botAI); } static Action* searing_pain(PlayerbotAI* botAI) { return new CastSearingPainAction(botAI); } static Action* shadow_ward(PlayerbotAI* botAI) { return new CastShadowWardAction(botAI); } static Action* curse_of_agony(PlayerbotAI* botAI) { return new CastCurseOfAgonyAction(botAI); } - static Action* curse_of_agony_on_attacker(PlayerbotAI* botAI) { return new CastCurseOfAgonyOnAttackerAction(botAI); } + static Action* curse_of_agony_on_attacker(PlayerbotAI* botAI) + { + return new CastCurseOfAgonyOnAttackerAction(botAI); + } static Action* curse_of_the_elements(PlayerbotAI* ai) { return new CastCurseOfTheElementsAction(ai); } static Action* curse_of_doom(PlayerbotAI* ai) { return new CastCurseOfDoomAction(ai); } static Action* curse_of_exhaustion(PlayerbotAI* ai) { return new CastCurseOfExhaustionAction(ai); } @@ -357,13 +370,47 @@ private: static Action* curse_of_weakness(PlayerbotAI* ai) { return new CastCurseOfWeaknessAction(ai); } }; -WarlockAiObjectContext::WarlockAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList WarlockAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList WarlockAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList WarlockAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList WarlockAiObjectContext::sharedValueContexts; + +WarlockAiObjectContext::WarlockAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void WarlockAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void WarlockAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new WarlockStrategyFactoryInternal()); strategyContexts.Add(new WarlockCombatStrategyFactoryInternal()); strategyContexts.Add(new WarlockPetStrategyFactoryInternal()); strategyContexts.Add(new WarlockSoulstoneStrategyFactoryInternal()); strategyContexts.Add(new WarlockCurseStrategyFactoryInternal()); +} + +void WarlockAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new WarlockAiObjectContextInternal()); +} + +void WarlockAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new WarlockTriggerFactoryInternal()); } + +void WarlockAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} \ No newline at end of file diff --git a/src/strategy/warlock/WarlockAiObjectContext.h b/src/strategy/warlock/WarlockAiObjectContext.h index c1feb912..08e6d0f5 100644 --- a/src/strategy/warlock/WarlockAiObjectContext.h +++ b/src/strategy/warlock/WarlockAiObjectContext.h @@ -14,6 +14,17 @@ class WarlockAiObjectContext : public AiObjectContext { public: WarlockAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif diff --git a/src/strategy/warrior/WarriorAiObjectContext.cpp b/src/strategy/warrior/WarriorAiObjectContext.cpp index 0a761c56..bcec922c 100644 --- a/src/strategy/warrior/WarriorAiObjectContext.cpp +++ b/src/strategy/warrior/WarriorAiObjectContext.cpp @@ -318,10 +318,44 @@ private: static Action* enraged_regeneration(PlayerbotAI* botAI) { return new CastEnragedRegenerationAction(botAI); } }; -WarriorAiObjectContext::WarriorAiObjectContext(PlayerbotAI* botAI) : AiObjectContext(botAI) +SharedNamedObjectContextList WarriorAiObjectContext::sharedStrategyContexts; +SharedNamedObjectContextList WarriorAiObjectContext::sharedActionContexts; +SharedNamedObjectContextList WarriorAiObjectContext::sharedTriggerContexts; +SharedNamedObjectContextList WarriorAiObjectContext::sharedValueContexts; + +WarriorAiObjectContext::WarriorAiObjectContext(PlayerbotAI* botAI) + : AiObjectContext(botAI, sharedStrategyContexts, sharedActionContexts, sharedTriggerContexts, sharedValueContexts) { +} + +void WarriorAiObjectContext::BuildSharedContexts() +{ + BuildSharedStrategyContexts(sharedStrategyContexts); + BuildSharedActionContexts(sharedActionContexts); + BuildSharedTriggerContexts(sharedTriggerContexts); + BuildSharedValueContexts(sharedValueContexts); +} + +void WarriorAiObjectContext::BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts) +{ + AiObjectContext::BuildSharedStrategyContexts(strategyContexts); strategyContexts.Add(new WarriorStrategyFactoryInternal()); strategyContexts.Add(new WarriorCombatStrategyFactoryInternal()); +} + +void WarriorAiObjectContext::BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts) +{ + AiObjectContext::BuildSharedActionContexts(actionContexts); actionContexts.Add(new WarriorAiObjectContextInternal()); +} + +void WarriorAiObjectContext::BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts) +{ + AiObjectContext::BuildSharedTriggerContexts(triggerContexts); triggerContexts.Add(new WarriorTriggerFactoryInternal()); } + +void WarriorAiObjectContext::BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts) +{ + AiObjectContext::BuildSharedValueContexts(valueContexts); +} \ No newline at end of file diff --git a/src/strategy/warrior/WarriorAiObjectContext.h b/src/strategy/warrior/WarriorAiObjectContext.h index ab522922..2c9bab97 100644 --- a/src/strategy/warrior/WarriorAiObjectContext.h +++ b/src/strategy/warrior/WarriorAiObjectContext.h @@ -14,6 +14,17 @@ class WarriorAiObjectContext : public AiObjectContext { public: WarriorAiObjectContext(PlayerbotAI* botAI); + + static void BuildSharedContexts(); + static void BuildSharedStrategyContexts(SharedNamedObjectContextList& strategyContexts); + static void BuildSharedActionContexts(SharedNamedObjectContextList& actionContexts); + static void BuildSharedTriggerContexts(SharedNamedObjectContextList& triggerContexts); + static void BuildSharedValueContexts(SharedNamedObjectContextList& valueContexts); + + static SharedNamedObjectContextList sharedStrategyContexts; + static SharedNamedObjectContextList sharedActionContexts; + static SharedNamedObjectContextList sharedTriggerContexts; + static SharedNamedObjectContextList sharedValueContexts; }; #endif