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 "Creature.h" // convenience include for scripts, all uses of ScriptedCreature also need Creature (except ScriptedCreature itself doesn't need Creature)
23#include "CreatureAI.h"
24#include "DBCEnums.h"
25#include "TaskScheduler.h"
26
27class InstanceScript;
28
30{
31public:
33 typedef StorageType::iterator iterator;
34 typedef StorageType::const_iterator const_iterator;
35 typedef StorageType::size_type size_type;
36 typedef StorageType::value_type value_type;
37
38 explicit SummonList(Creature* creature) : _me(creature) { }
39
40 // And here we see a problem of original inheritance approach. People started
41 // to exploit presence of std::list members, so I have to provide wrappers
42
44 {
45 return _storage.begin();
46 }
47
49 {
50 return _storage.begin();
51 }
52
54 {
55 return _storage.end();
56 }
57
59 {
60 return _storage.end();
61 }
62
64 {
65 return _storage.erase(i);
66 }
67
68 bool empty() const
69 {
70 return _storage.empty();
71 }
72
74 {
75 return _storage.size();
76 }
77
78 // Clear the underlying storage. This does NOT despawn the creatures - use DespawnAll for that!
79 void clear()
80 {
81 _storage.clear();
82 }
83
84 void Summon(Creature const* summon);
85 void Despawn(Creature const* summon);
86 void DespawnEntry(uint32 entry);
87 void DespawnAll();
88
89 template <typename T>
90 void DespawnIf(T const& predicate)
91 {
92 _storage.remove_if(predicate);
93 }
94
95 template <class Predicate>
96 void DoAction(int32 info, Predicate&& predicate, uint16 max = 0)
97 {
98 // We need to use a copy of SummonList here, otherwise original SummonList would be modified
99 StorageType listCopy;
100 std::copy_if(std::begin(_storage), std::end(_storage), std::inserter(listCopy, std::end(listCopy)), predicate);
101 DoActionImpl(info, listCopy, max);
102 }
103
104 void DoZoneInCombat(uint32 entry = 0);
105 void RemoveNotExisting();
106 bool HasEntry(uint32 entry) const;
107
108private:
109 void DoActionImpl(int32 action, StorageType& summons, uint16 max);
110
113};
114
116{
117 public:
118 EntryCheckPredicate(uint32 entry) : _entry(entry) { }
119 bool operator()(ObjectGuid guid) { return guid.GetEntry() == _entry; }
120
121 private:
123};
124
126{
127 public:
128 bool operator()(ObjectGuid) { return true; }
129};
130
132{
133 public:
134 explicit ScriptedAI(Creature* creature);
135 virtual ~ScriptedAI() { }
136
137 // *************
138 // CreatureAI Functions
139 // *************
140
141 void AttackStartNoMove(Unit* target);
142
143 // Called at World update tick
144 virtual void UpdateAI(uint32 diff) override;
145
146 // *************
147 // Variables
148 // *************
149
150 // For fleeing
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, uint32 powerCostMin, uint32 powerCostMax, 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 // return true for heroic mode. i.e.
238 // - for dungeon in mode 10-heroic,
239 // - for raid in mode 10-Heroic
240 // - for raid in mode 25-heroic
241 // DO NOT USE to check raid in mode 25-normal.
242 bool IsHeroic() const { return _isHeroic; }
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 & RAID_DIFFICULTY_MASK_25MAN; }
249
250 void SetAggressiveStateAfter(Milliseconds timer, Creature* who = nullptr, bool startCombat = true, Creature* summoner = nullptr, StartCombatArgs const& combatArgs = { });
251
252 void DoAddEvent(Milliseconds timer, BasicEvent* event, WorldObject* who = nullptr);
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 {
276 return normal10;
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 {
292 return normal10;
294 return normal25;
296 return heroic10;
298 return heroic25;
299 default:
300 break;
301 }
302
303 return heroic25;
304 }
305
306 private:
310};
311
313{
314 public:
315 BossAI(Creature* creature, uint32 bossId);
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 protected:
341 void _Reset();
342 void _JustEngagedWith(Unit* who);
343 void _JustDied();
344 void _JustReachedHome();
345 void _DespawnAtEvade(Seconds delayToRespawn = 30s, Creature* who = nullptr);
346
347 void TeleportCheaters();
348
352
353 private:
355};
356
358{
359 public:
360 WorldBossAI(Creature* creature);
361 virtual ~WorldBossAI() { }
362
363 void JustSummoned(Creature* summon) override;
364 void SummonedCreatureDespawn(Creature* summon) override;
365
366 virtual void UpdateAI(uint32 diff) override;
367
368 // Hook used to execute events scheduled into EventMap without the need
369 // to override UpdateAI
370 // note: You must re-schedule the event within this method if the event
371 // is supposed to run more than once
372 virtual void ExecuteEvent(uint32 /*eventId*/) { }
373
374 void Reset() override { _Reset(); }
375 void JustEngagedWith(Unit* /*who*/) override { _JustEngagedWith(); }
376 void JustDied(Unit* /*killer*/) override { _JustDied(); }
377
378 protected:
379 void _Reset();
380 void _JustEngagedWith();
381 void _JustDied();
382
385};
386
387// SD2 grid searchers.
388inline Creature* GetClosestCreatureWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool alive = true)
389{
390 return source->FindNearestCreature(entry, maxSearchRange, alive);
391}
392
393inline Creature* GetClosestCreatureWithOptions(WorldObject* source, float maxSearchRange, FindCreatureOptions const& options)
394{
395 return source->FindNearestCreatureWithOptions(maxSearchRange, options);
396}
397
398inline GameObject* GetClosestGameObjectWithEntry(WorldObject* source, uint32 entry, float maxSearchRange, bool spawnedOnly = true)
399{
400 return source->FindNearestGameObject(entry, maxSearchRange, spawnedOnly);
401}
402
403template <typename Container>
404inline void GetCreatureListWithEntryInGrid(Container& container, WorldObject* source, uint32 entry, float maxSearchRange)
405{
406 source->GetCreatureListWithEntryInGrid(container, entry, maxSearchRange);
407}
408
409template <typename Container>
410inline void GetCreatureListWithOptionsInGrid(Container& container, WorldObject* source, float maxSearchRange, FindCreatureOptions const& options)
411{
412 source->GetCreatureListWithOptionsInGrid(container, maxSearchRange, options);
413}
414
415template <typename Container>
416inline void GetGameObjectListWithEntryInGrid(Container& container, WorldObject* source, uint32 entry, float maxSearchRange)
417{
418 source->GetGameObjectListWithEntryInGrid(container, entry, maxSearchRange);
419}
420
421template <typename Container>
422inline void GetPlayerListInGrid(Container& container, WorldObject* source, float maxSearchRange, bool alive = true)
423{
424 source->GetPlayerListInGrid(container, maxSearchRange, alive);
425}
426
427#endif // TRINITY_SCRIPTEDCREATURE_H
SelectTargetType
Definition CreatureAI.h:53
@ EQUIP_NO_CHANGE
Definition CreatureAI.h:75
SelectEffect
Definition CreatureAI.h:66
Difficulty
Definition DBCEnums.h:279
@ RAID_DIFFICULTY_25MAN_HEROIC
Definition DBCEnums.h:289
@ RAID_DIFFICULTY_10MAN_NORMAL
Definition DBCEnums.h:286
@ DUNGEON_DIFFICULTY_NORMAL
Definition DBCEnums.h:282
@ RAID_DIFFICULTY_25MAN_NORMAL
Definition DBCEnums.h:287
@ DUNGEON_DIFFICULTY_HEROIC
Definition DBCEnums.h:283
@ RAID_DIFFICULTY_10MAN_HEROIC
Definition DBCEnums.h:288
#define RAID_DIFFICULTY_MASK_25MAN
Definition DBCEnums.h:292
#define TC_GAME_API
Definition Define.h:114
uint8_t uint8
Definition Define.h:135
int32_t int32
Definition Define.h:129
uint16_t uint16
Definition Define.h:134
uint32_t uint32
Definition Define.h:133
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:27
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::list< ObjectGuid > GuidList
Definition ObjectGuid.h:261
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 const _bossId
virtual void ExecuteEvent(uint32)
TaskScheduler scheduler
void JustReachedHome() override
SummonList summons
EventMap events
virtual void ScheduleTasks()
void Reset() override
EntryCheckPredicate(uint32 entry)
bool operator()(ObjectGuid guid)
uint32 GetEntry() const
Definition ObjectGuid.h:155
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:769
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:3173
GameObject * FindNearestGameObject(uint32 entry, float range, bool spawnedOnly=true) const
Definition Object.cpp:2121
Creature * FindNearestCreatureWithOptions(float range, FindCreatureOptions const &options) const
Definition Object.cpp:2108
void GetCreatureListWithEntryInGrid(Container &creatureContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:3153
void GetGameObjectListWithEntryInGrid(Container &gameObjectContainer, uint32 entry, float maxSearchRange=250.0f) const
Definition Object.cpp:3133
Creature * FindNearestCreature(uint32 entry, float range, bool alive=true) const
Definition Object.cpp:2099
void GetCreatureListWithOptionsInGrid(Container &creatureContainer, float maxSearchRange, FindCreatureOptions const &options) const
Definition Object.cpp:3161
bool IsHeroic() const
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