diff options
author | IntelligentQuantum <IntelligentQuantum@ProtonMail.Com> | 2022-07-15 18:41:49 +0430 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-15 16:11:49 +0200 |
commit | cc52712ac12e3d6a16aabcbd13807924c64aeb1e (patch) | |
tree | 3d6668eb91a9dba65225f6bf0bfd7c4a92c0f694 | |
parent | 02fa20b6380b991634198de9a295abac11152d60 (diff) |
refactor(Core/AI): factory functions cleanup (#11779)
35 files changed, 284 insertions, 310 deletions
diff --git a/src/common/Dynamic/FactoryHolder.h b/src/common/Dynamic/FactoryHolder.h index c1f1055b0b..093f6e4f3c 100644 --- a/src/common/Dynamic/FactoryHolder.h +++ b/src/common/Dynamic/FactoryHolder.h @@ -19,33 +19,29 @@ #define ACORE_FACTORY_HOLDER #include "Define.h" -#include "Dynamic/TypeList.h" #include "ObjectRegistry.h" +#include "TypeList.h" -/* - * FactoryHolder holds a factory object of a specific type +/** FactoryHolder holds a factory object of a specific type */ -template<class T, class Key = std::string> +template<class T, class O, class Key = std::string> class FactoryHolder { public: - typedef ObjectRegistry<FactoryHolder<T, Key >, Key > FactoryHolderRegistry; + typedef ObjectRegistry<FactoryHolder<T, O, Key>, Key> FactoryHolderRegistry; - FactoryHolder(Key k) : i_key(k) { } + explicit FactoryHolder(Key const& k) : _key(k) { } virtual ~FactoryHolder() { } - inline Key key() const { return i_key; } - void RegisterSelf(void) { FactoryHolderRegistry::instance()->InsertItem(this, i_key); } - void DeregisterSelf(void) { FactoryHolderRegistry::instance()->RemoveItem(this, false); } + void RegisterSelf() { FactoryHolderRegistry::instance()->InsertItem(this, _key); } /// Abstract Factory create method - virtual T* Create(void* data = nullptr) const = 0; + virtual T* Create(O* object = nullptr) const = 0; private: - Key i_key; + Key const _key; }; -/* - * Permissible is a classic way of letting the object decide +/** Permissible is a classic way of letting the object decide * whether how good they handle things. This is not retricted * to factory selectors. */ @@ -54,7 +50,6 @@ class Permissible { public: virtual ~Permissible() { } - virtual int Permit(const T*) const = 0; + virtual int32 Permit(T const*) const = 0; }; - #endif diff --git a/src/common/Dynamic/ObjectRegistry.h b/src/common/Dynamic/ObjectRegistry.h index 7cc2c9abca..d72fd7b3a7 100644 --- a/src/common/Dynamic/ObjectRegistry.h +++ b/src/common/Dynamic/ObjectRegistry.h @@ -23,20 +23,23 @@ #include <string> #include <unordered_map> #include <vector> +#include <memory> /** ObjectRegistry holds all registry item of the same type */ template<class T, class Key = std::string> -class ObjectRegistry +class ObjectRegistry final { public: - typedef std::map<Key, T*> RegistryMapType; + typedef std::map<Key, std::unique_ptr<T>> RegistryMapType; /// Returns a registry item - const T* GetRegistryItem(Key key) const + T const* GetRegistryItem(Key const& key) const { - typename RegistryMapType::const_iterator iter = i_registeredObjects.find(key); - return ( iter == i_registeredObjects.end() ? nullptr : iter->second ); + auto itr = _registeredObjects.find(key); + if (itr == _registeredObjects.end()) + return nullptr; + return itr->second.get(); } static ObjectRegistry<T, Key>* instance() @@ -46,72 +49,34 @@ public: } /// Inserts a registry item - bool InsertItem(T* obj, Key key, bool override = false) + bool InsertItem(T* obj, Key const& key, bool force = false) { - typename RegistryMapType::iterator iter = i_registeredObjects.find(key); - if ( iter != i_registeredObjects.end() ) + auto itr = _registeredObjects.find(key); + if (itr != _registeredObjects.end()) { - if ( !override ) + if (!force) { return false; } - delete iter->second; - i_registeredObjects.erase(iter); + _registeredObjects.erase(itr); } - i_registeredObjects[key] = obj; + _registeredObjects.emplace(std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(obj)); return true; } - /// Removes a registry item - void RemoveItem(Key key, bool delete_object = true) - { - typename RegistryMapType::iterator iter = i_registeredObjects.find(key); - if ( iter != i_registeredObjects.end() ) - { - if ( delete_object ) - { - delete iter->second; - } - i_registeredObjects.erase(iter); - } - } - - /// Returns true if registry contains an item - bool HasItem(Key key) const - { - return (i_registeredObjects.find(key) != i_registeredObjects.end()); - } - - /// Inefficiently return a vector of registered items - unsigned int GetRegisteredItems(std::vector<Key>& l) const - { - unsigned int sz = l.size(); - l.resize(sz + i_registeredObjects.size()); - for (typename RegistryMapType::const_iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter) - { - l[sz++] = iter->first; - } - return i_registeredObjects.size(); - } - /// Return the map of registered items RegistryMapType const& GetRegisteredItems() const { - return i_registeredObjects; + return _registeredObjects; } - ObjectRegistry() { } - ~ObjectRegistry() - { - for (typename RegistryMapType::iterator iter = i_registeredObjects.begin(); iter != i_registeredObjects.end(); ++iter) - { - delete iter->second; - } - i_registeredObjects.clear(); - } private: - RegistryMapType i_registeredObjects; + RegistryMapType _registeredObjects; + + // non instanceable, only static + ObjectRegistry() { } + ~ObjectRegistry() { } }; #endif diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp index 336733978e..18c7a2382d 100644 --- a/src/server/game/AI/CoreAI/CombatAI.cpp +++ b/src/server/game/AI/CoreAI/CombatAI.cpp @@ -26,7 +26,7 @@ // AggressorAI ///////////////// -int AggressorAI::Permissible(Creature const* creature) +int32 AggressorAI::Permissible(Creature const* creature) { // have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight if (!creature->IsCivilian() && !creature->IsNeutralToAll()) @@ -320,3 +320,11 @@ void VehicleAI::CheckConditions(uint32 diff) else m_ConditionsTimer -= diff; } + +int32 VehicleAI::Permissible(Creature const* creature) +{ + if (creature->IsVehicle()) + return PERMIT_BASE_SPECIAL; + + return PERMIT_BASE_NO; +} diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h index 39c016bc9b..6f58253852 100644 --- a/src/server/game/AI/CoreAI/CombatAI.h +++ b/src/server/game/AI/CoreAI/CombatAI.h @@ -31,7 +31,7 @@ public: explicit AggressorAI(Creature* c) : CreatureAI(c) {} void UpdateAI(uint32) override; - static int Permissible(Creature const*); + static int32 Permissible(Creature const* creature); }; typedef std::vector<uint32> SpellVct; @@ -47,7 +47,7 @@ public: void JustDied(Unit* killer) override; void UpdateAI(uint32 diff) override; - static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } + static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } protected: EventMap events; @@ -73,7 +73,7 @@ public: void AttackStart(Unit* who) override; void UpdateAI(uint32 diff) override; - static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } + static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } protected: float m_minRange; @@ -87,7 +87,7 @@ public: void AttackStart(Unit* who) override; void UpdateAI(uint32 diff) override; - static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } + static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } protected: float m_minRange; @@ -105,7 +105,7 @@ public: void AttackStart(Unit*) override {} void OnCharmed(bool apply) override; - static int Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } + static int32 Permissible(Creature const* creature); private: void LoadConditions(); diff --git a/src/server/game/AI/CoreAI/GameObjectAI.cpp b/src/server/game/AI/CoreAI/GameObjectAI.cpp index 4594ce83a8..ca52673315 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.cpp +++ b/src/server/game/AI/CoreAI/GameObjectAI.cpp @@ -17,12 +17,15 @@ #include "GameObjectAI.h" -//GameObjectAI::GameObjectAI(GameObject* g) : go(g) {} -int GameObjectAI::Permissible(GameObject const* go) +int32 GameObjectAI::Permissible(GameObject const* /*go*/) { - if (go->GetAIName() == "GameObjectAI") - return PERMIT_BASE_SPECIAL; return PERMIT_BASE_NO; } -NullGameObjectAI::NullGameObjectAI(GameObject* g) : GameObjectAI(g) {} +NullGameObjectAI::NullGameObjectAI(GameObject* go) : GameObjectAI(go) { } + +int32 NullGameObjectAI::Permissible(GameObject const* /*go*/) +{ + return PERMIT_BASE_IDLE; +} + diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h index 1bf62bcebc..3a2731105f 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.h +++ b/src/server/game/AI/CoreAI/GameObjectAI.h @@ -49,7 +49,7 @@ public: virtual void SetGUID(ObjectGuid /*guid*/, int32 /*id = 0 */) {} virtual ObjectGuid GetGUID(int32 /*id = 0 */) const { return ObjectGuid::Empty; } - static int Permissible(GameObject const* go); + static int32 Permissible(GameObject const* go); virtual bool GossipHello(Player* /*player*/, bool /*reportUse*/) { return false; } virtual bool GossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) { return false; } @@ -76,6 +76,6 @@ public: void UpdateAI(uint32 /*diff*/) override {} - static int Permissible(GameObject const* /*go*/) { return PERMIT_BASE_IDLE; } + static int32 Permissible(GameObject const* go); }; #endif diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp index 0253eb0075..86c6fc1f0b 100644 --- a/src/server/game/AI/CoreAI/GuardAI.cpp +++ b/src/server/game/AI/CoreAI/GuardAI.cpp @@ -19,10 +19,10 @@ #include "CreatureAIImpl.h" #include "Player.h" -int GuardAI::Permissible(Creature const* creature) +int32 GuardAI::Permissible(Creature const* creature) { if (creature->IsGuard()) - return PERMIT_BASE_SPECIAL; + return PERMIT_BASE_PROACTIVE; return PERMIT_BASE_NO; } diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h index c48b93a9f2..d8c7c93109 100644 --- a/src/server/game/AI/CoreAI/GuardAI.h +++ b/src/server/game/AI/CoreAI/GuardAI.h @@ -27,7 +27,7 @@ class GuardAI : public ScriptedAI public: explicit GuardAI(Creature* creature); - static int Permissible(Creature const* creature); + static int32 Permissible(Creature const* creature); void Reset() override; void EnterEvadeMode(EvadeReason /*why*/) override; diff --git a/src/server/game/AI/CoreAI/PassiveAI.cpp b/src/server/game/AI/CoreAI/PassiveAI.cpp index 1a576f47e0..d1ac8350f5 100644 --- a/src/server/game/AI/CoreAI/PassiveAI.cpp +++ b/src/server/game/AI/CoreAI/PassiveAI.cpp @@ -23,6 +23,17 @@ PassiveAI::PassiveAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASS PossessedAI::PossessedAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); } NullCreatureAI::NullCreatureAI(Creature* c) : CreatureAI(c) { me->SetReactState(REACT_PASSIVE); } +int32 NullCreatureAI::Permissible(Creature const* creature) +{ + if (creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK)) + return PERMIT_BASE_PROACTIVE + 50; + + if (creature->IsTrigger()) + return PERMIT_BASE_REACTIVE; + + return PERMIT_BASE_IDLE; +} + void PassiveAI::UpdateAI(uint32) { if (me->IsInCombat() && me->getAttackers().empty()) @@ -84,8 +95,24 @@ void CritterAI::UpdateAI(uint32 diff) } } +int32 CritterAI::Permissible(Creature const* creature) +{ + if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) + return PERMIT_BASE_PROACTIVE; + + return PERMIT_BASE_NO; +} + void TriggerAI::IsSummonedBy(Unit* summoner) { if (me->m_spells[0]) me->CastSpell(me, me->m_spells[0], false, 0, 0, summoner ? summoner->GetGUID() : ObjectGuid::Empty); } + +int32 TriggerAI::Permissible(Creature const* creature) +{ + if (creature->IsTrigger() && creature->m_spells[0]) + return PERMIT_BASE_SPECIAL; + + return PERMIT_BASE_NO; +} diff --git a/src/server/game/AI/CoreAI/PassiveAI.h b/src/server/game/AI/CoreAI/PassiveAI.h index 9f17a59358..79046100ea 100644 --- a/src/server/game/AI/CoreAI/PassiveAI.h +++ b/src/server/game/AI/CoreAI/PassiveAI.h @@ -30,7 +30,7 @@ public: void AttackStart(Unit*) override {} void UpdateAI(uint32) override; - static int Permissible(Creature const*) { return PERMIT_BASE_IDLE; } + static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } }; class PossessedAI : public CreatureAI @@ -46,7 +46,7 @@ public: void JustDied(Unit*) override; void KilledUnit(Unit* victim) override; - static int Permissible(Creature const*) { return PERMIT_BASE_IDLE; } + static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } }; class NullCreatureAI : public CreatureAI @@ -60,7 +60,7 @@ public: void EnterEvadeMode(EvadeReason /*why*/) override {} void OnCharmed(bool /*apply*/) override {} - static int Permissible(Creature const*) { return PERMIT_BASE_IDLE; } + static int32 Permissible(Creature const* creature); }; class CritterAI : public PassiveAI @@ -72,6 +72,7 @@ public: void EnterEvadeMode(EvadeReason why) override; void UpdateAI(uint32) override; + static int32 Permissible(Creature const* creature); // Xinef: Added private: uint32 _combatTimer; @@ -82,6 +83,8 @@ class TriggerAI : public NullCreatureAI public: explicit TriggerAI(Creature* c) : NullCreatureAI(c) {} void IsSummonedBy(Unit* summoner) override; + + static int32 Permissible(Creature const* creature); }; #endif diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index fe71ffadc5..3ed00426f9 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -28,11 +28,18 @@ #include "SpellMgr.h" #include "Util.h" -int PetAI::Permissible(Creature const* creature) +int32 PetAI::Permissible(Creature const* creature) { if (creature->IsPet()) return PERMIT_BASE_SPECIAL; + if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) + { + if (reinterpret_cast<Guardian const*>(creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER) + return PERMIT_BASE_PROACTIVE; + return PERMIT_BASE_REACTIVE; + } + return PERMIT_BASE_NO; } diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h index bf76852893..7db553adb1 100644 --- a/src/server/game/AI/CoreAI/PetAI.h +++ b/src/server/game/AI/CoreAI/PetAI.h @@ -49,7 +49,7 @@ public: explicit PetAI(Creature* c); void UpdateAI(uint32) override; - static int Permissible(Creature const*); + static int32 Permissible(Creature const* creature); void KilledUnit(Unit* /*victim*/) override; void AttackStart(Unit* target) override; diff --git a/src/server/game/AI/CoreAI/ReactorAI.cpp b/src/server/game/AI/CoreAI/ReactorAI.cpp index 37165d7f14..e50356f340 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.cpp +++ b/src/server/game/AI/CoreAI/ReactorAI.cpp @@ -19,7 +19,7 @@ #include "CreatureAIImpl.h" #include "Errors.h" -int ReactorAI::Permissible(Creature const* creature) +int32 ReactorAI::Permissible(Creature const* creature) { if (creature->IsCivilian() || creature->IsNeutralToAll()) return PERMIT_BASE_REACTIVE; diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h index fb65eb0fc6..b6a203189b 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.h +++ b/src/server/game/AI/CoreAI/ReactorAI.h @@ -30,6 +30,6 @@ public: void MoveInLineOfSight(Unit*) override {} void UpdateAI(uint32 diff) override; - static int Permissible(Creature const*); + static int32 Permissible(Creature const* creature); }; #endif diff --git a/src/server/game/AI/CoreAI/TotemAI.cpp b/src/server/game/AI/CoreAI/TotemAI.cpp index 77560df6bc..d12232f27a 100644 --- a/src/server/game/AI/CoreAI/TotemAI.cpp +++ b/src/server/game/AI/CoreAI/TotemAI.cpp @@ -25,7 +25,7 @@ #include "SpellMgr.h" #include "Totem.h" -int TotemAI::Permissible(Creature const* creature) +int32 TotemAI::Permissible(Creature const* creature) { if (creature->IsTotem()) return PERMIT_BASE_PROACTIVE; diff --git a/src/server/game/AI/CoreAI/TotemAI.h b/src/server/game/AI/CoreAI/TotemAI.h index 837d5e0fdc..36639a006a 100644 --- a/src/server/game/AI/CoreAI/TotemAI.h +++ b/src/server/game/AI/CoreAI/TotemAI.h @@ -38,7 +38,7 @@ public: void DoAction(int32 param) override; void UpdateAI(uint32 diff) override; - static int Permissible(Creature const* creature); + static int32 Permissible(Creature const* creature); private: ObjectGuid i_victimGuid; diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index b03e25578f..a85638975b 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -222,7 +222,7 @@ private: bool m_MoveInLineOfSight_locked; }; -enum Permitions +enum Permitions : int32 { PERMIT_BASE_NO = -1, PERMIT_BASE_IDLE = 1, diff --git a/src/server/game/AI/CreatureAIFactory.h b/src/server/game/AI/CreatureAIFactory.h index 233d4c1658..6ae188a7bb 100644 --- a/src/server/game/AI/CreatureAIFactory.h +++ b/src/server/game/AI/CreatureAIFactory.h @@ -19,60 +19,32 @@ #define ACORE_CREATUREAIFACTORY_H #include "FactoryHolder.h" -#include "GameObjectAI.h" #include "ObjectRegistry.h" -struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature> -{ - SelectableAI(const char* id) : FactoryHolder<CreatureAI>(id) {} -}; +typedef FactoryHolder<CreatureAI, Creature> CreatureAICreator; -template<class REAL_AI> -struct CreatureAIFactory : public SelectableAI +struct SelectableAI : public CreatureAICreator, public Permissible<Creature> { - CreatureAIFactory(const char* name) : SelectableAI(name) {} - - CreatureAI* Create(void*) const; - - int Permit(Creature const* c) const { return REAL_AI::Permissible(c); } + SelectableAI(std::string const& name) : CreatureAICreator(name), Permissible<Creature>() { } }; template<class REAL_AI> -inline CreatureAI* -CreatureAIFactory<REAL_AI>::Create(void* data) const -{ - Creature* creature = reinterpret_cast<Creature*>(data); - return (new REAL_AI(creature)); -} - -typedef FactoryHolder<CreatureAI> CreatureAICreator; -typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry; - -//GO -struct SelectableGameObjectAI : public FactoryHolder<GameObjectAI>, public Permissible<GameObject> -{ - SelectableGameObjectAI(const char* id) : FactoryHolder<GameObjectAI>(id) {} -}; - -template<class REAL_GO_AI> -struct GameObjectAIFactory : public SelectableGameObjectAI +struct CreatureAIFactory : public SelectableAI { - GameObjectAIFactory(const char* name) : SelectableGameObjectAI(name) {} + CreatureAIFactory(std::string const& name) : SelectableAI(name) { } - GameObjectAI* Create(void*) const; + inline CreatureAI* Create(Creature* c) const override + { + return new REAL_AI(c); + } - int Permit(GameObject const* g) const { return REAL_GO_AI::Permissible(g); } + int32 Permit(Creature const* c) const override + { + return REAL_AI::Permissible(c); + } }; -template<class REAL_GO_AI> -inline GameObjectAI* -GameObjectAIFactory<REAL_GO_AI>::Create(void* data) const -{ - GameObject* go = reinterpret_cast<GameObject*>(data); - return (new REAL_GO_AI(go)); -} - -typedef FactoryHolder<GameObjectAI> GameObjectAICreator; -typedef FactoryHolder<GameObjectAI>::FactoryHolderRegistry GameObjectAIRegistry; +typedef CreatureAICreator::FactoryHolderRegistry CreatureAIRegistry; +#define sCreatureAIRegistry CreatureAIRegistry::instance() #endif diff --git a/src/server/game/AI/CreatureAIRegistry.cpp b/src/server/game/AI/CreatureAIRegistry.cpp index f3d29e5beb..4e1f6fdc5f 100644 --- a/src/server/game/AI/CreatureAIRegistry.cpp +++ b/src/server/game/AI/CreatureAIRegistry.cpp @@ -19,7 +19,7 @@ #include "CombatAI.h" #include "CreatureAIFactory.h" #include "GuardAI.h" -#include "MovementGeneratorImpl.h" +#include "MovementGenerator.h" #include "PassiveAI.h" #include "PetAI.h" #include "RandomMovementGenerator.h" @@ -27,6 +27,7 @@ #include "SmartAI.h" #include "TotemAI.h" #include "WaypointMovementGenerator.h" +#include "GameObjectAIFactory.h" namespace AIRegistry { @@ -47,10 +48,12 @@ namespace AIRegistry (new CreatureAIFactory<VehicleAI>("VehicleAI"))->RegisterSelf(); (new CreatureAIFactory<SmartAI>("SmartAI"))->RegisterSelf(); + (new GameObjectAIFactory<NullGameObjectAI>("NullGameObjectAI"))->RegisterSelf(); (new GameObjectAIFactory<GameObjectAI>("GameObjectAI"))->RegisterSelf(); (new GameObjectAIFactory<SmartGameObjectAI>("SmartGameObjectAI"))->RegisterSelf(); - (new MovementGeneratorFactory<RandomMovementGenerator<Creature> >(RANDOM_MOTION_TYPE))->RegisterSelf(); - (new MovementGeneratorFactory<WaypointMovementGenerator<Creature> >(WAYPOINT_MOTION_TYPE))->RegisterSelf(); + (new IdleMovementFactory())->RegisterSelf(); + (new MovementGeneratorFactory<RandomMovementGenerator<Creature>>(RANDOM_MOTION_TYPE))->RegisterSelf(); + (new MovementGeneratorFactory<WaypointMovementGenerator<Creature>>(WAYPOINT_MOTION_TYPE))->RegisterSelf(); } } diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index a9ed9832c6..d4c1e71a10 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -15,132 +15,102 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "CreatureAISelector.h" #include "Creature.h" +#include "CreatureAISelector.h" #include "CreatureAIFactory.h" + #include "MovementGenerator.h" -#include "PassiveAI.h" -#include "Pet.h" + +#include "GameObject.h" +#include "GameObjectAIFactory.h" + #include "ScriptMgr.h" -#include "TemporarySummon.h" namespace FactorySelector { - CreatureAI* selectAI(Creature* creature) + template <class T> + struct PermissibleOrderPred { - const CreatureAICreator* ai_factory = nullptr; - CreatureAIRegistry& ai_registry(*CreatureAIRegistry::instance()); + public: + PermissibleOrderPred(T const* obj) : _obj(obj) { } - // xinef: if we have controlable guardian, define petai for players as they can steer him, otherwise db / normal ai - // xinef: dont remember why i changed this qq commented out as may break some quests - if (creature->IsPet()/* || (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)*/) - ai_factory = ai_registry.GetRegistryItem("PetAI"); + template <class Value> + bool operator()(Value const& left, Value const& right) const + { + Permissible<T> const* leftPermit = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(left.second.get())); + Permissible<T> const* rightPermit = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(right.second.get())); + + return leftPermit->Permit(_obj) < rightPermit->Permit(_obj); + } + + private: + T const* const _obj; + }; + + CreatureAI* SelectAI(Creature* creature) + { + CreatureAICreator const* ai_factory = nullptr; - //scriptname in db + // scriptname in db if (!ai_factory) if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature)) return scriptedAI; // AIname in db - std::string ainame = creature->GetAIName(); - if (!ai_factory && !ainame.empty()) - ai_factory = ai_registry.GetRegistryItem(ainame); + std::string const& aiName = creature->GetAIName(); + if (!ai_factory && !aiName.empty()) + ai_factory = sCreatureAIRegistry->GetRegistryItem(aiName); - // select by NPC flags + // select by permit check if (!ai_factory) { - if (creature->IsVehicle()) - ai_factory = ai_registry.GetRegistryItem("VehicleAI"); - else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER) - ai_factory = ai_registry.GetRegistryItem("PetAI"); - else if (creature->HasNpcFlag(UNIT_NPC_FLAG_SPELLCLICK)) - ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); - else if (creature->IsGuard()) - ai_factory = ai_registry.GetRegistryItem("GuardAI"); - else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN)) - ai_factory = ai_registry.GetRegistryItem("PetAI"); - else if (creature->IsTotem()) - ai_factory = ai_registry.GetRegistryItem("TotemAI"); - else if (creature->IsTrigger()) - { - if (creature->m_spells[0]) - ai_factory = ai_registry.GetRegistryItem("TriggerAI"); - else - ai_factory = ai_registry.GetRegistryItem("NullCreatureAI"); - } - else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN)) - ai_factory = ai_registry.GetRegistryItem("CritterAI"); + CreatureAIRegistry::RegistryMapType const& items = sCreatureAIRegistry->GetRegisteredItems(); + auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<Creature>(creature)); + if (itr != items.end()) + ai_factory = itr->second.get(); } - // select by permit check if (!ai_factory) - { - int best_val = -1; - typedef CreatureAIRegistry::RegistryMapType RMT; - RMT const& l = ai_registry.GetRegisteredItems(); - for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter) - { - const CreatureAICreator* factory = iter->second; - const SelectableAI* p = dynamic_cast<const SelectableAI*>(factory); - ASSERT(p); - int val = p->Permit(creature); - if (val > best_val) - { - best_val = val; - ai_factory = p; - } - } - } + ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI"); - // select NullCreatureAI if not another cases - ainame = (!ai_factory) ? "NullCreatureAI" : ai_factory->key(); - LOG_DEBUG("scripts.ai", "Creature {} used AI is {}.", creature->GetGUID().ToString(), ainame); - return (!ai_factory ? new NullCreatureAI(creature) : ai_factory->Create(creature)); + return ASSERT_NOTNULL(ai_factory)->Create(creature); } - MovementGenerator* selectMovementGenerator(Creature* creature) + MovementGenerator* SelectMovementGenerator(Unit* unit) { - MovementGeneratorRegistry& mv_registry(*MovementGeneratorRegistry::instance()); - ASSERT(creature->GetCreatureTemplate()); - const MovementGeneratorCreator* mv_factory = mv_registry.GetRegistryItem(creature->GetDefaultMovementType()); + MovementGeneratorType type = IDLE_MOTION_TYPE; + if (unit->GetTypeId() == TYPEID_UNIT) + type = unit->ToCreature()->GetDefaultMovementType(); - /* if (mv_factory == nullptr) - { - int best_val = -1; - std::vector<std::string> l; - mv_registry.GetRegisteredItems(l); - for (std::vector<std::string>::iterator iter = l.begin(); iter != l.end(); ++iter) - { - const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str()); - const SelectableMovement *p = dynamic_cast<const SelectableMovement *>(factory); - ASSERT(p != nullptr); - int val = p->Permit(creature); - if (val > best_val) - { - best_val = val; - mv_factory = p; - } - } - }*/ - - return (!mv_factory ? nullptr : mv_factory->Create(creature)); + MovementGeneratorCreator const* mv_factory = sMovementGeneratorRegistry->GetRegistryItem(type); + return ASSERT_NOTNULL(mv_factory)->Create(unit); } GameObjectAI* SelectGameObjectAI(GameObject* go) { - const GameObjectAICreator* ai_factory = nullptr; - GameObjectAIRegistry& ai_registry(*GameObjectAIRegistry::instance()); + GameObjectAICreator const* ai_factory = nullptr; + // scriptname in db if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go)) return scriptedAI; - ai_factory = ai_registry.GetRegistryItem(go->GetAIName()); + // AIname in db + std::string const& aiName = go->GetAIName(); + if (!ai_factory && !aiName.empty()) + ai_factory = sGameObjectAIRegistry->GetRegistryItem(aiName); - //future goAI types go here + // select by permit check + if (!ai_factory) + { + GameObjectAIRegistry::RegistryMapType const& items = sGameObjectAIRegistry->GetRegisteredItems(); + auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<GameObject>(go)); + if (itr != items.end()) + ai_factory = itr->second.get(); + } - std::string ainame = (!ai_factory || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key(); - LOG_DEBUG("scripts.ai", "GameObject {} used AI is {}.", go->GetGUID().ToString(), ainame); + if (!ai_factory) + ai_factory = sGameObjectAIRegistry->GetRegistryItem("NullGameObjectAI"); - return (!ai_factory ? new NullGameObjectAI(go) : ai_factory->Create(go)); + return ASSERT_NOTNULL(ai_factory)->Create(go); } } diff --git a/src/server/game/AI/CreatureAISelector.h b/src/server/game/AI/CreatureAISelector.h index 936587e122..a5df78f81e 100644 --- a/src/server/game/AI/CreatureAISelector.h +++ b/src/server/game/AI/CreatureAISelector.h @@ -21,13 +21,14 @@ class CreatureAI; class Creature; class MovementGenerator; +class Unit; class GameObjectAI; class GameObject; namespace FactorySelector { - CreatureAI* selectAI(Creature*); - MovementGenerator* selectMovementGenerator(Creature*); - GameObjectAI* SelectGameObjectAI(GameObject*); + AC_GAME_API CreatureAI* SelectAI(Creature* creature); + AC_GAME_API MovementGenerator* SelectMovementGenerator(Unit* unit); + AC_GAME_API GameObjectAI* SelectGameObjectAI(GameObject* go); } #endif diff --git a/src/server/game/AI/GameObjectAIFactory.h b/src/server/game/AI/GameObjectAIFactory.h new file mode 100644 index 0000000000..bfebd358b9 --- /dev/null +++ b/src/server/game/AI/GameObjectAIFactory.h @@ -0,0 +1,51 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ACORE_GAMEOBJECTAIFACTORY_H +#define ACORE_GAMEOBJECTAIFACTORY_H + +#include "ObjectRegistry.h" +#include "FactoryHolder.h" + +typedef FactoryHolder<GameObjectAI, GameObject> GameObjectAICreator; + +struct SelectableGameObjectAI : public GameObjectAICreator, public Permissible<GameObject> +{ + SelectableGameObjectAI(std::string const& name) : GameObjectAICreator(name), Permissible<GameObject>() { } +}; + +template<class REAL_GO_AI> +struct GameObjectAIFactory : public SelectableGameObjectAI +{ + GameObjectAIFactory(std::string const& name) : SelectableGameObjectAI(name) { } + + GameObjectAI* Create(GameObject* go) const override + { + return new REAL_GO_AI(go); + } + + int32 Permit(GameObject const* go) const override + { + return REAL_GO_AI::Permissible(go); + } +}; + +typedef GameObjectAICreator::FactoryHolderRegistry GameObjectAIRegistry; + +#define sGameObjectAIRegistry GameObjectAIRegistry::instance() + +#endif diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 6129812601..34a6111d44 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -763,13 +763,6 @@ void SmartAI::JustRespawned() mFollowArrivedAlive = true; } -int SmartAI::Permissible(Creature const* creature) -{ - if (creature->GetAIName() == "SmartAI") - return PERMIT_BASE_SPECIAL; - return PERMIT_BASE_NO; -} - void SmartAI::JustReachedHome() { GetScript()->OnReset(); @@ -1133,13 +1126,6 @@ void SmartGameObjectAI::SummonedCreatureDies(Creature* summon, Unit* /*killer*/) GetScript()->ProcessEventsFor(SMART_EVENT_SUMMONED_UNIT_DIES, summon); } -int SmartGameObjectAI::Permissible(GameObject const* g) -{ - if (g->GetAIName() == "SmartGameObjectAI") - return PERMIT_BASE_SPECIAL; - return PERMIT_BASE_NO; -} - void SmartGameObjectAI::UpdateAI(uint32 diff) { GetScript()->OnUpdate(diff); diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 7bc589ec55..38b07a19b7 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -164,7 +164,7 @@ public: ObjectGuid GetGUID(int32 id = 0) const override; //core related - static int32 Permissible(Creature const*); + static int32 Permissible(Creature const* /*creature*/) { return PERMIT_BASE_NO; } // Called at movepoint reached void MovepointReached(uint32 id); @@ -259,7 +259,7 @@ public: void InitializeAI() override; void Reset() override; SmartScript* GetScript() { return &mScript; } - static int32 Permissible(GameObject const* g); + static int32 Permissible(GameObject const* /*go*/) { return PERMIT_BASE_NO; } bool GossipHello(Player* player, bool reportUse) override; bool GossipSelect(Player* player, uint32 sender, uint32 action) override; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 6af1be4419..ecacbf3b31 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1020,7 +1020,7 @@ bool Creature::AIM_Initialize(CreatureAI* ai) // Xinef: called in add to world //Motion_Initialize(); - i_AI = ai ? ai : FactorySelector::selectAI(this); + i_AI = ai ? ai : FactorySelector::SelectAI(this); delete oldAI; IsAIEnabled = true; i_AI->InitializeAI(); @@ -2860,7 +2860,7 @@ uint8 Creature::getLevelForTarget(WorldObject const* target) const return uint8(level); } -std::string Creature::GetAIName() const +std::string const& Creature::GetAIName() const { return sObjectMgr->GetCreatureTemplate(GetEntry())->AIName; } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index e404dcc833..b1fd4eea4a 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -198,7 +198,7 @@ public: void SetDetectionDistance(float dist){ m_detectionDistance = dist; } [[nodiscard]] CreatureAddon const* GetCreatureAddon() const; - [[nodiscard]] std::string GetAIName() const; + [[nodiscard]] std::string const& GetAIName() const; [[nodiscard]] std::string GetScriptName() const; [[nodiscard]] uint32 GetScriptId() const; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index be992f4fef..2a75ff688f 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -96,7 +96,7 @@ bool GameObject::AIM_Initialize() return true; } -std::string GameObject::GetAIName() const +std::string const& GameObject::GetAIName() const { return sObjectMgr->GetGameObjectTemplate(GetEntry())->AIName; } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index bd8500f973..a13a1be393 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -1000,7 +1000,7 @@ public: [[nodiscard]] virtual uint32 GetScriptId() const; [[nodiscard]] GameObjectAI* AI() const { return m_AI; } - [[nodiscard]] std::string GetAIName() const; + [[nodiscard]] std::string const& GetAIName() const; void SetDisplayId(uint32 displayid); [[nodiscard]] uint32 GetDisplayId() const { return GetUInt32Value(GAMEOBJECT_DISPLAYID); } diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 6d2cdcb95f..fe8075ddb5 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -32,6 +32,11 @@ #include "TargetedMovementGenerator.h" #include "WaypointMovementGenerator.h" +inline MovementGenerator* GetIdleMovementGenerator() +{ + return sMovementGeneratorRegistry->GetRegistryItem(IDLE_MOTION_TYPE)->Create(); +} + // ---- ChaseRange ---- // ChaseRange::ChaseRange(float range) : MinRange(range > CONTACT_DISTANCE ? 0 : range - CONTACT_DISTANCE), MinTolerance(range), MaxRange(range + CONTACT_DISTANCE), MaxTolerance(range) { } @@ -59,9 +64,9 @@ bool ChaseAngle::IsAngleOkay(float relativeAngle) const return (std::min(diff, float(2 * M_PI) - diff) <= Tolerance); } -inline bool isStatic(MovementGenerator* mv) +inline bool isStatic(MovementGenerator* movement) { - return (mv == &si_idleMovement); + return (movement == GetIdleMovementGenerator()); } void MotionMaster::Initialize() @@ -80,16 +85,7 @@ void MotionMaster::Initialize() // set new default movement generator void MotionMaster::InitDefault() { - // Xinef: Do not allow to initialize any motion generator for dead creatures - if (_owner->GetTypeId() == TYPEID_UNIT && _owner->IsAlive()) - { - MovementGenerator* movement = FactorySelector::selectMovementGenerator(_owner->ToCreature()); - Mutate(!movement ? &si_idleMovement : movement, MOTION_SLOT_IDLE); - } - else - { - Mutate(&si_idleMovement, MOTION_SLOT_IDLE); - } + Mutate(FactorySelector::SelectMovementGenerator(_owner), MOTION_SLOT_IDLE); } MotionMaster::~MotionMaster() @@ -236,7 +232,7 @@ void MotionMaster::MoveIdle() { //! Should be preceded by MovementExpired or Clear if there's an overlying movementgenerator active if (empty() || !isStatic(top())) - Mutate(&si_idleMovement, MOTION_SLOT_IDLE); + Mutate(GetIdleMovementGenerator(), MOTION_SLOT_IDLE); } void MotionMaster::MoveRandom(float wanderDistance) diff --git a/src/server/game/Movement/MovementGenerator.cpp b/src/server/game/Movement/MovementGenerator.cpp index 3e80ab121c..a14578b26e 100644 --- a/src/server/game/Movement/MovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerator.cpp @@ -16,7 +16,14 @@ */ #include "MovementGenerator.h" +#include "IdleMovementGenerator.h" MovementGenerator::~MovementGenerator() { } + +MovementGenerator* IdleMovementFactory::Create(Unit* /*object*/) const +{ + static IdleMovementGenerator instance; + return &instance; +} diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index 5ea148e2cc..2f317ec484 100644 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -82,19 +82,28 @@ public: } }; -struct SelectableMovement : public FactoryHolder<MovementGenerator, MovementGeneratorType> +typedef FactoryHolder<MovementGenerator, Unit, MovementGeneratorType> MovementGeneratorCreator; + +template<class Movement> +struct MovementGeneratorFactory : public MovementGeneratorCreator { - SelectableMovement(MovementGeneratorType mgt) : FactoryHolder<MovementGenerator, MovementGeneratorType>(mgt) {} + MovementGeneratorFactory(MovementGeneratorType movementGeneratorType) : MovementGeneratorCreator(movementGeneratorType) { } + + MovementGenerator* Create(Unit* /*object*/) const + { + return new Movement(); + } }; -template<class REAL_MOVEMENT> -struct MovementGeneratorFactory : public SelectableMovement +struct IdleMovementFactory : public MovementGeneratorCreator { - MovementGeneratorFactory(MovementGeneratorType mgt) : SelectableMovement(mgt) {} + IdleMovementFactory() : MovementGeneratorCreator(IDLE_MOTION_TYPE) { } - MovementGenerator* Create(void*) const; + MovementGenerator* Create(Unit* object) const override; }; -typedef FactoryHolder<MovementGenerator, MovementGeneratorType> MovementGeneratorCreator; -typedef FactoryHolder<MovementGenerator, MovementGeneratorType>::FactoryHolderRegistry MovementGeneratorRegistry; +typedef MovementGeneratorCreator::FactoryHolderRegistry MovementGeneratorRegistry; + +#define sMovementGeneratorRegistry MovementGeneratorRegistry::instance() + #endif diff --git a/src/server/game/Movement/MovementGeneratorImpl.h b/src/server/game/Movement/MovementGeneratorImpl.h deleted file mode 100644 index d566fbbcb4..0000000000 --- a/src/server/game/Movement/MovementGeneratorImpl.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef ACORE_MOVEMENTGENERATOR_IMPL_H -#define ACORE_MOVEMENTGENERATOR_IMPL_H - -#include "MovementGenerator.h" - -template<class MOVEMENT_GEN> -inline MovementGenerator* -MovementGeneratorFactory<MOVEMENT_GEN>::Create(void* /*data*/) const -{ - return (new MOVEMENT_GEN()); -} -#endif diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp index da3058c769..5f64daef33 100644 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp @@ -19,8 +19,6 @@ #include "Creature.h" #include "CreatureAI.h" -IdleMovementGenerator si_idleMovement; - // StopMoving is needed to make unit stop if its last movement generator expires // But it should not be sent otherwise there are many redundent packets void IdleMovementGenerator::Initialize(Unit* owner) diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h index b1571f66d7..293862bdda 100644 --- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.h @@ -30,8 +30,6 @@ public: MovementGeneratorType GetMovementGeneratorType() override { return IDLE_MOTION_TYPE; } }; -extern IdleMovementGenerator si_idleMovement; - class RotateMovementGenerator : public MovementGenerator { public: diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 3ca17f2ed2..c2e8463960 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -16,10 +16,14 @@ */ #include "MapBuilder.h" +#include "IntermediateValues.h" #include "MapDefines.h" #include "MapTree.h" #include "ModelInstance.h" #include "PathCommon.h" +#include "StringFormat.h" +#include "VMapFactory.h" +#include "VMapMgr2.h" #include <DetourCommon.h> #include <DetourNavMesh.h> #include <DetourNavMeshBuilder.h> |