TrinityCore
ScriptedCreature.cpp
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#include "ScriptedCreature.h"
19#include "AreaBoundary.h"
20#include "DB2Stores.h"
21#include "Cell.h"
22#include "CellImpl.h"
23#include "Containers.h"
24#include "CreatureAIImpl.h"
25#include "GridNotifiers.h"
26#include "GridNotifiersImpl.h"
27#include "InstanceScript.h"
28#include "Log.h"
29#include "Loot.h"
30#include "MotionMaster.h"
31#include "ObjectAccessor.h"
32#include "PhasingHandler.h"
33#include "Spell.h"
34#include "SpellMgr.h"
35#include "TemporarySummon.h"
36
37void SummonList::Summon(Creature const* summon)
38{
39 _storage.push_back(summon->GetGUID());
40}
41
42void SummonList::Despawn(Creature const* summon)
43{
44 _storage.remove(summon->GetGUID());
45}
46
48{
49 for (StorageType::iterator i = _storage.begin(); i != _storage.end();)
50 {
52 ++i;
53 if (summon && summon->IsAIEnabled()
54 && (!entry || summon->GetEntry() == entry))
55 {
56 summon->AI()->DoZoneInCombat();
57 }
58 }
59}
60
62{
63 for (StorageType::iterator i = _storage.begin(); i != _storage.end();)
64 {
66 if (!summon)
67 i = _storage.erase(i);
68 else if (summon->GetEntry() == entry)
69 {
70 i = _storage.erase(i);
71 summon->DespawnOrUnsummon();
72 }
73 else
74 ++i;
75 }
76}
77
79{
80 while (!_storage.empty())
81 {
83 _storage.pop_front();
84 if (summon)
85 summon->DespawnOrUnsummon();
86 }
87}
88
90{
91 for (StorageType::iterator i = _storage.begin(); i != _storage.end();)
92 {
94 ++i;
95 else
96 i = _storage.erase(i);
97 }
98}
99
101{
102 for (ObjectGuid const& guid : _storage)
103 {
104 Creature* summon = ObjectAccessor::GetCreature(*_me, guid);
105 if (summon && summon->GetEntry() == entry)
106 return true;
107 }
108
109 return false;
110}
111
113{
114 if (max)
116
117 for (ObjectGuid const& guid : summons)
118 {
119 Creature* summon = ObjectAccessor::GetCreature(*_me, guid);
120 if (summon && summon->IsAIEnabled())
121 summon->AI()->DoAction(action);
122 }
123}
124
125ScriptedAI::ScriptedAI(Creature* creature) : ScriptedAI(creature, creature->GetScriptId()) { }
126
127ScriptedAI::ScriptedAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), IsFleeing(false), _isCombatMovementAllowed(true)
128{
130}
131
133{
134 if (!who)
135 return;
137 if (me->Attack(who, true))
139}
140
142{
145 else
147}
148
150{
151 // Check if we have a current target
152 UpdateVictim();
153}
154
155void ScriptedAI::DoStartMovement(Unit* victim, float distance, float angle)
156{
157 if (victim)
158 me->StartDefaultCombatMovement(victim, distance, angle);
159}
160
162{
163 if (!victim)
164 return;
165
167}
168
170{
171 if (me->GetVictim())
172 me->AttackStop();
173}
174
175void ScriptedAI::DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool triggered)
176{
177 if (!target || me->IsNonMeleeSpellCast(false))
178 return;
179
180 me->StopMoving();
181 me->CastSpell(target, spellInfo->Id, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
182}
183
185{
186 if (!source)
187 return;
188
189 if (!sSoundKitStore.LookupEntry(soundId))
190 {
191 TC_LOG_ERROR("scripts.ai", "ScriptedAI::DoPlaySoundToSet: Invalid soundId {} used in DoPlaySoundToSet (Source: {})", soundId, source->GetGUID().ToString());
192 return;
193 }
194
195 source->PlayDirectSound(soundId);
196}
197
198void ScriptedAI::AddThreat(Unit* victim, float amount, Unit* who)
199{
200 if (!victim)
201 return;
202 if (!who)
203 who = me;
204 who->GetThreatManager().AddThreat(victim, amount, nullptr, true, true);
205}
206
208{
209 if (!victim)
210 return;
211 if (!who)
212 who = me;
213 who->GetThreatManager().ModifyThreatByPercent(victim, pct);
214}
215
217{
218 if (!victim)
219 return;
220 if (!who)
221 who = me;
222 who->GetThreatManager().ResetThreat(victim);
223}
224
226{
227 if (!who)
228 who = me;
230}
231
232float ScriptedAI::GetThreat(Unit const* victim, Unit const* who)
233{
234 if (!victim)
235 return 0.0f;
236 if (!who)
237 who = me;
238 return who->GetThreatManager().GetThreat(victim);
239}
240
241void ScriptedAI::ForceCombatStop(Creature* who, bool reset /*= true*/)
242{
243 if (!who || !who->IsInCombat())
244 return;
245
246 who->CombatStop(true);
249
250 if (reset)
251 {
252 who->LoadCreaturesAddon();
254 who->SetTappedBy(nullptr);
255
257 who->SetLastDamagedTime(0);
258 who->SetCannotReachTarget(false);
259 }
260}
261
262void ScriptedAI::ForceCombatStopForCreatureEntry(uint32 entry, float maxSearchRange /*= 250.0f*/, bool samePhase /*= true*/, bool reset /*= true*/)
263{
264 TC_LOG_DEBUG("scripts.ai", "ScriptedAI::ForceCombatStopForCreatureEntry: called on '{}'. Debug info: {}", me->GetGUID().ToString(), me->GetDebugInfo());
265
266 std::list<Creature*> creatures;
267 Trinity::AllCreaturesOfEntryInRange check(me, entry, maxSearchRange);
269
270 if (!samePhase)
272
273 Cell::VisitGridObjects(me, searcher, maxSearchRange);
274
275 if (!samePhase)
277
278 for (Creature* creature : creatures)
279 ForceCombatStop(creature, reset);
280}
281
282void ScriptedAI::ForceCombatStopForCreatureEntry(std::vector<uint32> creatureEntries, float maxSearchRange /*= 250.0f*/, bool samePhase /*= true*/, bool reset /*= true*/)
283{
284 for (uint32 const entry : creatureEntries)
285 ForceCombatStopForCreatureEntry(entry, maxSearchRange, samePhase, reset);
286}
287
288Creature* ScriptedAI::DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, Milliseconds despawntime)
289{
290 return me->SummonCreature(entry, me->GetPositionX() + offsetX, me->GetPositionY() + offsetY, me->GetPositionZ() + offsetZ, angle, TempSummonType(type), despawntime);
291}
292
294{
295 return me->HealthBelowPct(pct);
296}
297
299{
300 return me->HealthAbovePct(pct);
301}
302
304{
305 return me->GetMap()->IsLFR();
306}
307
309{
310 return me->GetMap()->IsNormal();
311}
312
314{
315 return me->GetMap()->IsHeroic();
316}
317
319{
320 return me->GetMap()->IsMythic();
321}
322
324{
325 return me->GetMap()->IsMythicPlus();
326}
327
329{
330 return me->GetMap()->IsHeroicOrHigher();
331}
332
334{
335 return me->GetMap()->IsTimewalking();
336}
337
338SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect)
339{
340 // No target so we can't cast
341 if (!target)
342 return nullptr;
343
344 // Silenced so we can't cast
345 if (me->IsSilenced(school ? SpellSchoolMask(school) : SPELL_SCHOOL_MASK_MAGIC))
346 return nullptr;
347
348 // Using the extended script system we first create a list of viable spells
349 SpellInfo const* apSpell[MAX_CREATURE_SPELLS];
350 memset(apSpell, 0, MAX_CREATURE_SPELLS * sizeof(SpellInfo*));
351
352 uint32 spellCount = 0;
353
354 SpellInfo const* tempSpell = nullptr;
355 AISpellInfoType const* aiSpell = nullptr;
356
357 // Check if each spell is viable(set it to null if not)
358 for (uint32 spell : me->m_spells)
359 {
360 tempSpell = sSpellMgr->GetSpellInfo(spell, me->GetMap()->GetDifficultyID());
361 aiSpell = GetAISpellInfo(spell, me->GetMap()->GetDifficultyID());
362
363 // This spell doesn't exist
364 if (!tempSpell || !aiSpell)
365 continue;
366
367 // Targets and Effects checked first as most used restrictions
368 // Check the spell targets if specified
369 if (targets && !(aiSpell->Targets & (1 << (targets-1))))
370 continue;
371
372 // Check the type of spell if we are looking for a specific spell type
373 if (effect && !(aiSpell->Effects & (1 << (effect-1))))
374 continue;
375
376 // Check for school if specified
377 if (school && (tempSpell->SchoolMask & school) == 0)
378 continue;
379
380 // Check for spell mechanic if specified
381 if (mechanic && tempSpell->Mechanic != mechanic)
382 continue;
383
384 // Continue if we don't have the mana to actually cast this spell
385 bool hasPower = true;
386 for (SpellPowerCost const& cost : tempSpell->CalcPowerCost(me, tempSpell->GetSchoolMask()))
387 {
388 if (cost.Amount > me->GetPower(cost.Power))
389 {
390 hasPower = false;
391 break;
392 }
393 }
394
395 if (!hasPower)
396 continue;
397
398 // Check if the spell meets our range requirements
399 if (rangeMin && me->GetSpellMinRangeForTarget(target, tempSpell) < rangeMin)
400 continue;
401 if (rangeMax && me->GetSpellMaxRangeForTarget(target, tempSpell) > rangeMax)
402 continue;
403
404 // Check if our target is in range
405 if (me->IsWithinDistInMap(target, float(me->GetSpellMinRangeForTarget(target, tempSpell))) || !me->IsWithinDistInMap(target, float(me->GetSpellMaxRangeForTarget(target, tempSpell))))
406 continue;
407
408 // All good so lets add it to the spell list
409 apSpell[spellCount] = tempSpell;
410 ++spellCount;
411 }
412
413 // We got our usable spells so now lets randomly pick one
414 if (!spellCount)
415 return nullptr;
416
417 return apSpell[urand(0, spellCount - 1)];
418}
419
420void ScriptedAI::DoTeleportTo(float x, float y, float z, uint32 time)
421{
422 me->Relocate(x, y, z);
423 float speed = me->GetDistance(x, y, z) / ((float)time * 0.001f);
424 me->MonsterMoveWithSpeed(x, y, z, speed);
425}
426
427void ScriptedAI::DoTeleportTo(const float position[4])
428{
429 me->NearTeleportTo(position[0], position[1], position[2], position[3]);
430}
431
432void ScriptedAI::DoTeleportPlayer(Unit* unit, float x, float y, float z, float o)
433{
434 if (!unit)
435 return;
436
437 if (Player* player = unit->ToPlayer())
438 player->TeleportTo(unit->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT);
439 else
440 TC_LOG_ERROR("scripts.ai", "ScriptedAI::DoTeleportPlayer: Creature {} Tried to teleport non-player unit ({}) to x: {} y:{} z: {} o: {}. Aborted.",
441 me->GetGUID().ToString(), unit->GetGUID().ToString(), x, y, z, o);
442}
443
444void ScriptedAI::DoTeleportAll(float x, float y, float z, float o)
445{
446 Map* map = me->GetMap();
447 if (!map->IsDungeon())
448 return;
449
450 for (MapReference const& mapref : map->GetPlayers())
451 if (Player* player = mapref.GetSource())
452 if (player->IsAlive())
453 player->TeleportTo(me->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT);
454}
455
457{
458 Unit* unit = nullptr;
459 Trinity::MostHPMissingInRange u_check(me, range, minHPDiff);
461 Cell::VisitAllObjects(me, searcher, range);
462
463 return unit;
464}
465
466Unit* ScriptedAI::DoSelectBelowHpPctFriendlyWithEntry(uint32 entry, float range, uint8 minHPDiff, bool excludeSelf)
467{
468 Unit* unit = nullptr;
469 Trinity::FriendlyBelowHpPctEntryInRange u_check(me, entry, range, minHPDiff, excludeSelf);
471 Cell::VisitAllObjects(me, searcher, range);
472
473 return unit;
474}
475
476std::list<Creature*> ScriptedAI::DoFindFriendlyCC(float range)
477{
478 std::list<Creature*> list;
479 Trinity::FriendlyCCedInRange u_check(me, range);
481 Cell::VisitAllObjects(me, searcher, range);
482
483 return list;
484}
485
486std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float range, uint32 uiSpellid)
487{
488 std::list<Creature*> list;
489 Trinity::FriendlyMissingBuffInRange u_check(me, range, uiSpellid);
491 Cell::VisitAllObjects(me, searcher, range);
492
493 return list;
494}
495
497{
498 Player* player = nullptr;
499
500 Trinity::PlayerAtMinimumRangeAway check(me, minimumRange);
502 Cell::VisitWorldObjects(me, searcher, minimumRange);
503
504 return player;
505}
506
507void ScriptedAI::SetEquipmentSlots(bool loadDefault, int32 mainHand /*= EQUIP_NO_CHANGE*/, int32 offHand /*= EQUIP_NO_CHANGE*/, int32 ranged /*= EQUIP_NO_CHANGE*/)
508{
509 if (loadDefault)
510 {
512 return;
513 }
514
515 if (mainHand >= 0)
516 me->SetVirtualItem(0, uint32(mainHand));
517
518 if (offHand >= 0)
519 me->SetVirtualItem(1, uint32(offHand));
520
521 if (ranged >= 0)
522 me->SetVirtualItem(2, uint32(ranged));
523}
524
525void ScriptedAI::SetCombatMovement(bool allowMovement)
526{
527 _isCombatMovementAllowed = allowMovement;
528}
529
530// BossAI - for instanced bosses
531BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature), instance(creature->GetInstanceScript()), summons(creature), _bossId(bossId)
532{
533 if (instance)
536 {
538 });
539}
540
542{
543 if (!me->IsAlive())
544 return;
545
547 me->ResetLootMode();
548 events.Reset();
553}
554
556{
557 events.Reset();
560 if (instance)
562}
563
565{
566 me->setActive(false);
567}
568
570{
571 if (instance)
572 {
573 // bosses do not respawn, check only on enter combat
575 {
577 return;
578 }
580 }
581
583 me->setActive(true);
586}
587
589{
590 float x, y, z;
591 me->GetPosition(x, y, z);
592
593 for (auto const& pair : me->GetCombatManager().GetPvECombatRefs())
594 {
595 Unit* target = pair.second->GetOther(me);
596 if (target->IsControlledByPlayer() && !IsInBoundary(target))
597 target->NearTeleportTo(x, y, z, 0);
598 }
599}
600
602{
603 summons.Summon(summon);
604 if (me->IsEngaged())
605 DoZoneInCombat(summon);
606}
607
609{
610 summons.Despawn(summon);
611}
612
614{
615 if (!UpdateVictim())
616 return;
617
618 events.Update(diff);
619
621 return;
622
623 while (uint32 eventId = events.ExecuteEvent())
624 {
625 ExecuteEvent(eventId);
627 return;
628 }
629}
630
631bool BossAI::CanAIAttack(Unit const* target) const
632{
633 return IsInBoundary(target);
634}
635
636void BossAI::_DespawnAtEvade(Seconds delayToRespawn /*= 30s*/, Creature* who /*= nullptr*/)
637{
638 if (delayToRespawn < 2s)
639 {
640 TC_LOG_ERROR("scripts.ai", "BossAI::_DespawnAtEvade: called with delay of {} seconds, defaulting to 2 (me: {})", delayToRespawn.count(), me->GetGUID().ToString());
641 delayToRespawn = 2s;
642 }
643
644 if (!who)
645 who = me;
646
647 if (TempSummon* whoSummon = who->ToTempSummon())
648 {
649 TC_LOG_WARN("scripts.ai", "BossAI::_DespawnAtEvade: called on a temporary summon (who: {})", who->GetGUID().ToString());
650 whoSummon->UnSummon();
651 return;
652 }
653
654 who->DespawnOrUnsummon(0s, delayToRespawn);
655
656 if (instance && who == me)
658}
659
660// WorldBossAI - for non-instanced bosses
661WorldBossAI::WorldBossAI(Creature* creature) : ScriptedAI(creature), summons(creature) { }
662
664{
665 if (!me->IsAlive())
666 return;
667
668 events.Reset();
670}
671
673{
674 events.Reset();
676}
677
679{
680 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
681 if (target)
682 AttackStart(target);
683}
684
686{
687 summons.Summon(summon);
688 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
689 if (target)
690 summon->AI()->AttackStart(target);
691}
692
694{
695 summons.Despawn(summon);
696}
697
699{
700 if (!UpdateVictim())
701 return;
702
703 events.Update(diff);
704
706 return;
707
708 while (uint32 eventId = events.ExecuteEvent())
709 {
710 ExecuteEvent(eventId);
712 return;
713 }
714}
SelectEffect
SelectTargetType
AISpellInfoType * GetAISpellInfo(uint32 spellId, Difficulty difficulty)
Definition: CreatureAI.cpp:40
const uint32 MAX_CREATURE_SPELLS
Definition: CreatureData.h:419
DB2Storage< SoundKitEntry > sSoundKitStore("SoundKit.db2", &SoundKitLoadInfo::Instance)
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
@ IN_PROGRESS
@ FAIL
@ DONE
@ NOT_STARTED
#define TC_LOG_WARN(filterType__,...)
Definition: Log.h:162
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
@ MOTION_PRIORITY_NORMAL
TempSummonType
Definition: ObjectDefines.h:62
@ TELE_TO_NOT_LEAVE_COMBAT
Definition: Player.h:804
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
SpellSchoolMask
@ SPELL_SCHOOL_MASK_MAGIC
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
Definition: SpellDefines.h:266
@ TRIGGERED_NONE
Not triggered.
Definition: SpellDefines.h:246
#define sSpellMgr
Definition: SpellMgr.h:849
@ UNIT_STATE_CASTING
Definition: Unit.h:270
InstanceScript *const instance
void _JustReachedHome()
void _JustEngagedWith(Unit *who)
void TeleportCheaters()
void JustSummoned(Creature *summon) override
void _DespawnAtEvade(Seconds delayToRespawn=30s, Creature *who=nullptr)
bool CanAIAttack(Unit const *target) const override
uint32 const _bossId
virtual void UpdateAI(uint32 diff) override
virtual void ExecuteEvent(uint32)
TaskScheduler scheduler
SummonList summons
EventMap events
void SummonedCreatureDespawn(Creature *summon) override
BossAI(Creature *creature, uint32 bossId)
virtual void ScheduleTasks()
void _JustDied()
std::unordered_map< ObjectGuid, CombatReference * > const & GetPvECombatRefs() const
void DoZoneInCombat()
Definition: CreatureAI.h:161
virtual void EnterEvadeMode(EvadeReason why=EvadeReason::Other)
Definition: CreatureAI.cpp:219
bool IsInBoundary(Position const *who=nullptr) const
Definition: CreatureAI.cpp:426
bool UpdateVictim()
Definition: CreatureAI.cpp:245
void SetBoundary(CreatureBoundary const *boundary, bool negativeBoundaries=false)
Definition: CreatureAI.cpp:446
void AttackStart(Unit *victim) override
== Triggered Actions Requested ==================
Definition: CreatureAI.cpp:328
Creature *const me
Definition: CreatureAI.h:61
bool LoadCreaturesAddon()
Definition: Creature.cpp:2749
void SetCombatPulseDelay(uint32 delay)
Definition: Creature.h:345
bool IsTapListNotClearedOnEvade() const
Definition: Creature.h:285
int8 GetOriginalEquipmentId() const
Definition: Creature.h:240
void ResetLootMode()
Definition: Creature.h:300
void StartDefaultCombatMovement(Unit *victim, Optional< float > range={}, Optional< float > angle={})
Definition: Creature.cpp:2855
uint32 m_spells[MAX_CREATURE_SPELLS]
Definition: Creature.h:302
void SetLastDamagedTime(time_t val)
Definition: Creature.h:427
void LoadEquipment(int8 id=1, bool force=false)
Definition: Creature.cpp:1946
void DoNotReacquireSpellFocusTarget()
Definition: Creature.cpp:3545
bool IsEngaged() const override
Definition: Creature.cpp:3601
void ResetPlayerDamageReq()
Definition: Creature.h:400
void SetCannotReachTarget(bool cannotReach)
Definition: Creature.cpp:3303
void SetTappedBy(Unit const *unit, bool withGroup=true)
Definition: Creature.cpp:1339
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
Definition: Creature.cpp:2415
CreatureAI * AI() const
Definition: Creature.h:214
std::string GetDebugInfo() const override
Definition: Creature.cpp:3667
uint32 ExecuteEvent()
Definition: EventMap.cpp:73
void Update(uint32 time)
Definition: EventMap.h:56
void Reset()
Definition: EventMap.cpp:21
virtual bool SetBossState(uint32 id, EncounterState state)
CreatureBoundary const * GetBossBoundary(uint32 id) const
EncounterState GetBossState(uint32 id) const
virtual bool CheckRequiredBosses(uint32, Player const *=nullptr) const
Definition: Map.h:189
bool IsDungeon() const
Definition: Map.cpp:3238
bool IsNormal() const
Definition: Map.cpp:3266
bool IsLFR() const
Definition: Map.cpp:3253
bool IsMythicPlus() const
Definition: Map.cpp:3310
bool IsTimewalking() const
Definition: Map.cpp:3325
bool IsHeroicOrHigher() const
Definition: Map.cpp:3315
Difficulty GetDifficultyID() const
Definition: Map.h:324
bool IsHeroic() const
Definition: Map.cpp:3282
PlayerList const & GetPlayers() const
Definition: Map.h:367
bool IsMythic() const
Definition: Map.cpp:3303
std::string ToString() const
Definition: ObjectGuid.cpp:554
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
static void SetAlwaysVisible(WorldObject *object, bool apply, bool updateVisibility)
Optional< SpellPowerCost > CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition: SpellInfo.cpp:3870
uint32 const Id
Definition: SpellInfo.h:325
uint32 Mechanic
Definition: SpellInfo.h:329
uint32 SchoolMask
Definition: SpellInfo.h:413
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:2465
Creature * _me
bool HasEntry(uint32 entry) const
void Despawn(Creature const *summon)
void DespawnEntry(uint32 entry)
void RemoveNotExisting()
void Summon(Creature const *summon)
void DoZoneInCombat(uint32 entry=0)
GuidList StorageType
void DoActionImpl(int32 action, StorageType &summons, uint16 max)
StorageType _storage
TaskScheduler & CancelAll()
TaskScheduler & SetValidator(P &&predicate)
Sets a validator which is asked if tasks are allowed to be executed.
void ModifyThreatByPercent(Unit *target, int32 percent)
void ResetThreat(Unit *target)
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
float GetThreat(Unit const *who, bool includeOffline=false) const
virtual void DoAction(int32)
Definition: UnitAI.h:72
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition: UnitAI.cpp:79
Definition: Unit.h:627
bool HealthAbovePct(int32 pct) const
Definition: Unit.h:782
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition: Unit.cpp:5827
void SetVirtualItem(uint32 slot, uint32 itemId, uint16 appearanceModId=0, uint16 itemVisual=0)
Definition: Unit.cpp:13604
ThreatManager & GetThreatManager()
Definition: Unit.h:1063
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition: Unit.cpp:3059
bool IsAlive() const
Definition: Unit.h:1164
void StopMoving()
Definition: Unit.cpp:10049
bool IsSilenced(SpellSchoolMask schoolMask) const
Definition: Unit.h:1453
TempSummon * ToTempSummon()
Definition: Unit.h:1756
bool IsAIEnabled() const
Definition: Unit.h:658
bool HealthBelowPct(int32 pct) const
Definition: Unit.h:780
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:5670
void NearTeleportTo(Position const &pos, bool casting=false)
Definition: Unit.cpp:12327
Unit * GetVictim() const
Definition: Unit.h:715
int32 GetPower(Powers power) const
Definition: Unit.cpp:9401
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
bool IsControlledByPlayer() const
Definition: Unit.h:1193
CombatManager & GetCombatManager()
Definition: Unit.h:1023
bool AttackStop()
Definition: Unit.cpp:5781
bool IsInCombat() const
Definition: Unit.h:1043
void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath=false, bool forceDestination=false)
Definition: Unit.cpp:506
virtual void UpdateAI(uint32 diff) override
virtual void ExecuteEvent(uint32)
void JustSummoned(Creature *summon) override
WorldBossAI(Creature *creature)
SummonList summons
void SummonedCreatureDespawn(Creature *summon) override
constexpr uint32 GetMapId() const
Definition: Position.h:201
void PlayDirectSound(uint32 soundId, Player const *target=nullptr, uint32 broadcastTextId=0) const
Definition: Object.cpp:3592
Map * GetMap() const
Definition: Object.h:624
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition: Object.cpp:2025
void setActive(bool isActiveObject)
Definition: Object.cpp:922
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition: Object.cpp:1147
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Object.cpp:2319
float GetDistance(WorldObject const *obj) const
Definition: Object.cpp:1078
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition: Object.cpp:2305
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void RandomResize(C &container, std::size_t requestedSize)
Definition: Containers.h:67
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:203
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:179
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition: CellImpl.h:191
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr void Relocate(float x, float y)
Definition: Position.h:63
constexpr float GetPositionZ() const
Definition: Position.h:78
bool IsHeroic() const
bool IsNormal() const
void DoStartNoMovement(Unit *target)
bool IsMythic() const
void SetEquipmentSlots(bool loadDefault, int32 mainHand=EQUIP_NO_CHANGE, int32 offHand=EQUIP_NO_CHANGE, int32 ranged=EQUIP_NO_CHANGE)
void ForceCombatStop(Creature *who, bool reset=true)
void AttackStart(Unit *) override
== Triggered Actions Requested ==================
void SetCombatMovement(bool allowMovement)
bool IsCombatMovementAllowed() const
bool HealthAbovePct(uint32 pct) const
Unit * DoSelectLowestHpFriendly(float range, uint32 minHPDiff=1)
bool IsTimewalking() const
Difficulty _difficulty
void DoTeleportTo(float x, float y, float z, uint32 time=0)
float GetThreat(Unit const *victim, Unit const *who=nullptr)
Player * GetPlayerAtMinimumRange(float minRange)
bool IsLFR() const
bool _isCombatMovementAllowed
bool IsMythicPlus() const
void DoTeleportPlayer(Unit *unit, float x, float y, float z, float o)
void DoTeleportAll(float x, float y, float z, float o)
bool HealthBelowPct(uint32 pct) const
SpellInfo const * SelectSpell(Unit *target, uint32 school, uint32 mechanic, SelectTargetType targets, float rangeMin, float rangeMax, SelectEffect effect)
void DoCastSpell(Unit *target, SpellInfo const *spellInfo, bool triggered=false)
void ModifyThreatByPercent(Unit *victim, int32 pct, Unit *who=nullptr)
void AttackStartNoMove(Unit *target)
Creature * DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, Milliseconds despawntime)
std::list< Creature * > DoFindFriendlyMissingBuff(float range, uint32 spellId)
void ResetThreat(Unit *victim, Unit *who=nullptr)
bool IsHeroicOrHigher() const
void ForceCombatStopForCreatureEntry(uint32 entry, float maxSearchRange=250.0f, bool samePhase=true, bool reset=true)
std::list< Creature * > DoFindFriendlyCC(float range)
ScriptedAI(Creature *creature)
Unit * DoSelectBelowHpPctFriendlyWithEntry(uint32 entry, float range, uint8 hpPct=1, bool excludeSelf=true)
void ResetThreatList(Unit *who=nullptr)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void AddThreat(Unit *victim, float amount, Unit *who=nullptr)
void DoStartMovement(Unit *target, float distance=0.0f, float angle=0.0f)
virtual void UpdateAI(uint32 diff) override