diff options
| -rw-r--r-- | src/server/game/AI/CoreAI/CombatAI.cpp | 2 | ||||
| -rw-r--r-- | src/server/game/AI/CoreAI/PetAI.cpp | 3 | ||||
| -rw-r--r-- | src/server/game/AI/CreatureAISelector.cpp | 69 |
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 e10592426d1..86858de04dd 100644 --- a/src/server/game/AI/CoreAI/CombatAI.cpp +++ b/src/server/game/AI/CoreAI/CombatAI.cpp @@ -31,7 +31,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 ec908f9db4d..c242f4baf54 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -31,9 +31,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 30b606b49c7..8da0eadfc15 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -52,32 +52,42 @@ namespace FactorySelector T const* const _obj; }; + template <class AI, class T> + inline FactoryHolder<AI, T> const* SelectFactory(T* obj) + { + 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"); + + using AIRegistry = typename FactoryHolder<AI, T>::FactoryHolderRegistry; + + // AIName in db + std::string const& aiName = obj->GetAIName(); + if (!aiName.empty()) + return AIRegistry::instance()->GetRegistryItem(aiName); + + // select by permit check + 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) { - CreatureAICreator const* ai_factory = nullptr; + // 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); // scriptname in db if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature)) return scriptedAI; - // AIname in db - std::string const& aiName = creature->GetAIName(); - if (!ai_factory && !aiName.empty()) - ai_factory = sCreatureAIRegistry->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(); - } - - if (!ai_factory) - ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI"); - - return ASSERT_NOTNULL(ai_factory)->Create(creature); + return SelectFactory<CreatureAI>(creature)->Create(creature); } MovementGenerator* SelectMovementGenerator(Unit* unit) @@ -92,29 +102,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); } } |
