TrinityCore
UnitAI.h
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#ifndef TRINITY_UNITAI_H
19#define TRINITY_UNITAI_H
20
21#include "Errors.h"
22#include "ObjectGuid.h"
23#include "SharedDefines.h"
24#include "SpellDefines.h"
25#include "UnitAICommon.h"
26#include <unordered_map>
27
28#define CAST_AI(a, b) (dynamic_cast<a*>(b))
29#define ENSURE_AI(a,b) (EnsureAI<a>(b))
30
31template<class T, class U>
32T* EnsureAI(U* ai)
33{
34 T* cast_ai = dynamic_cast<T*>(ai);
35 ASSERT(cast_ai);
36 return cast_ai;
37}
38
39class Player;
40class Quest;
41class SpellInfo;
42class Unit;
43struct AISpellInfoType;
45enum Difficulty : uint8;
47enum SpellEffIndex : uint8;
48
50{
51 protected:
52 Unit* const me;
53 public:
54 explicit UnitAI(Unit* unit) : me(unit) { }
55 virtual ~UnitAI() { }
56
57 virtual bool CanAIAttack(Unit const* /*target*/) const { return true; }
58 virtual void AttackStart(Unit* victim);
59 virtual void UpdateAI(uint32 diff) = 0;
60
61 virtual void InitializeAI();
62
63 virtual void Reset() { }
64
65 // Called when unit's charm state changes with isNew = false
66 // Implementation should call me->ScheduleAIChange() if AI replacement is desired
67 // If this call is made, AI will be replaced on the next tick
68 // When replacement is made, OnCharmed is called with isNew = true
69 virtual void OnCharmed(bool isNew);
70
71 // Pass parameters between AI
72 virtual void DoAction(int32 /*param*/) { }
73 virtual uint32 GetData(uint32 /*id = 0*/) const { return 0; }
74 virtual void SetData(uint32 /*id*/, uint32 /*value*/) { }
75 virtual void SetGUID(ObjectGuid const& /*guid*/, int32 /*id*/ = 0) { }
76 virtual ObjectGuid GetGUID(int32 /*id*/ = 0) const { return ObjectGuid::Empty; }
77
78 // Select the best target (in <targetType> order) from the threat list that fulfill the following:
79 // - Not among the first <offset> entries in <targetType> order (or SelectTargetMethod::MaxThreat order,
80 // if <targetType> is SelectTargetMethod::Random).
81 // - Within at most <dist> yards (if dist > 0.0f)
82 // - At least -<dist> yards away (if dist < 0.0f)
83 // - Is a player (if playerOnly = true)
84 // - Not the current tank (if withTank = false)
85 // - Has aura with ID <aura> (if aura > 0)
86 // - Does not have aura with ID -<aura> (if aura < 0)
87 Unit* SelectTarget(SelectTargetMethod targetType, uint32 offset = 0, float dist = 0.0f, bool playerOnly = false, bool withTank = true, int32 aura = 0);
88
89 // Select the best target (in <targetType> order) satisfying <predicate> from the threat list.
90 // If <offset> is nonzero, the first <offset> entries in <targetType> order (or SelectTargetMethod::MaxThreat
91 // order, if <targetType> is SelectTargetMethod::Random) are skipped.
92 template<class PREDICATE>
93 Unit* SelectTarget(SelectTargetMethod targetType, uint32 offset, PREDICATE const& predicate)
94 {
95 std::list<Unit*> targetList;
96 SelectTargetList(targetList, std::numeric_limits<uint32>::max(), targetType, offset, predicate);
97
98 return FinalizeTargetSelection(targetList, targetType);
99 }
100
101 // Select the best (up to) <num> targets (in <targetType> order) from the threat list that fulfill the following:
102 // - Not among the first <offset> entries in <targetType> order (or SelectTargetMethod::MaxThreat order,
103 // if <targetType> is SelectTargetMethod::Random).
104 // - Within at most <dist> yards (if dist > 0.0f)
105 // - At least -<dist> yards away (if dist < 0.0f)
106 // - Is a player (if playerOnly = true)
107 // - Not the current tank (if withTank = false)
108 // - Has aura with ID <aura> (if aura > 0)
109 // - Does not have aura with ID -<aura> (if aura < 0)
110 // The resulting targets are stored in <targetList> (which is cleared first).
111 void SelectTargetList(std::list<Unit*>& targetList, uint32 num, SelectTargetMethod targetType, uint32 offset = 0, float dist = 0.0f, bool playerOnly = false, bool withTank = true, int32 aura = 0);
112
113 // Select the best (up to) <num> targets (in <targetType> order) satisfying <predicate> from the threat list and stores them in <targetList> (which is cleared first).
114 // If <offset> is nonzero, the first <offset> entries in <targetType> order (or SelectTargetMethod::MaxThreat
115 // order, if <targetType> is SelectTargetMethod::Random) are skipped.
116 template <class PREDICATE>
117 void SelectTargetList(std::list<Unit*>& targetList, uint32 num, SelectTargetMethod targetType, uint32 offset, PREDICATE const& predicate)
118 {
119 if (!PrepareTargetListSelection(targetList, targetType, offset))
120 return;
121
122 // then finally filter by predicate
123 targetList.remove_if([&predicate](Unit* target) { return !predicate(target); });
124
125 FinalizeTargetListSelection(targetList, num, targetType);
126 }
127
128 // Called when the unit enters combat
129 // (NOTE: Creature engage logic should NOT be here, but in JustEngagedWith, which happens once threat is established!)
130 virtual void JustEnteredCombat(Unit* /*who*/) { }
131
132 // Called when the unit leaves combat
133 virtual void JustExitedCombat() { }
134
135 // Called when the unit is about to be removed from the world (despawn, grid unload, corpse disappearing, player logging out etc.)
136 virtual void OnDespawn() { }
137
138 // Called at any Damage to any victim (before damage apply)
139 virtual void DamageDealt(Unit* /*victim*/, uint32& /*damage*/, DamageEffectType /*damageType*/) { }
140
141 // Called at any Damage from any attacker (before damage apply)
142 // Note: it for recalculation damage or special reaction at damage
143 virtual void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) { }
144
145 // Called when the creature receives heal
146 virtual void HealReceived(Unit* /*done_by*/, uint32& /*addhealth*/) { }
147
148 // Called when the unit heals
149 virtual void HealDone(Unit* /*done_to*/, uint32& /*addhealth*/) { }
150
153 virtual void SpellInterrupted(uint32 /*spellId*/, uint32 /*unTimeMs*/) { }
154
155 void AttackStartCaster(Unit* victim, float dist);
156
157 SpellCastResult DoCast(uint32 spellId);
158 SpellCastResult DoCast(Unit* victim, uint32 spellId, CastSpellExtraArgs const& args = {});
159 SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const& args = {}) { return DoCast(me, spellId, args); }
160 SpellCastResult DoCastVictim(uint32 spellId, CastSpellExtraArgs const& args = {});
161 SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const& args = {}) { return DoCast(nullptr, spellId, args); }
162
163 bool DoSpellAttackIfReady(uint32 spellId);
164
165 static std::unordered_map<std::pair<uint32, Difficulty>, AISpellInfoType> AISpellInfo;
166 static void FillAISpellInfo();
167
168 // Called when a game event starts or ends
169 virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) { }
170
171 virtual std::string GetDebugInfo() const;
172
173 private:
174 UnitAI(UnitAI const& right) = delete;
175 UnitAI& operator=(UnitAI const& right) = delete;
176
177 Unit* FinalizeTargetSelection(std::list<Unit*>& targetList, SelectTargetMethod targetType);
178 bool PrepareTargetListSelection(std::list<Unit*>& targetList, SelectTargetMethod targetType, uint32 offset);
179 void FinalizeTargetListSelection(std::list<Unit*>& targetList, uint32 num, SelectTargetMethod targetType);
180};
181
182#endif
Difficulty
Definition: DBCEnums.h:873
#define TC_GAME_API
Definition: Define.h:123
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
std::string GetDebugInfo()
Definition: Errors.cpp:157
#define ASSERT
Definition: Errors.h:68
MovementGeneratorType
SpellEffIndex
Definition: SharedDefines.h:29
SpellCastResult
SelectTargetMethod
Definition: UnitAICommon.h:40
T * EnsureAI(U *ai)
Definition: UnitAI.h:32
DamageEffectType
Definition: UnitDefines.h:131
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
Definition: UnitAI.h:50
virtual void HealReceived(Unit *, uint32 &)
Definition: UnitAI.h:146
virtual void SetData(uint32, uint32)
Definition: UnitAI.h:74
virtual void DoAction(int32)
Definition: UnitAI.h:72
virtual void JustEnteredCombat(Unit *)
Definition: UnitAI.h:130
virtual void SpellInterrupted(uint32, uint32)
Definition: UnitAI.h:153
virtual ~UnitAI()
Definition: UnitAI.h:55
virtual void Reset()
Definition: UnitAI.h:63
SpellCastResult DoCastSelf(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:159
UnitAI(Unit *unit)
Definition: UnitAI.h:54
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset, PREDICATE const &predicate)
Definition: UnitAI.h:93
virtual bool CanAIAttack(Unit const *) const
Definition: UnitAI.h:57
virtual uint32 GetData(uint32) const
Definition: UnitAI.h:73
void SelectTargetList(std::list< Unit * > &targetList, uint32 num, SelectTargetMethod targetType, uint32 offset, PREDICATE const &predicate)
Definition: UnitAI.h:117
static std::unordered_map< std::pair< uint32, Difficulty >, AISpellInfoType > AISpellInfo
Definition: UnitAI.h:165
UnitAI & operator=(UnitAI const &right)=delete
virtual ObjectGuid GetGUID(int32=0) const
Definition: UnitAI.h:76
virtual void DamageTaken(Unit *, uint32 &, DamageEffectType, SpellInfo const *)
Definition: UnitAI.h:143
virtual void OnGameEvent(bool, uint16)
Definition: UnitAI.h:169
virtual void OnDespawn()
Definition: UnitAI.h:136
virtual void JustExitedCombat()
Definition: UnitAI.h:133
Unit *const me
Definition: UnitAI.h:52
virtual void HealDone(Unit *, uint32 &)
Definition: UnitAI.h:149
virtual void DamageDealt(Unit *, uint32 &, DamageEffectType)
Definition: UnitAI.h:139
virtual void UpdateAI(uint32 diff)=0
UnitAI(UnitAI const &right)=delete
virtual void SetGUID(ObjectGuid const &, int32=0)
Definition: UnitAI.h:75
SpellCastResult DoCastAOE(uint32 spellId, CastSpellExtraArgs const &args={})
Definition: UnitAI.h:161
Definition: Unit.h:627