Skip to content

Commit

Permalink
Core/AI: restore old check forcing PetAI on Pets using SmartAI
Browse files Browse the repository at this point in the history
includes more template love

Closes #19837
  • Loading branch information
ariel- committed Jun 2, 2017
1 parent 67115ed commit 9c24ec5
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 43 deletions.
2 changes: 1 addition & 1 deletion src/server/game/AI/CoreAI/CombatAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
3 changes: 0 additions & 3 deletions src/server/game/AI/CoreAI/PetAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
69 changes: 30 additions & 39 deletions src/server/game/AI/CreatureAISelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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);
}
}

0 comments on commit 9c24ec5

Please sign in to comment.