aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp3
-rw-r--r--src/server/game/AI/CreatureAISelector.cpp69
3 files changed, 31 insertions, 43 deletions
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp
index ec60d790fee..160b58a9742 100644
--- a/src/server/game/AI/CoreAI/CombatAI.cpp
+++ b/src/server/game/AI/CoreAI/CombatAI.cpp
@@ -36,7 +36,7 @@ int32 AggressorAI::Permissible(Creature const* creature)
{
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
if (!creature->IsCivilian() && !creature->IsNeutralToAll())
- return PERMIT_BASE_PROACTIVE;
+ return PERMIT_BASE_REACTIVE;
return PERMIT_BASE_NO;
}
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index aa0dbfb76e3..c16e1f945eb 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -33,9 +33,6 @@
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)
diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp
index 8e6c5cc2f4c..b7181a35f76 100644
--- a/src/server/game/AI/CreatureAISelector.cpp
+++ b/src/server/game/AI/CreatureAISelector.cpp
@@ -51,32 +51,42 @@ namespace FactorySelector
T const* const _obj;
};
- CreatureAI* SelectAI(Creature* creature)
+ template <class AI, class T>
+ inline FactoryHolder<AI, T> const* SelectFactory(T* obj)
{
- CreatureAICreator const* ai_factory = nullptr;
+ static_assert(std::is_same<AI, CreatureAI>::value || std::is_same<AI, GameObjectAI>::value, "Invalid template parameter");
+ static_assert(std::is_same<AI, CreatureAI>::value == std::is_same<T, Creature>::value, "Incompatible AI for type");
+ static_assert(std::is_same<AI, GameObjectAI>::value == std::is_same<T, GameObject>::value, "Incompatible AI for type");
- // scriptname in db
- if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
- return scriptedAI;
+ using AIRegistry = typename FactoryHolder<AI, T>::FactoryHolderRegistry;
- // AIname in db
- std::string const& aiName = creature->GetAIName();
- if (!ai_factory && !aiName.empty())
- ai_factory = sCreatureAIRegistry->GetRegistryItem(aiName);
+ // AIName in db
+ std::string const& aiName = obj->GetAIName();
+ if (!aiName.empty())
+ return AIRegistry::instance()->GetRegistryItem(aiName);
// select by permit check
- if (!ai_factory)
- {
- CreatureAIRegistry::RegistryMapType const& items = sCreatureAIRegistry->GetRegisteredItems();
- auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<Creature>(creature));
- if (itr != items.end() && GetPermitFor(creature, *itr) >= 0)
- ai_factory = itr->second.get();
- }
+ typename AIRegistry::RegistryMapType const& items = AIRegistry::instance()->GetRegisteredItems();
+ auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<T>(obj));
+ if (itr != items.end() && GetPermitFor(obj, *itr) >= 0)
+ return itr->second.get();
+
+ // should _never_ happen, Null AI types defined as PERMIT_BASE_IDLE, it must've been found
+ ABORT();
+ return nullptr;
+ }
+
+ CreatureAI* SelectAI(Creature* creature)
+ {
+ // special pet case, if a tamed creature uses AIName (example SmartAI) we need to override it
+ if (creature->IsPet())
+ return ASSERT_NOTNULL(sCreatureAIRegistry->GetRegistryItem("PetAI"))->Create(creature);
- if (!ai_factory)
- ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
+ // scriptname in db
+ if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
+ return scriptedAI;
- return ASSERT_NOTNULL(ai_factory)->Create(creature);
+ return SelectFactory<CreatureAI>(creature)->Create(creature);
}
MovementGenerator* SelectMovementGenerator(Unit* unit)
@@ -91,29 +101,10 @@ namespace FactorySelector
GameObjectAI* SelectGameObjectAI(GameObject* go)
{
- GameObjectAICreator const* ai_factory = nullptr;
-
// scriptname in db
if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
return scriptedAI;
- // AIname in db
- std::string const& aiName = go->GetAIName();
- if (!ai_factory && !aiName.empty())
- ai_factory = sGameObjectAIRegistry->GetRegistryItem(aiName);
-
- // 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() && GetPermitFor(go, *itr) >= 0)
- ai_factory = itr->second.get();
- }
-
- if (!ai_factory)
- ai_factory = sGameObjectAIRegistry->GetRegistryItem("NullGameObjectAI");
-
- return ASSERT_NOTNULL(ai_factory)->Create(go);
+ return SelectFactory<GameObjectAI>(go)->Create(go);
}
}