TrinityCore
Loading...
Searching...
No Matches
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, uint32 scriptId = 0) noexcept;
137 virtual ~ScriptedAI() { }
138
139 // *************
140 // CreatureAI Functions
141 // *************
142
143 void AttackStartNoMove(Unit* target);
144
145 // Called at World update tick
146 virtual void UpdateAI(uint32 diff) override;
147
148 // *************
149 // Variables
150 // *************
151
152 // *************
153 // Pure virtual functions
154 // *************
155
156 // Called before JustEngagedWith even before the creature is in combat.
157 void AttackStart(Unit* /*target*/) override;
158
159 // *************
160 // AI Helper Functions
161 // *************
162
163 // Start movement toward victim
164 void DoStartMovement(Unit* target, float distance = 0.0f, float angle = 0.0f);
165
166 // Start no movement on victim
167 void DoStartNoMovement(Unit* target);
168
169 // Stop attack of current victim
170 void DoStopAttack();
171
172 // Cast spell by spell info
173 void DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool triggered = false);
174
175 // Plays a sound to all nearby players
176 void DoPlaySoundToSet(WorldObject* source, uint32 soundId);
177
178 // Add specified amount of threat directly to victim (ignores redirection effects) - also puts victim in combat and engages them if necessary
179 void AddThreat(Unit* victim, float amount, Unit* who = nullptr);
180 // Adds/removes the specified percentage from the specified victim's threat (to who, or me if not specified)
181 void ModifyThreatByPercent(Unit* victim, int32 pct, Unit* who = nullptr);
182 // Resets the victim's threat level to who (or me if not specified) to zero
183 void ResetThreat(Unit* victim, Unit* who = nullptr);
184 // Resets the specified unit's threat list (me if not specified) - does not delete entries, just sets their threat to zero
185 void ResetThreatList(Unit* who = nullptr);
186 // Returns the threat level of victim towards who (or me if not specified)
187 float GetThreat(Unit const* victim, Unit const* who = nullptr);
188 // Stops combat, ignoring restrictions, for the given creature
189 void ForceCombatStop(Creature* who, bool reset = true);
190 // Stops combat, ignoring restrictions, for the found creatures
191 void ForceCombatStopForCreatureEntry(uint32 entry, float maxSearchRange = 250.0f, bool samePhase = true, bool reset = true);
192 // Stops combat, ignoring restrictions, for the found creatures
193 void ForceCombatStopForCreatureEntry(std::vector<uint32> creatureEntries, float maxSearchRange = 250.0f, bool samePhase = true, bool reset = true);
194
195 void DoTeleportTo(float x, float y, float z, uint32 time = 0);
196 void DoTeleportTo(float const pos[4]);
197
198 // Teleports a player without dropping threat (only teleports to same map)
199 void DoTeleportPlayer(Unit* unit, float x, float y, float z, float o);
200 void DoTeleportAll(float x, float y, float z, float o);
201
202 // Returns friendly unit with the most amount of hp missing from max hp
203 Unit* DoSelectLowestHpFriendly(float range, uint32 minHPDiff = 1);
204
205 // Returns friendly unit with hp pct below specified and with specified entry
206 Unit* DoSelectBelowHpPctFriendlyWithEntry(uint32 entry, float range, uint8 hpPct = 1, bool excludeSelf = true);
207
208 // Returns a list of friendly CC'd units within range
209 std::list<Creature*> DoFindFriendlyCC(float range);
210
211 // Returns a list of all friendly units missing a specific buff within range
212 std::list<Creature*> DoFindFriendlyMissingBuff(float range, uint32 spellId);
213
214 // Return a player with at least minimumRange from me
215 Player* GetPlayerAtMinimumRange(float minRange);
216
217 // Spawns a creature relative to me
218 Creature* DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, Milliseconds despawntime);
219
220 bool HealthBelowPct(uint32 pct) const;
221 bool HealthAbovePct(uint32 pct) const;
222
223 // Returns spells that meet the specified criteria from the creatures spell list
224 SpellInfo const* SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect);
225
226 void SetEquipmentSlots(bool loadDefault, int32 mainHand = EQUIP_NO_CHANGE, int32 offHand = EQUIP_NO_CHANGE, int32 ranged = EQUIP_NO_CHANGE);
227
228 // Used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims
229 // NOTE: If you use SetCombatMovement while the creature is in combat, it will do NOTHING - This only affects AttackStart
230 // You should make the necessary to make it happen so.
231 // Remember that if you modified _isCombatMovementAllowed (e.g: using SetCombatMovement) it will not be reset at Reset().
232 // It will keep the last value you set.
233 void SetCombatMovement(bool allowMovement);
234 bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; }
235
236 bool IsLFR() const;
237 bool IsNormal() const;
238 bool IsHeroic() const;
239 bool IsMythic() const;
240 bool IsMythicPlus() const;
241 bool IsHeroicOrHigher() const;
242 bool IsTimewalking() const;
243
244 // return the dungeon or raid difficulty
245 Difficulty GetDifficulty() const { return _difficulty; }
246
247 // return true for 25 man or 25 man heroic mode
248 bool Is25ManRaid() const { return _difficulty == DIFFICULTY_25_N || _difficulty == DIFFICULTY_25_HC; }
249
250 template <class T>
251 inline T const& DUNGEON_MODE(T const& normal5, T const& heroic10) const
252 {
253 switch (_difficulty)
254 {
256 return normal5;
258 return heroic10;
259 default:
260 break;
261 }
262
263 return heroic10;
264 }
265
266 template <class T>
267 inline T const& RAID_MODE(T const& normal10, T const& normal25) const
268 {
269 switch (_difficulty)
270 {
271 case DIFFICULTY_10_N:
272 return normal10;
273 case DIFFICULTY_25_N:
274 return normal25;
275 default:
276 break;
277 }
278
279 return normal25;
280 }
281
282 template <class T>
283 inline T const& RAID_MODE(T const& normal10, T const& normal25, T const& heroic10, T const& heroic25) const
284 {
285 switch (_difficulty)
286 {
287 case DIFFICULTY_10_N:
288 return normal10;
289 case DIFFICULTY_25_N:
290 return normal25;
291 case DIFFICULTY_10_HC:
292 return heroic10;
293 case DIFFICULTY_25_HC:
294 return heroic25;
295 default:
296 break;
297 }
298
299 return heroic25;
300 }
301
302 private:
305};
306
308{
309 public:
310 explicit BossAI(Creature* creature, uint32 bossId) noexcept;
311 virtual ~BossAI();
312
314
315 void JustSummoned(Creature* summon) override;
316 void SummonedCreatureDespawn(Creature* summon) override;
317
318 virtual void UpdateAI(uint32 diff) override;
319
320 // Hook used to execute events scheduled into EventMap without the need
321 // to override UpdateAI
322 // note: You must re-schedule the event within this method if the event
323 // is supposed to run more than once
324 virtual void ExecuteEvent(uint32 /*eventId*/) { }
325
326 virtual void ScheduleTasks() { }
327
328 void Reset() override { _Reset(); }
329 void JustEngagedWith(Unit* who) override { _JustEngagedWith(who); }
330 void JustDied(Unit* /*killer*/) override { _JustDied(); }
331 void JustReachedHome() override { _JustReachedHome(); }
332
333 bool CanAIAttack(Unit const* target) const override;
334
335 uint32 GetBossId() const { return _bossId; }
336
337 protected:
338 void _Reset();
339 void _JustEngagedWith(Unit* who);
340 void _JustDied();
341 void _JustReachedHome();
342 void _DespawnAtEvade(Seconds delayToRespawn = 30s, Creature* who = nullptr);
343
344 void TeleportCheaters();
345
349
350 private:
352};
353
355{
356 public:
357 explicit WorldBossAI(Creature* creature) noexcept;
358 virtual ~WorldBossAI();
359
360 void JustSummoned(Creature* summon) override;
361 void SummonedCreatureDespawn(Creature* summon) override;
362
363 virtual void UpdateAI(uint32 diff) override;
364
365 // Hook used to execute events scheduled into EventMap without the need
366 // to override UpdateAI
367 // note: You must re-schedule the event within this method if the event
368 // is supposed to run more than once
369 virtual void ExecuteEvent(uint32 /*eventId*/) { }
370
371 void Reset() override { _Reset(); }
372 void JustEngagedWith(Unit* /*who*/) override { _JustEngagedWith(); }
373 void JustDied(Unit* /*killer*/) override { _JustDied(); }
374
375 protected:
376 void _Reset();
377 void _JustEngagedWith();
378 void _JustDied();
379
382};
383
384// SD2 grid searchers.
385inline Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive = true)
386{
387 return source->FindNearestCreature(entry, maxSearchRange, alive);
388}
389
390inline Creature* GetClosestCreatureWithOptions(WorldObject* source, float maxSearchRange, FindCreatureOptions const& options)
391{
392 return source->FindNearestCreatureWithOptions(maxSearchRange, options);
393}
394
395inline GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool spawnedOnly = true)
396{
397 return source->FindNearestGameObject(entry, maxSearchRange, spawnedOnly);
398}
399
400template <typename Container>
401inline void GetCreatureListWithEntryInGrid(Container& container, WorldObject* source, uint32 entry, float maxSearchRange)
402{
403 source->GetCreatureListWithEntryInGrid(container, entry, maxSearchRange);
404}
405
406template <typename Container>
407inline void GetCreatureListWithOptionsInGrid(Container& container, WorldObject* source, float maxSearchRange, FindCreatureOptions const& options)
408{
409 source->GetCreatureListWithOptionsInGrid(container, maxSearchRange, options);
410}
411
412template <typename Container>
413inline void GetGameObjectListWithEntryInGrid(Container& container, WorldObject* source, uint32 entry, float maxSearchRange)
414{
415 source->GetGameObjectListWithEntryInGrid(container, entry, maxSearchRange);
416}
417
418template <typename Container>
419inline void GetPlayerListInGrid(Container& container, WorldObject* source, float maxSearchRange, bool alive = true)
420{
421 source->GetPlayerListInGrid(container, maxSearchRange, alive);
422}
423
424#endif // TRINITY_SCRIPTEDCREATURE_H
SelectEffect
SelectTargetType
@ EQUIP_NO_CHANGE
Definition CreatureAI.h:56
Difficulty
Definition DBCEnums.h:932
@ DIFFICULTY_25_HC
Definition DBCEnums.h:939
@ DIFFICULTY_NORMAL
Definition DBCEnums.h:934
@ DIFFICULTY_HEROIC
Definition DBCEnums.h:935
@ DIFFICULTY_10_N
Definition DBCEnums.h:936
@ DIFFICULTY_25_N
Definition DBCEnums.h:937
@ DIFFICULTY_10_HC
Definition DBCEnums.h:938
#define TC_GAME_API
Definition Define.h:129
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
std::list< ObjectGuid > GuidList
Definition ObjectGuid.h:433
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
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
virtual ~BossAI()
bool operator()(ObjectGuid const &) const
EntryCheckPredicate(uint32 entry)
bool operator()(ObjectGuid const &guid) const
uint32 GetEntry() const
Definition ObjectGuid.h:334
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:635
void JustDied(Unit *) override
virtual ~WorldBossAI()
virtual void ExecuteEvent(uint32)
void JustEngagedWith(Unit *) override
void Reset() override
SummonList summons
void GetPlayerListInGrid(Container &playerContainer, float maxSearchRange, bool alive=true) const
Definition Object.cpp:2678
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition Object.cpp:1539
Creature * FindNearestCreatureWithOptions(float range, FindCreatureOptions const &options) const
Definition Object.cpp:1526
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:2658
void GetGameObjectListWithEntryInGrid(Container &gameObjectContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:2638
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:1517
void GetCreatureListWithOptionsInGrid(Container &creatureContainer, float maxSearchRange, FindCreatureOptions const &options) const
Definition Object.cpp:2666
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