aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AI/CreatureAISelector.cpp21
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp19
-rw-r--r--src/server/game/World/World.cpp6
-rw-r--r--src/server/shared/Dynamic/FactoryHolder.h1
-rw-r--r--src/server/shared/Dynamic/ObjectRegistry.h6
5 files changed, 40 insertions, 13 deletions
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 <class T, class Value>
+ inline int32 GetPermitFor(T const* obj, Value const& value)
+ {
+ Permissible<T> const* const p = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(value.second.get()));
+ return p->Permit(obj);
+ }
+
template <class T>
struct PermissibleOrderPred
{
@@ -37,10 +44,7 @@ namespace FactorySelector
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);
+ 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>(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<GameObject>(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<CreatureTemplate*>(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
{