TrinityCore
Loading...
Searching...
No Matches
CreatureAISelector.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "AIException.h"
19#include "Creature.h"
20#include "CreatureAISelector.h"
21#include "CreatureAIFactory.h"
22
23#include "MovementGenerator.h"
24
25#include "GameObject.h"
26#include "GameObjectAIFactory.h"
27
28#include "Log.h"
29#include "ScriptMgr.h"
30
32{
33 template <class T, class Value>
34 inline int32 GetPermitFor(T const* obj, Value const& value)
35 {
36 Permissible<T> const* const p = ASSERT_NOTNULL(dynamic_cast<Permissible<T> const*>(value.second.get()));
37 return p->Permit(obj);
38 }
39
40 template <class T>
42 {
43 public:
44 PermissibleOrderPred(T const* obj) : _obj(obj) { }
45
46 template <class Value>
47 bool operator()(Value const& left, Value const& right) const
48 {
49 return GetPermitFor(_obj, left) < GetPermitFor(_obj, right);
50 }
51
52 private:
53 T const* const _obj;
54 };
55
56 template <class AI, class T>
57 inline FactoryHolder<AI, T> const* SelectFactory(T* obj)
58 {
59 static_assert(std::is_same<AI, CreatureAI>::value || std::is_same<AI, GameObjectAI>::value, "Invalid template parameter");
60 static_assert(std::is_same<AI, CreatureAI>::value == std::is_same<T, Creature>::value, "Incompatible AI for type");
61 static_assert(std::is_same<AI, GameObjectAI>::value == std::is_same<T, GameObject>::value, "Incompatible AI for type");
62
64
65 // AIName in db
66 std::string const& aiName = obj->GetAIName();
67 if (!aiName.empty())
68 return AIRegistry::instance()->GetRegistryItem(aiName);
69
70 // select by permit check
71 typename AIRegistry::RegistryMapType const& items = AIRegistry::instance()->GetRegisteredItems();
72 auto itr = std::max_element(items.begin(), items.end(), PermissibleOrderPred<T>(obj));
73 if (itr != items.end() && GetPermitFor(obj, *itr) >= 0)
74 return itr->second.get();
75
76 // should _never_ happen, Null AI types defined as PERMIT_BASE_IDLE, it must've been found
77 ABORT();
78 return nullptr;
79 }
80
82 {
83 // special pet case, if a tamed creature uses AIName (example SmartAI) we need to override it
84 if (creature->IsPet())
85 return ASSERT_NOTNULL(sCreatureAIRegistry->GetRegistryItem("PetAI"))->Create(creature);
86
87 // scriptname in db
88 try
89 {
90 if (CreatureAI* scriptedAI = sScriptMgr->GetCreatureAI(creature))
91 return scriptedAI;
92 }
93 catch (InvalidAIException const& e)
94 {
95 TC_LOG_ERROR("entities.unit", "Exception trying to assign script '{}' to Creature (Entry: {}), this Creature will have a default AI. Exception message: {}",
96 creature->GetScriptName(), creature->GetEntry(), e.what());
97 }
98
99 return SelectFactory<CreatureAI>(creature)->Create(creature);
100 }
101
103 {
105 if (Creature* creature = unit->ToCreature())
106 if (!creature->GetCharmerOrSelfPlayer())
107 type = creature->GetDefaultMovementType();
108
109 MovementGeneratorCreator const* mv_factory = sMovementGeneratorRegistry->GetRegistryItem(type);
110 return ASSERT_NOTNULL(mv_factory)->Create(unit);
111 }
112
114 {
115 // scriptname in db
116 if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
117 return scriptedAI;
118
119 return SelectFactory<GameObjectAI>(go)->Create(go);
120 }
121}
#define sCreatureAIRegistry
int32_t int32
Definition Define.h:129
#define ABORT
Definition Errors.h:74
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:84
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
MovementGeneratorType
#define sMovementGeneratorRegistry
#define sScriptMgr
Definition ScriptMgr.h:1168
std::string GetScriptName() const
virtual T * Create(O *object=nullptr) const =0
Abstract Factory create method.
char const * what() const noexcept override
Definition AIException.h:29
T const * GetRegistryItem(Key const &key) const
Returns a registry item.
static Creature * ToCreature(Object *o)
Definition Object.h:186
uint32 GetEntry() const
Definition Object.h:81
virtual int32 Permit(T const *) const =0
Definition Unit.h:769
virtual MovementGeneratorType GetDefaultMovementType() const
Definition Unit.cpp:10307
bool IsPet() const
Definition Unit.h:884
MovementGenerator * SelectMovementGenerator(Unit *unit)
CreatureAI * SelectAI(Creature *creature)
GameObjectAI * SelectGameObjectAI(GameObject *go)
int32 GetPermitFor(T const *obj, Value const &value)
FactoryHolder< AI, T > const * SelectFactory(T *obj)
bool operator()(Value const &left, Value const &right) const