From 1881088744315ed3edcb1a61290cd5bde6ff1d9a Mon Sep 17 00:00:00 2001 From: ariel- Date: Thu, 1 Jun 2017 02:29:20 -0300 Subject: Core/AI: Factory functions cleanup - Get rid of fugly void pointers - Streamlined AI selection code, using Permissible as it should've been instead of harcoded checks on the selector code - Moved IdleMovementGenerator singleton to factory code (cherry picked from commit ce3787f190d28c1e981598eef2cd24c622a2cbae) --- src/server/shared/Dynamic/ObjectRegistry.h | 71 +++++++++--------------------- 1 file changed, 21 insertions(+), 50 deletions(-) (limited to 'src/server/shared/Dynamic/ObjectRegistry.h') diff --git a/src/server/shared/Dynamic/ObjectRegistry.h b/src/server/shared/Dynamic/ObjectRegistry.h index 45380d699d3..89ca33f15fa 100644 --- a/src/server/shared/Dynamic/ObjectRegistry.h +++ b/src/server/shared/Dynamic/ObjectRegistry.h @@ -23,14 +23,15 @@ #include #include #include +#include /** ObjectRegistry holds all registry item of the same type */ template -class ObjectRegistry +class ObjectRegistry final { public: - typedef std::map RegistryMapType; + typedef std::map> RegistryMapType; static ObjectRegistry* instance() { @@ -39,71 +40,41 @@ class ObjectRegistry } /// 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() ? NULL : iter->second ); + auto itr = _registeredObjects.find(key); + if (itr == _registeredObjects.end()) + return nullptr; + return itr->second.get(); } /// 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 &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 + 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 -- cgit v1.2.3 From 3cf5db1831e0533627e6a5b78dd6bf406ccfab3f Mon Sep 17 00:00:00 2001 From: ariel- Date: Fri, 2 Jun 2017 03:24:27 -0300 Subject: Core/Globals: add more AIName and MovementType checks to ObjectMgr - Ninja fix AI factories (restores prev behaviour of not selecting stuff with PERMIT_BASE_NO) Closes #19831 (cherry picked from commit d56a28afee19741c582ed8e16dbf8e30311f68ea) --- src/server/game/AI/CreatureAISelector.cpp | 21 ++++++++++++--------- src/server/game/Globals/ObjectMgr.cpp | 19 +++++++++++++++++++ src/server/game/World/World.cpp | 6 +++--- src/server/shared/Dynamic/FactoryHolder.h | 1 - src/server/shared/Dynamic/ObjectRegistry.h | 6 ++++++ 5 files changed, 40 insertions(+), 13 deletions(-) (limited to 'src/server/shared/Dynamic/ObjectRegistry.h') diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index 610a8e5b537..8e6c5cc2f4c 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -28,6 +28,13 @@ namespace FactorySelector { + template + inline int32 GetPermitFor(T const* obj, Value const& value) + { + Permissible const* const p = ASSERT_NOTNULL(dynamic_cast const*>(value.second.get())); + return p->Permit(obj); + } + template struct PermissibleOrderPred { @@ -37,10 +44,7 @@ namespace FactorySelector template bool operator()(Value const& left, Value const& right) const { - Permissible const* leftPermit = ASSERT_NOTNULL(dynamic_cast const*>(left.second.get())); - Permissible const* rightPermit = ASSERT_NOTNULL(dynamic_cast const*>(right.second.get())); - - return leftPermit->Permit(_obj) < rightPermit->Permit(_obj); + return GetPermitFor(_obj, left) < GetPermitFor(_obj, right); } private: @@ -52,9 +56,8 @@ namespace FactorySelector CreatureAICreator const* ai_factory = nullptr; // scriptname in db - if (!ai_factory) - if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature)) - return scriptedAI; + if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature)) + return scriptedAI; // AIname in db std::string const& aiName = creature->GetAIName(); @@ -66,7 +69,7 @@ namespace FactorySelector { CreatureAIRegistry::RegistryMapType const& items = sCreatureAIRegistry->GetRegisteredItems(); auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred(creature)); - if (itr != items.end()) + if (itr != items.end() && GetPermitFor(creature, *itr) >= 0) ai_factory = itr->second.get(); } @@ -104,7 +107,7 @@ namespace FactorySelector { GameObjectAIRegistry::RegistryMapType const& items = sGameObjectAIRegistry->GetRegisteredItems(); auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred(go)); - if (itr != items.end()) + if (itr != items.end() && GetPermitFor(go, *itr) >= 0) ai_factory = itr->second.get(); } diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index e38539429ae..c616ee11270 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -21,10 +21,12 @@ #include "AzeriteItem.h" #include "Chat.h" #include "Containers.h" +#include "CreatureAIFactory.h" #include "DatabaseEnv.h" #include "DB2Stores.h" #include "DisableMgr.h" #include "GameObject.h" +#include "GameObjectAIFactory.h" #include "GameTables.h" #include "GridDefines.h" #include "GossipDef.h" @@ -935,6 +937,12 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo) ok = true; } + if (!cInfo->AIName.empty() && !sCreatureAIRegistry->HasItem(cInfo->AIName)) + { + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has non-registered `AIName` '%s' set, removing", cInfo->Entry, cInfo->AIName.c_str()); + const_cast(cInfo)->AIName.clear(); + } + FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction); if (!factionTemplate) { @@ -2048,6 +2056,12 @@ void ObjectMgr::LoadCreatures() TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD " Entry: %u) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature is not in instance.", guid, data.id); } + if (data.movementType >= MAX_DB_MOTION_TYPE) + { + TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD " Entry: %u) with wrong movement generator type (%u), ignored and set to IDLE.", guid, data.id, data.movementType); + data.movementType = IDLE_MOTION_TYPE; + } + if (data.spawndist < 0.0f) { TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD " Entry: %u) with `spawndist`< 0, set to 0.", guid, data.id); @@ -7061,6 +7075,11 @@ void ObjectMgr::LoadGameObjectTemplate() got.ScriptId = GetScriptId(fields[44].GetString()); // Checks + if (!got.AIName.empty() && !sGameObjectAIRegistry->HasItem(got.AIName)) + { + TC_LOG_ERROR("sql.sql", "GameObject (Entry: %u) has non-registered `AIName` '%s' set, removing", got.entry, got.AIName.c_str()); + got.AIName.clear(); + } switch (got.type) { diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index fc45fa83113..7a64662c730 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1613,6 +1613,9 @@ void World::SetInitialWorldSettings() MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager(); mmmgr->InitializeThreadUnsafe(mapData); + ///- Initialize static helper structures + AIRegistry::Initialize(); + TC_LOG_INFO("server.loading", "Loading SpellInfo store..."); sSpellMgr->LoadSpellInfoStore(); @@ -2140,9 +2143,6 @@ void World::SetInitialWorldSettings() mail_timer_expires = ((DAY * IN_MILLISECONDS) / (m_timers[WUPDATE_AUCTIONS].GetInterval())); TC_LOG_INFO("server.loading", "Mail timer set to: " UI64FMTD ", mail return is called every " UI64FMTD " minutes", uint64(mail_timer), uint64(mail_timer_expires)); - ///- Initilize static helper structures - AIRegistry::Initialize(); - ///- Initialize MapManager TC_LOG_INFO("server.loading", "Starting Map System"); sMapMgr->Initialize(); diff --git a/src/server/shared/Dynamic/FactoryHolder.h b/src/server/shared/Dynamic/FactoryHolder.h index 32c4343e503..317d50ea9fc 100644 --- a/src/server/shared/Dynamic/FactoryHolder.h +++ b/src/server/shared/Dynamic/FactoryHolder.h @@ -32,7 +32,6 @@ class FactoryHolder explicit FactoryHolder(Key const& k) : _key(k) { } virtual ~FactoryHolder() { } - inline Key GetKey() const { return _key; } void RegisterSelf() { FactoryHolderRegistry::instance()->InsertItem(this, _key); } diff --git a/src/server/shared/Dynamic/ObjectRegistry.h b/src/server/shared/Dynamic/ObjectRegistry.h index 89ca33f15fa..973c34fda24 100644 --- a/src/server/shared/Dynamic/ObjectRegistry.h +++ b/src/server/shared/Dynamic/ObjectRegistry.h @@ -63,6 +63,12 @@ class ObjectRegistry final return true; } + /// Returns true if registry contains an item + bool HasItem(Key const& key) const + { + return (_registeredObjects.count(key) > 0); + } + /// Return the map of registered items RegistryMapType const& GetRegisteredItems() const { -- cgit v1.2.3