TrinityCore
ScriptedCreature.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_SCRIPTEDCREATURE_H
19#define TRINITY_SCRIPTEDCREATURE_H
20
21#include "CreatureAI.h"
22#include "Creature.h" // convenience include for scripts, all uses of ScriptedCreature also need Creature (except ScriptedCreature itself doesn't need Creature)
23#include "DBCEnums.h"
24#include "EventMap.h"
25#include "TaskScheduler.h"
26
27class InstanceScript;
29enum SelectEffect : uint8;
30
32{
33public:
35 typedef StorageType::iterator iterator;
36 typedef StorageType::const_iterator const_iterator;
37 typedef StorageType::size_type size_type;
38 typedef StorageType::value_type value_type;
39
40 explicit SummonList(Creature* creature) : _me(creature) { }
41
42 // And here we see a problem of original inheritance approach. People started
43 // to exploit presence of std::list members, so I have to provide wrappers
44
46 {
47 return _storage.begin();
48 }
49
51 {
52 return _storage.begin();
53 }
54
56 {
57 return _storage.end();
58 }
59
61 {
62 return _storage.end();
63 }
64
66 {
67 return _storage.erase(i);
68 }
69
70 bool empty() const
71 {
72 return _storage.empty();
73 }
74
76 {
77 return _storage.size();
78 }
79
80 // Clear the underlying storage. This does NOT despawn the creatures - use DespawnAll for that!
81 void clear()
82 {
83 _storage.clear();
84 }
85
86 void Summon(Creature const* summon);
87 void Despawn(Creature const* summon);
88 void DespawnEntry(uint32 entry);
89 void DespawnAll();
90
91 template <typename T>
92 void DespawnIf(T const& predicate)
93 {
94 _storage.remove_if(predicate);
95 }
96
97 template <class Predicate>
98 void DoAction(int32 info, Predicate&& predicate, uint16 max = 0)
99 {
100 // We need to use a copy of SummonList here, otherwise original SummonList would be modified
101 StorageType listCopy;
102 std::copy_if(std::begin(_storage), std::end(_storage), std::inserter(listCopy, std::end(listCopy)), predicate);
103 DoActionImpl(info, listCopy, max);
104 }
105
106 void DoZoneInCombat(uint32 entry = 0);
107 void RemoveNotExisting();
108 bool HasEntry(uint32 entry) const;
109
110private:
111 void DoActionImpl(int32 action, StorageType& summons, uint16 max);
112
115};
116
118{
119 public:
120 EntryCheckPredicate(uint32 entry) : _entry(entry) { }
121 bool operator()(ObjectGuid const& guid) const { return guid.GetEntry() == _entry; }
122
123 private:
125};
126
128{
129 public:
130 bool operator()(ObjectGuid const&) const { return true; }
131};
132
134{
135 public:
136 explicit ScriptedAI(Creature* creature);
137 explicit ScriptedAI(Creature* creature, uint32 scriptId);
138 virtual ~ScriptedAI() { }
139
140 // *************
141 // CreatureAI Functions
142 // *************
143
144 void AttackStartNoMove(Unit* target);
145
146 // Called at World update tick
147 virtual void UpdateAI(uint32 diff) override;
148
149 // *************
150 // Variables
151 // *************
152
153 // For fleeing
155
156 // *************
157 // Pure virtual functions
158 // *************
159
160 // Called before JustEngagedWith even before the creature is in combat.
161 void AttackStart(Unit* /*target*/) override;
162
163 // *************
164 // AI Helper Functions
165 // *************
166
167 // Start movement toward victim
168 void DoStartMovement(Unit* target, float distance = 0.0f, float angle = 0.0f);
169
170 // Start no movement on victim
171 void DoStartNoMovement(Unit* target);
172
173 // Stop attack of current victim
174 void DoStopAttack();
175
176 // Cast spell by spell info
177 void DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool triggered = false);
178
179 // Plays a sound to all nearby players
180 void DoPlaySoundToSet(WorldObject* source, uint32 soundId);
181
182 // Add specified amount of threat directly to victim (ignores redirection effects) - also puts victim in combat and engages them if necessary
183 void AddThreat(Unit* victim, float amount, Unit* who = nullptr);
184 // Adds/removes the specified percentage from the specified victim's threat (to who, or me if not specified)
185 void ModifyThreatByPercent(Unit* victim, int32 pct, Unit* who = nullptr);
186 // Resets the victim's threat level to who (or me if not specified) to zero
187 void ResetThreat(Unit* victim, Unit* who = nullptr);
188 // Resets the specified unit's threat list (me if not specified) - does not delete entries, just sets their threat to zero
189 void ResetThreatList(Unit* who = nullptr);
190 // Returns the threat level of victim towards who (or me if not specified)
191 float GetThreat(Unit const* victim, Unit const* who = nullptr);
192 // Stops combat, ignoring restrictions, for the given creature
193 void ForceCombatStop(Creature* who, bool reset = true);
194 // Stops combat, ignoring restrictions, for the found creatures
195 void ForceCombatStopForCreatureEntry(uint32 entry, float maxSearchRange = 250.0f, bool samePhase = true, bool reset = true);
196 // Stops combat, ignoring restrictions, for the found creatures
197 void ForceCombatStopForCreatureEntry(std::vector<uint32> creatureEntries, float maxSearchRange = 250.0f, bool samePhase = true, bool reset = true);
198
199 void DoTeleportTo(float x, float y, float z, uint32 time = 0);
200 void DoTeleportTo(float const pos[4]);
201
202 // Teleports a player without dropping threat (only teleports to same map)
203 void DoTeleportPlayer(Unit* unit, float x, float y, float z, float o);
204 void DoTeleportAll(float x, float y, float z, float o);
205
206 // Returns friendly unit with the most amount of hp missing from max hp
207 Unit* DoSelectLowestHpFriendly(float range, uint32 minHPDiff = 1);
208
209 // Returns friendly unit with hp pct below specified and with specified entry
210 Unit* DoSelectBelowHpPctFriendlyWithEntry(uint32 entry, float range, uint8 hpPct = 1, bool excludeSelf = true);
211
212 // Returns a list of friendly CC'd units within range
213 std::list<Creature*> DoFindFriendlyCC(float range);
214
215 // Returns a list of all friendly units missing a specific buff within range
216 std::list<Creature*> DoFindFriendlyMissingBuff(float range, uint32 spellId);
217
218 // Return a player with at least minimumRange from me
219 Player* GetPlayerAtMinimumRange(float minRange);
220
221 // Spawns a creature relative to me
222 Creature* DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, Milliseconds despawntime);
223
224 bool HealthBelowPct(uint32 pct) const;
225 bool HealthAbovePct(uint32 pct) const;
226
227 // Returns spells that meet the specified criteria from the creatures spell list
228 SpellInfo const* SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect);
229
230 void SetEquipmentSlots(bool loadDefault, int32 mainHand = EQUIP_NO_CHANGE, int32 offHand = EQUIP_NO_CHANGE, int32 ranged = EQUIP_NO_CHANGE);
231
232 // Used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims
233 // NOTE: If you use SetCombatMovement while the creature is in combat, it will do NOTHING - This only affects AttackStart
234 // You should make the necessary to make it happen so.
235 // Remember that if you modified _isCombatMovementAllowed (e.g: using SetCombatMovement) it will not be reset at Reset().
236 // It will keep the last value you set.
237 void SetCombatMovement(bool allowMovement);
238 bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; }
239
240 bool IsLFR() const;
241 bool IsNormal() const;
242 bool IsHeroic() const;
243 bool IsMythic() const;
244 bool IsMythicPlus() const;
245 bool IsHeroicOrHigher() const;
246 bool IsTimewalking() const;
247
248 // return the dungeon or raid difficulty
249 Difficulty GetDifficulty() const { return _difficulty; }
250
251 // return true for 25 man or 25 man heroic mode
252 bool Is25ManRaid() const { return _difficulty == DIFFICULTY_25_N || _difficulty == DIFFICULTY_25_HC; }
253
254 template <class T>
255 inline T const& DUNGEON_MODE(T const& normal5, T const& heroic10) const
256 {
257 switch (_difficulty)
258 {
260 return normal5;
262 return heroic10;
263 default:
264 break;
265 }
266
267 return heroic10;
268 }
269
270 template <class T>
271 inline T const& RAID_MODE(T const& normal10, T const& normal25) const
272 {
273 switch (_difficulty)
274 {
275 case DIFFICULTY_10_N:
276 return normal10;
277 case DIFFICULTY_25_N:
278 return normal25;
279 default:
280 break;
281 }
282
283 return normal25;
284 }
285
286 template <class T>
287 inline T const& RAID_MODE(T const& normal10, T const& normal25, T const& heroic10, T const& heroic25) const
288 {
289 switch (_difficulty)
290 {
291 case DIFFICULTY_10_N:
292 return normal10;
293 case DIFFICULTY_25_N:
294 return normal25;
295 case DIFFICULTY_10_HC:
296 return heroic10;
297 case DIFFICULTY_25_HC:
298 return heroic25;
299 default:
300 break;
301 }
302
303 return heroic25;
304 }
305
306 private:
309};
310
312{
313 public:
314 BossAI(Creature* creature, uint32 bossId);
315 virtual ~BossAI() { }
316
318
319 void JustSummoned(Creature* summon) override;
320 void SummonedCreatureDespawn(Creature* summon) override;
321
322 virtual void UpdateAI(uint32 diff) override;
323
324 // Hook used to execute events scheduled into EventMap without the need
325 // to override UpdateAI
326 // note: You must re-schedule the event within this method if the event
327 // is supposed to run more than once
328 virtual void ExecuteEvent(uint32 /*eventId*/) { }
329
330 virtual void ScheduleTasks() { }
331
332 void Reset() override { _Reset(); }
333 void JustEngagedWith(Unit* who) override { _JustEngagedWith(who); }
334 void JustDied(Unit* /*killer*/) override { _JustDied(); }
335 void JustReachedHome() override { _JustReachedHome(); }
336
337 bool CanAIAttack(Unit const* target) const override;
338
339 uint32 GetBossId() const { return _bossId; }
340
341 protected:
342 void _Reset();
343 void _JustEngagedWith(Unit* who);
344 void _JustDied();
345 void _JustReachedHome();
346 void _DespawnAtEvade(Seconds delayToRespawn = 30s, Creature* who = nullptr);
347
348 void TeleportCheaters();
349
353
354 private:
356};
357
359{
360 public:
361 WorldBossAI(Creature* creature);
362 virtual ~WorldBossAI() { }
363
364 void JustSummoned(Creature* summon) override;
365 void SummonedCreatureDespawn(Creature* summon) override;
366
367 virtual void UpdateAI(uint32 diff) override;
368
369 // Hook used to execute events scheduled into EventMap without the need
370 // to override UpdateAI
371 // note: You must re-schedule the event within this method if the event
372 // is supposed to run more than once
373 virtual void ExecuteEvent(uint32 /*eventId*/) { }
374
375 void Reset() override { _Reset(); }
376 void JustEngagedWith(Unit* /*who*/) override { _JustEngagedWith(); }
377 void JustDied(Unit* /*killer*/) override { _JustDied(); }
378
379 protected:
380 void _Reset();
381 void _JustEngagedWith();
382 void _JustDied();
383
386};
387
388// SD2 grid searchers.
389inline Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive = true)
390{
391 return source->FindNearestCreature(entry, maxSearchRange, alive);
392}
393
394inline Creature* GetClosestCreatureWithOptions(WorldObject* source, float maxSearchRange, FindCreatureOptions const& options)
395{
396 return source->FindNearestCreatureWithOptions(maxSearchRange, options);
397}
398
399inline GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool spawnedOnly = true)
400{
401 return source->FindNearestGameObject(entry, maxSearchRange, spawnedOnly);
402}
403
404template <typename Container>
405inline void GetCreatureListWithEntryInGrid(Container& container, WorldObject* source, uint32 entry, float maxSearchRange)
406{
407 source->GetCreatureListWithEntryInGrid(container, entry, maxSearchRange);
408}
409
410template <typename Container>
411inline void GetCreatureListWithOptionsInGrid(Container& container, WorldObject* source, float maxSearchRange, FindCreatureOptions const& options)
412{
413 source->GetCreatureListWithOptionsInGrid(container, maxSearchRange, options);
414}
415
416template <typename Container>
417inline void GetGameObjectListWithEntryInGrid(Container& container, WorldObject* source, uint32 entry, float maxSearchRange)
418{
419 source->GetGameObjectListWithEntryInGrid(container, entry, maxSearchRange);
420}
421
422template <typename Container>
423inline void GetPlayerListInGrid(Container& container, WorldObject* source, float maxSearchRange, bool alive = true)
424{
425 source->GetPlayerListInGrid(container, maxSearchRange, alive);
426}
427
428#endif // TRINITY_SCRIPTEDCREATURE_H
SelectEffect
SelectTargetType
@ EQUIP_NO_CHANGE
Definition: CreatureAI.h:54
Difficulty
Definition: DBCEnums.h:873
@ DIFFICULTY_25_HC
Definition: DBCEnums.h:880
@ DIFFICULTY_NORMAL
Definition: DBCEnums.h:875
@ DIFFICULTY_HEROIC
Definition: DBCEnums.h:876
@ DIFFICULTY_10_N
Definition: DBCEnums.h:877
@ DIFFICULTY_25_N
Definition: DBCEnums.h:878
@ DIFFICULTY_10_HC
Definition: DBCEnums.h:879
#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::chrono::seconds Seconds
Seconds shorthand typedef.
Definition: Duration.h:32
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
std::list< ObjectGuid > GuidList
Definition: ObjectGuid.h:394
void GetCreatureListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
void GetCreatureListWithOptionsInGrid(Container &container, WorldObject *source, float maxSearchRange, FindCreatureOptions const &options)
void GetPlayerListInGrid(Container &container, WorldObject *source, float maxSearchRange, bool alive=true)
Creature * GetClosestCreatureWithOptions(WorldObject *source, float maxSearchRange, FindCreatureOptions const &options)
GameObject * GetClosestGameObjectWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool spawnedOnly=true)
Creature * GetClosestCreatureWithEntry(WorldObject *source, uint32 entry, float maxSearchRange, bool alive=true)
void GetGameObjectListWithEntryInGrid(Container &container, WorldObject *source, uint32 entry, float maxSearchRange)
InstanceScript *const instance
void JustEngagedWith(Unit *who) override
void JustDied(Unit *) override
virtual ~BossAI()
uint32 GetBossId() const
uint32 const _bossId
virtual void ExecuteEvent(uint32)
TaskScheduler scheduler
void JustReachedHome() override
SummonList summons
EventMap events
virtual void ScheduleTasks()
void Reset() override
bool operator()(ObjectGuid const &) const
EntryCheckPredicate(uint32 entry)
bool operator()(ObjectGuid const &guid) const
uint32 GetEntry() const
Definition: ObjectGuid.h:291
bool empty() const
Creature * _me
iterator erase(iterator i)
iterator begin()
StorageType::const_iterator const_iterator
void DespawnIf(T const &predicate)
StorageType::size_type size_type
iterator end()
SummonList(Creature *creature)
StorageType::value_type value_type
size_type size() const
const_iterator begin() const
GuidList StorageType
const_iterator end() const
StorageType::iterator iterator
void DoAction(int32 info, Predicate &&predicate, uint16 max=0)
StorageType _storage
Definition: Unit.h:627
void JustDied(Unit *) override
virtual void ExecuteEvent(uint32)
virtual ~WorldBossAI()
void JustEngagedWith(Unit *) override
void Reset() override
SummonList summons
void GetPlayerListInGrid(Container &playerContainer, float maxSearchRange, bool alive=true) const
Definition: Object.cpp:3332
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition: Object.cpp:2170
Creature * FindNearestCreatureWithOptions(float range, FindCreatureOptions const &options) const
Definition: Object.cpp:2157
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3312
void GetGameObjectListWithEntryInGrid(Container &gameObjectContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition: Object.cpp:3292
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition: Object.cpp:2148
void GetCreatureListWithOptionsInGrid(Container &creatureContainer, float maxSearchRange, FindCreatureOptions const &options) const
Definition: Object.cpp:3320
T const & DUNGEON_MODE(T const &normal5, T const &heroic10) const
bool IsCombatMovementAllowed() const
Difficulty _difficulty
T const & RAID_MODE(T const &normal10, T const &normal25) const
bool _isCombatMovementAllowed
virtual ~ScriptedAI()
Difficulty GetDifficulty() const
bool Is25ManRaid() const
T const & RAID_MODE(T const &normal10, T const &normal25, T const &heroic10, T const &heroic25) const