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