TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
UnitAI.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
3  * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 2 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef TRINITY_UNITAI_H
20 #define TRINITY_UNITAI_H
21 
22 #include "Define.h"
23 #include "Unit.h"
24 #include "Containers.h"
25 #include "EventMap.h"
26 #include <list>
27 
28 class Player;
29 class Quest;
30 struct AISpellInfoType;
31 
32 //Selection method used by SelectTarget
34 {
35  SELECT_TARGET_RANDOM = 0, //Just selects a random target
36  SELECT_TARGET_TOPAGGRO, //Selects targes from top aggro to bottom
37  SELECT_TARGET_BOTTOMAGGRO, //Selects targets from bottom aggro to top
40 };
41 
42 // default predicate function to select target based on distance, player and/or aura criteria
43 struct TC_GAME_API DefaultTargetSelector : public std::unary_function<Unit*, bool>
44 {
45  const Unit* me;
46  float m_dist;
49 
50  // unit: the reference unit
51  // dist: if 0: ignored, if > 0: maximum distance to the reference unit, if < 0: minimum distance to the reference unit
52  // playerOnly: self explaining
53  // aura: if 0: ignored, if > 0: the target shall have the aura, if < 0, the target shall NOT have the aura
54  DefaultTargetSelector(Unit const* unit, float dist, bool playerOnly, int32 aura) : me(unit), m_dist(dist), m_playerOnly(playerOnly), m_aura(aura) { }
55 
56  bool operator()(Unit const* target) const
57  {
58  if (!me)
59  return false;
60 
61  if (!target)
62  return false;
63 
64  if (m_playerOnly && (target->GetTypeId() != TYPEID_PLAYER))
65  return false;
66 
67  if (m_dist > 0.0f && !me->IsWithinCombatRange(target, m_dist))
68  return false;
69 
70  if (m_dist < 0.0f && me->IsWithinCombatRange(target, -m_dist))
71  return false;
72 
73  if (m_aura)
74  {
75  if (m_aura > 0)
76  {
77  if (!target->HasAura(m_aura))
78  return false;
79  }
80  else
81  {
82  if (target->HasAura(-m_aura))
83  return false;
84  }
85  }
86 
87  return true;
88  }
89 };
90 
91 // Target selector for spell casts checking range, auras and attributes
93 struct TC_GAME_API SpellTargetSelector : public std::unary_function<Unit*, bool>
94 {
95  public:
96  SpellTargetSelector(Unit* caster, uint32 spellId);
97  bool operator()(Unit const* target) const;
98 
99  private:
100  Unit const* _caster;
102 };
103 
104 // Very simple target selector, will just skip main target
105 // NOTE: When passing to UnitAI::SelectTarget remember to use 0 as position for random selection
106 // because tank will not be in the temporary list
107 struct TC_GAME_API NonTankTargetSelector : public std::unary_function<Unit*, bool>
108 {
109  public:
110  NonTankTargetSelector(Creature* source, bool playerOnly = true) : _source(source), _playerOnly(playerOnly) { }
111  bool operator()(Unit const* target) const;
112 
113  private:
116 };
117 
119 {
120  protected:
121  Unit* const me;
122  public:
123  explicit UnitAI(Unit* unit) : me(unit) { }
124  virtual ~UnitAI() { }
125 
126  virtual bool CanAIAttack(Unit const* /*target*/) const { return true; }
127  virtual void AttackStart(Unit* /*target*/);
128  virtual void UpdateAI(uint32 diff) = 0;
129 
130  virtual void InitializeAI() { if (!me->isDead()) Reset(); }
131 
132  virtual void Reset() { }
133 
134  // Called when unit is charmed
135  virtual void OnCharmed(bool apply) = 0;
136 
137  // Pass parameters between AI
138  virtual void DoAction(int32 /*param*/) { }
139  virtual uint32 GetData(uint32 /*id = 0*/) const { return 0; }
140  virtual void SetData(uint32 /*id*/, uint32 /*value*/) { }
141  virtual void SetGUID(ObjectGuid /*guid*/, int32 /*id*/ = 0) { }
142  virtual ObjectGuid GetGUID(int32 /*id*/ = 0) const { return ObjectGuid::Empty; }
143 
144  Unit* SelectTarget(SelectAggroTarget targetType, uint32 position = 0, float dist = 0.0f, bool playerOnly = false, int32 aura = 0);
145  // Select the targets satisfying the predicate.
146  // predicate shall extend std::unary_function<Unit*, bool>
147  template<class PREDICATE> Unit* SelectTarget(SelectAggroTarget targetType, uint32 position, PREDICATE const& predicate)
148  {
149  ThreatContainer::StorageType const& threatlist = me->getThreatManager().getThreatList();
150  if (position >= threatlist.size())
151  return NULL;
152 
153  std::list<Unit*> targetList;
154  for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
155  if (predicate((*itr)->getTarget()))
156  targetList.push_back((*itr)->getTarget());
157 
158  if (position >= targetList.size())
159  return NULL;
160 
161  if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
162  targetList.sort(Trinity::ObjectDistanceOrderPred(me));
163 
164  switch (targetType)
165  {
168  {
169  std::list<Unit*>::iterator itr = targetList.begin();
170  std::advance(itr, position);
171  return *itr;
172  }
175  {
176  std::list<Unit*>::reverse_iterator ritr = targetList.rbegin();
177  std::advance(ritr, position);
178  return *ritr;
179  }
181  {
182  std::list<Unit*>::iterator itr = targetList.begin();
183  std::advance(itr, urand(position, uint32(targetList.size() - 1)));
184  return *itr;
185  }
186  default:
187  break;
188  }
189 
190  return NULL;
191  }
192 
193  void SelectTargetList(std::list<Unit*>& targetList, uint32 num, SelectAggroTarget targetType, float dist = 0.0f, bool playerOnly = false, int32 aura = 0);
194 
195  // Select the targets satifying the predicate.
196  // predicate shall extend std::unary_function<Unit*, bool>
197  template <class PREDICATE> void SelectTargetList(std::list<Unit*>& targetList, PREDICATE const& predicate, uint32 maxTargets, SelectAggroTarget targetType)
198  {
199  ThreatContainer::StorageType const& threatlist = me->getThreatManager().getThreatList();
200  if (threatlist.empty())
201  return;
202 
203  for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
204  if (predicate((*itr)->getTarget()))
205  targetList.push_back((*itr)->getTarget());
206 
207  if (targetList.size() < maxTargets)
208  return;
209 
210  if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST)
211  targetList.sort(Trinity::ObjectDistanceOrderPred(me));
212 
213  if (targetType == SELECT_TARGET_FARTHEST || targetType == SELECT_TARGET_BOTTOMAGGRO)
214  targetList.reverse();
215 
216  if (targetType == SELECT_TARGET_RANDOM)
217  Trinity::Containers::RandomResizeList(targetList, maxTargets);
218  else
219  targetList.resize(maxTargets);
220  }
221 
222  // Called at any Damage to any victim (before damage apply)
223  virtual void DamageDealt(Unit* /*victim*/, uint32& /*damage*/, DamageEffectType /*damageType*/) { }
224 
225  // Called at any Damage from any attacker (before damage apply)
226  // Note: it for recalculation damage or special reaction at damage
227  // for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
228  virtual void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { }
229 
230  // Called when the creature receives heal
231  virtual void HealReceived(Unit* /*done_by*/, uint32& /*addhealth*/) { }
232 
233  // Called when the unit heals
234  virtual void HealDone(Unit* /*done_to*/, uint32& /*addhealth*/) { }
235 
238  virtual void SpellInterrupted(uint32 /*spellId*/, uint32 /*unTimeMs*/) { }
239 
240  void AttackStartCaster(Unit* victim, float dist);
241 
242  void DoCast(uint32 spellId);
243  void DoCast(Unit* victim, uint32 spellId, bool triggered = false);
244  void DoCastVictim(uint32 spellId, bool triggered = false);
245  void DoCastAOE(uint32 spellId, bool triggered = false);
246 
247  void DoMeleeAttackIfReady();
248  bool DoSpellAttackIfReady(uint32 spellId);
249 
251  static void FillAISpellInfo();
252 
253  virtual void sGossipHello(Player* /*player*/) { }
254  virtual void sGossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) { }
255  virtual void sGossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/) { }
256  virtual void sQuestAccept(Player* /*player*/, Quest const* /*quest*/) { }
257  virtual void sQuestSelect(Player* /*player*/, Quest const* /*quest*/) { }
258  virtual void sQuestReward(Player* /*player*/, Quest const* /*quest*/, uint32 /*opt*/) { }
259  virtual bool sOnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/) { return false; }
260  virtual void sOnGameEvent(bool /*start*/, uint16 /*eventId*/) { }
261 
262  private:
263  UnitAI(UnitAI const& right) = delete;
264  UnitAI& operator=(UnitAI const& right) = delete;
265 };
266 
268 {
269  protected:
270  Player* const me;
271  public:
272  explicit PlayerAI(Player* player) : UnitAI((Unit*)player), me(player) { }
273 
274  void OnCharmed(bool apply) override;
275 };
276 
278 {
279  public:
280  void UpdateAI(uint32 diff) override;
281  SimpleCharmedAI(Player* player): PlayerAI(player) { }
282 };
283 
284 #endif
virtual void SetData(uint32, uint32)
Definition: UnitAI.h:140
bool IsWithinCombatRange(const Unit *obj, float dist2compare) const
Definition: Unit.cpp:492
static AISpellInfoType * AISpellInfo
Definition: UnitAI.h:250
virtual void sGossipSelect(Player *, uint32, uint32)
Definition: UnitAI.h:254
virtual ObjectGuid GetGUID(int32=0) const
Definition: UnitAI.h:142
virtual void sQuestReward(Player *, Quest const *, uint32)
Definition: UnitAI.h:258
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4240
DefaultTargetSelector(Unit const *unit, float dist, bool playerOnly, int32 aura)
Definition: UnitAI.h:54
SimpleCharmedAI(Player *player)
Definition: UnitAI.h:281
virtual ~UnitAI()
Definition: UnitAI.h:124
Definition: UnitAI.h:107
Definition: UnitAI.h:36
static ObjectGuid const Empty
Definition: ObjectGuid.h:196
virtual void HealDone(Unit *, uint32 &)
Definition: UnitAI.h:234
virtual void sOnGameEvent(bool, uint16)
Definition: UnitAI.h:260
Player *const me
Definition: UnitAI.h:270
Definition: QuestDef.h:279
bool operator()(Unit const *target) const
Definition: UnitAI.h:56
Definition: SpellInfo.h:326
NonTankTargetSelector(Creature *source, bool playerOnly=true)
Definition: UnitAI.h:110
const Unit * me
Definition: UnitAI.h:45
Unit const * _caster
Definition: UnitAI.h:100
void RandomResizeList(std::list< T > &list, uint32 size)
Definition: Containers.h:34
arena_t NULL
Definition: jemalloc_internal.h:624
ThreatContainer::StorageType const & getThreatList() const
Definition: ThreatManager.h:263
Definition: Object.h:668
Unit * SelectTarget(SelectAggroTarget targetType, uint32 position, PREDICATE const &predicate)
Definition: UnitAI.h:147
virtual void UpdateAI(uint32 diff)=0
Definition: Creature.h:467
Unit *const me
Definition: UnitAI.h:121
void apply(T *val)
Definition: ByteConverter.h:41
bool _playerOnly
Definition: UnitAI.h:115
virtual void SetGUID(ObjectGuid, int32=0)
Definition: UnitAI.h:141
virtual void DamageTaken(Unit *, uint32 &)
Definition: UnitAI.h:228
virtual bool CanAIAttack(Unit const *) const
Definition: UnitAI.h:126
virtual void sGossipSelectCode(Player *, uint32, uint32, char const *)
Definition: UnitAI.h:255
void advance(octet_iterator &it, distance_type n, octet_iterator end)
Definition: checked.h:190
Definition: UnitAI.h:37
UnitAI(Unit *unit)
Definition: UnitAI.h:123
virtual void InitializeAI()
Definition: UnitAI.h:130
TypeID GetTypeId() const
Definition: Object.h:113
float m_dist
Definition: UnitAI.h:46
virtual bool sOnDummyEffect(Unit *, uint32, SpellEffIndex)
Definition: UnitAI.h:259
int32 m_aura
Definition: UnitAI.h:48
Definition: UnitAI.h:35
SelectAggroTarget
Definition: UnitAI.h:33
virtual void sQuestAccept(Player *, Quest const *)
Definition: UnitAI.h:256
DamageEffectType
Definition: Unit.h:660
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:45
Definition: UnitAI.h:267
Definition: UnitAI.h:93
SpellEffIndex
Definition: SharedDefines.h:26
Vector2int16 & operator=(const Any &a)
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
uint16_t uint16
Definition: Define.h:151
virtual void DoAction(int32)
Definition: UnitAI.h:138
Definition: UnitAI.h:43
bool isDead() const
Definition: Unit.h:1694
Definition: UnitAI.h:277
Definition: ObjectGuid.h:33
std::list< HostileReference * > StorageType
Definition: ThreatManager.h:149
#define TC_GAME_API
Definition: Define.h:134
virtual void DamageDealt(Unit *, uint32 &, DamageEffectType)
Definition: UnitAI.h:223
Definition: UnitAI.h:39
ThreatManager & getThreatManager()
Definition: Unit.h:1998
SpellInfo const * _spellInfo
Definition: UnitAI.h:101
Definition: ObjectGuid.h:189
uint32_t uint32
Definition: g3dmath.h:168
virtual void HealReceived(Unit *, uint32 &)
Definition: UnitAI.h:231
virtual uint32 GetData(uint32) const
Definition: UnitAI.h:139
virtual void OnCharmed(bool apply)=0
bool m_playerOnly
Definition: UnitAI.h:47
virtual void Reset()
Definition: UnitAI.h:132
Definition: Unit.h:1305
Creature const * _source
Definition: UnitAI.h:114
void SelectTargetList(std::list< Unit * > &targetList, PREDICATE const &predicate, uint32 maxTargets, SelectAggroTarget targetType)
Definition: UnitAI.h:197
PlayerAI(Player *player)
Definition: UnitAI.h:272
virtual void SpellInterrupted(uint32, uint32)
Definition: UnitAI.h:238
Definition: UnitAI.h:38
virtual void sQuestSelect(Player *, Quest const *)
Definition: UnitAI.h:257
Definition: CreatureAIImpl.h:55
Definition: UnitAI.h:118
virtual void sGossipHello(Player *)
Definition: UnitAI.h:253