TrinityCore
Loading...
Searching...
No Matches
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 "Cell.h"
21#include "CellImpl.h"
22#include "Containers.h"
23#include "CommonHelpers.h"
24#include "DBCStores.h"
25#include "GridNotifiers.h"
26#include "GridNotifiersImpl.h"
27#include "InstanceScript.h"
28#include "Log.h"
29#include "MotionMaster.h"
30#include "ObjectAccessor.h"
31#include "Spell.h"
32#include "SpellMgr.h"
33#include "TemporarySummon.h"
34
35// Spell summary for ScriptedAI::SelectSpell
37{
38 uint8 Targets; // set of enum SelectTarget
39 uint8 Effects; // set of enum SelectEffect
40};
41
43
44void SummonList::Summon(Creature const* summon)
45{
46 _storage.push_back(summon->GetGUID());
47}
48
49void SummonList::Despawn(Creature const* summon)
50{
51 _storage.remove(summon->GetGUID());
52}
53
55{
56 for (StorageType::iterator i = _storage.begin(); i != _storage.end();)
57 {
59 ++i;
60 if (summon && summon->IsAIEnabled()
61 && (!entry || summon->GetEntry() == entry))
62 {
63 summon->AI()->DoZoneInCombat(nullptr);
64 }
65 }
66}
67
69{
70 for (StorageType::iterator i = _storage.begin(); i != _storage.end();)
71 {
73 if (!summon)
74 i = _storage.erase(i);
75 else if (summon->GetEntry() == entry)
76 {
77 i = _storage.erase(i);
78 summon->DespawnOrUnsummon();
79 }
80 else
81 ++i;
82 }
83}
84
86{
87 while (!_storage.empty())
88 {
90 _storage.pop_front();
91 if (summon)
92 summon->DespawnOrUnsummon();
93 }
94}
95
97{
98 for (StorageType::iterator i = _storage.begin(); i != _storage.end();)
99 {
101 ++i;
102 else
103 i = _storage.erase(i);
104 }
105}
106
108{
109 for (ObjectGuid const& guid : _storage)
110 {
111 Creature* summon = ObjectAccessor::GetCreature(*_me, guid);
112 if (summon && summon->GetEntry() == entry)
113 return true;
114 }
115
116 return false;
117}
118
120{
121 if (max)
123
124 for (ObjectGuid const& guid : summons)
125 {
126 Creature* summon = ObjectAccessor::GetCreature(*_me, guid);
127 if (summon && summon->IsAIEnabled())
128 summon->AI()->DoAction(action);
129 }
130}
131
132ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature), IsFleeing(false), _isCombatMovementAllowed(true)
133{
137
139{
140 if (!who)
141 return;
142
143 if (me->Attack(who, true))
145}
146
148{
151 else
153}
154
156{
157 // Check if we have a current target
158 if (!UpdateVictim())
159 return;
160
162}
163
164void ScriptedAI::DoStartMovement(Unit* victim, float distance, float angle)
165{
166 if (victim)
167 me->GetMotionMaster()->MoveChase(victim, distance, angle);
168}
169
171{
172 if (!victim)
173 return;
174
176}
177
179{
180 if (me->GetVictim())
181 me->AttackStop();
182}
183
184void ScriptedAI::DoCastSpell(Unit* target, SpellInfo const* spellInfo, bool triggered)
185{
186 if (!target || me->IsNonMeleeSpellCast(false))
187 return;
188
189 me->StopMoving();
190 me->CastSpell(target, spellInfo->Id, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
191}
192
194{
195 if (!source)
196 return;
197
198 if (!sSoundEntriesStore.LookupEntry(soundId))
199 {
200 TC_LOG_ERROR("scripts.ai", "ScriptedAI::DoPlaySoundToSet: Invalid soundId {} used in DoPlaySoundToSet (Source: {})", soundId, source->GetGUID().ToString());
201 return;
202 }
203
204 source->PlayDirectSound(soundId);
205}
206
207void ScriptedAI::AddThreat(Unit* victim, float amount, Unit* who)
208{
209 if (!victim)
210 return;
211 if (!who)
212 who = me;
213 who->GetThreatManager().AddThreat(victim, amount, nullptr, true, true);
214}
215
217{
218 if (!victim)
219 return;
220 if (!who)
221 who = me;
222 who->GetThreatManager().ModifyThreatByPercent(victim, pct);
223}
224
226{
227 if (!victim)
228 return;
229 if (!who)
230 who = me;
231 who->GetThreatManager().ResetThreat(victim);
232}
233
235{
236 if (!who)
237 who = me;
239}
240
241float ScriptedAI::GetThreat(Unit const* victim, Unit const* who)
242{
243 if (!victim)
244 return 0.0f;
245 if (!who)
246 who = me;
247 return who->GetThreatManager().GetThreat(victim);
248}
249
250void ScriptedAI::ForceCombatStop(Creature* who, bool reset /*= true*/)
251{
252 if (!who || !who->IsInCombat())
253 return;
254
255 who->CombatStop(true);
258
259 if (reset) {
260 who->LoadCreaturesAddon();
261 who->SetLootRecipient(nullptr);
263 who->SetLastDamagedTime(0);
264 who->SetCannotReachTarget(false);
265 }
266}
267
268void ScriptedAI::ForceCombatStopForCreatureEntry(uint32 entry, float maxSearchRange /*= 250.0f*/, bool samePhase /*= true*/, bool reset /*= true*/)
269{
270 TC_LOG_DEBUG("scripts.ai", "ScriptedAI::ForceCombatStopForCreatureEntry: called on '{}'. Debug info: {}", me->GetGUID().ToString(), me->GetDebugInfo());
271
272 std::list<Creature*> creatures;
273 Trinity::AllCreaturesOfEntryInRange check(me, entry, maxSearchRange);
275
276 if (!samePhase)
278
279 Cell::VisitGridObjects(me, searcher, maxSearchRange);
280
281 for (Creature* creature : creatures)
282 ForceCombatStop(creature, reset);
283}
284
285void ScriptedAI::ForceCombatStopForCreatureEntry(std::vector<uint32> creatureEntries, float maxSearchRange /*= 250.0f*/, bool samePhase /*= true*/, bool reset /*= true*/)
286{
287 for (uint32 const entry : creatureEntries)
288 ForceCombatStopForCreatureEntry(entry, maxSearchRange, samePhase, reset);
289}
290
291Creature* ScriptedAI::DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, Milliseconds despawntime)
292{
293 return me->SummonCreature(entry, me->GetPositionX() + offsetX, me->GetPositionY() + offsetY, me->GetPositionZ() + offsetZ, angle, TempSummonType(type), despawntime);
294}
295
297{
298 return me->HealthBelowPct(pct);
299}
300
302{
303 return me->HealthAbovePct(pct);
304}
305
306SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect effects)
307{
308 // No target so we can't cast
309 if (!target)
310 return nullptr;
311
312 // Silenced so we can't cast
314 return nullptr;
315
316 // Using the extended script system we first create a list of viable spells
317 SpellInfo const* apSpell[MAX_CREATURE_SPELLS];
318 memset(apSpell, 0, MAX_CREATURE_SPELLS * sizeof(SpellInfo*));
319
320 uint32 spellCount = 0;
321
322 SpellInfo const* tempSpell = nullptr;
323
324 // Check if each spell is viable(set it to null if not)
325 for (uint32 spell : me->m_spells)
326 {
327 tempSpell = sSpellMgr->GetSpellInfo(spell);
328
329 // This spell doesn't exist
330 if (!tempSpell)
331 continue;
332
333 // Targets and Effects checked first as most used restrictions
334 // Check the spell targets if specified
335 if (targets && !(SpellSummary[spell].Targets & (1 << (targets-1))))
336 continue;
337
338 // Check the type of spell if we are looking for a specific spell type
339 if (effects && !(SpellSummary[spell].Effects & (1 << (effects-1))))
340 continue;
341
342 // Check for school if specified
343 if (school && (tempSpell->SchoolMask & school) == 0)
344 continue;
345
346 // Check for spell mechanic if specified
347 if (mechanic && tempSpell->Mechanic != mechanic)
348 continue;
349
350 // Make sure that the spell uses the requested amount of power
351 if (powerCostMin && tempSpell->ManaCost < powerCostMin)
352 continue;
353
354 if (powerCostMax && tempSpell->ManaCost > powerCostMax)
355 continue;
356
357 // Continue if we don't have the mana to actually cast this spell
358 if (tempSpell->ManaCost > me->GetPower(tempSpell->PowerType))
359 continue;
360
361 // Check if the spell meets our range requirements
362 if (rangeMin && me->GetSpellMinRangeForTarget(target, tempSpell) < rangeMin)
363 continue;
364 if (rangeMax && me->GetSpellMaxRangeForTarget(target, tempSpell) > rangeMax)
365 continue;
366
367 // Check if our target is in range
368 if (me->IsWithinDistInMap(target, float(me->GetSpellMinRangeForTarget(target, tempSpell))) || !me->IsWithinDistInMap(target, float(me->GetSpellMaxRangeForTarget(target, tempSpell))))
369 continue;
370
371 // All good so lets add it to the spell list
372 apSpell[spellCount] = tempSpell;
373 ++spellCount;
374 }
375
376 // We got our usable spells so now lets randomly pick one
377 if (!spellCount)
378 return nullptr;
379
380 return apSpell[urand(0, spellCount - 1)];
381}
382
383void ScriptedAI::DoTeleportTo(float x, float y, float z, uint32 time)
384{
385 me->Relocate(x, y, z);
386 float speed = me->GetDistance(x, y, z) / ((float)time * 0.001f);
387 me->MonsterMoveWithSpeed(x, y, z, speed);
388}
389
390void ScriptedAI::DoTeleportTo(const float position[4])
391{
392 me->NearTeleportTo(position[0], position[1], position[2], position[3]);
393}
394
395void ScriptedAI::DoTeleportPlayer(Unit* unit, float x, float y, float z, float o)
396{
397 if (!unit)
398 return;
399
400 if (Player* player = unit->ToPlayer())
401 player->TeleportTo(unit->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT);
402 else
403 TC_LOG_ERROR("scripts.ai", "ScriptedAI::DoTeleportPlayer: Creature {} Tried to teleport non-player unit ({}) to x: {} y:{} z: {} o: {}. Aborted.",
404 me->GetGUID().ToString(), unit->GetGUID().ToString(), x, y, z, o);
405}
406
407void ScriptedAI::DoTeleportAll(float x, float y, float z, float o)
408{
409 Map* map = me->GetMap();
410 if (!map->IsDungeon())
411 return;
412
413 for (MapReference const& mapref : map->GetPlayers())
414 if (Player* player = mapref.GetSource())
415 if (player->IsAlive())
416 player->TeleportTo(me->GetMapId(), x, y, z, o, TELE_TO_NOT_LEAVE_COMBAT);
417}
418
420{
421 Unit* unit = nullptr;
422 Trinity::MostHPMissingInRange u_check(me, range, minHPDiff);
424 Cell::VisitAllObjects(me, searcher, range);
425
426 return unit;
427}
428
429Unit* ScriptedAI::DoSelectBelowHpPctFriendlyWithEntry(uint32 entry, float range, uint8 minHPDiff, bool excludeSelf)
430{
431 Unit* unit = nullptr;
432 Trinity::FriendlyBelowHpPctEntryInRange u_check(me, entry, range, minHPDiff, excludeSelf);
434 Cell::VisitAllObjects(me, searcher, range);
435
436 return unit;
437}
438
439std::list<Creature*> ScriptedAI::DoFindFriendlyCC(float range)
440{
441 std::list<Creature*> list;
442 Trinity::FriendlyCCedInRange u_check(me, range);
444 Cell::VisitAllObjects(me, searcher, range);
445
446 return list;
447}
448
449std::list<Creature*> ScriptedAI::DoFindFriendlyMissingBuff(float range, uint32 uiSpellid)
450{
451 std::list<Creature*> list;
452 Trinity::FriendlyMissingBuffInRange u_check(me, range, uiSpellid);
454 Cell::VisitAllObjects(me, searcher, range);
455
456 return list;
457}
458
460{
461 Player* player = nullptr;
462
463 Trinity::PlayerAtMinimumRangeAway check(me, minimumRange);
465 Cell::VisitWorldObjects(me, searcher, minimumRange);
466
467 return player;
468}
469
470void ScriptedAI::SetEquipmentSlots(bool loadDefault, int32 mainHand /*= EQUIP_NO_CHANGE*/, int32 offHand /*= EQUIP_NO_CHANGE*/, int32 ranged /*= EQUIP_NO_CHANGE*/)
471{
472 if (loadDefault)
473 {
475 return;
476 }
477
478 if (mainHand >= 0)
479 me->SetVirtualItem(0, uint32(mainHand));
480
481 if (offHand >= 0)
482 me->SetVirtualItem(1, uint32(offHand));
483
484 if (ranged >= 0)
485 me->SetVirtualItem(2, uint32(ranged));
486}
487
488void ScriptedAI::SetCombatMovement(bool allowMovement)
489{
490 _isCombatMovementAllowed = allowMovement;
491}
492
493void ScriptedAI::SetAggressiveStateAfter(Milliseconds timer, Creature* who/* = nullptr*/, bool startCombat/* = true*/, Creature* summoner/* = nullptr*/, StartCombatArgs const& combatArgs/* = { }*/)
494{
495 if (!who)
496 who = me;
497 who->m_Events.AddEvent(new Trinity::Helpers::Events::SetAggresiveStateEvent(who, startCombat, summoner ? summoner->GetGUID() : ObjectGuid::Empty, combatArgs), who->m_Events.CalculateTime(timer));
498}
499
500void ScriptedAI::DoAddEvent(Milliseconds timer, BasicEvent* event, WorldObject* who/* = nullptr*/)
501{
502 if (!who)
503 who = me;
504 who->m_Events.AddEvent(event, who->m_Events.CalculateTime(timer));
505}
506
507// BossAI - for instanced bosses
508BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature), instance(creature->GetInstanceScript()), summons(creature), _bossId(bossId)
509{
510 if (instance)
513 {
515 });
516}
517
519{
520 if (!me->IsAlive())
521 return;
522
524 me->ResetLootMode();
525 events.Reset();
530}
531
540
542{
543 me->setActive(false);
544}
545
547{
548 if (instance)
549 {
550 // bosses do not respawn, check only on enter combat
552 {
554 return;
555 }
557 }
558
560 me->setActive(true);
563}
564
566{
567 float x, y, z;
568 me->GetPosition(x, y, z);
569
570 for (auto const& pair : me->GetCombatManager().GetPvECombatRefs())
571 {
572 Unit* target = pair.second->GetOther(me);
573 if (target->IsControlledByPlayer() && !IsInBoundary(target))
574 target->NearTeleportTo(x, y, z, 0);
575 }
576}
577
579{
580 summons.Summon(summon);
581 if (me->IsEngaged())
582 DoZoneInCombat(summon);
583}
584
586{
587 summons.Despawn(summon);
588}
589
591{
592 if (!UpdateVictim())
593 return;
594
595 events.Update(diff);
596
598 return;
599
600 while (uint32 eventId = events.ExecuteEvent())
601 {
602 ExecuteEvent(eventId);
604 return;
605 }
606
608}
609
610bool BossAI::CanAIAttack(Unit const* target) const
611{
612 return IsInBoundary(target);
613}
614
615void BossAI::_DespawnAtEvade(Seconds delayToRespawn /*= 30s*/, Creature* who /*= nullptr*/)
616{
617 if (delayToRespawn < 2s)
618 {
619 TC_LOG_ERROR("scripts.ai", "BossAI::_DespawnAtEvade: called with delay of {} seconds, defaulting to 2 (me: {})", delayToRespawn.count(), me->GetGUID().ToString());
620 delayToRespawn = 2s;
621 }
622
623 if (!who)
624 who = me;
625
626 if (TempSummon* whoSummon = who->ToTempSummon())
627 {
628 TC_LOG_WARN("scripts.ai", "BossAI::_DespawnAtEvade: called on a temporary summon (who: {})", who->GetGUID().ToString());
629 whoSummon->UnSummon();
630 return;
631 }
632
633 who->DespawnOrUnsummon(0s, delayToRespawn);
634
635 if (instance && who == me)
637}
638
639// WorldBossAI - for non-instanced bosses
640WorldBossAI::WorldBossAI(Creature* creature) : ScriptedAI(creature), summons(creature) { }
641
643{
644 if (!me->IsAlive())
645 return;
646
647 events.Reset();
649}
650
652{
653 events.Reset();
655}
656
658{
659 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
660 if (target)
661 AttackStart(target);
662}
663
665{
666 summons.Summon(summon);
667 Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
668 if (target)
669 summon->AI()->AttackStart(target);
670}
671
676
678{
679 if (!UpdateVictim())
680 return;
681
682 events.Update(diff);
683
685 return;
686
687 while (uint32 eventId = events.ExecuteEvent())
688 {
689 ExecuteEvent(eventId);
691 return;
692 }
693
695}
SelectTargetType
Definition CreatureAI.h:53
SelectEffect
Definition CreatureAI.h:66
static const uint32 MAX_CREATURE_SPELLS
Difficulty
Definition DBCEnums.h:279
DBCStorage< SoundEntriesEntry > sSoundEntriesStore(SoundEntriesfmt)
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
@ 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
@ PHASEMASK_ANYWHERE
TempSummonType
@ TELE_TO_NOT_LEAVE_COMBAT
Definition Player.h:681
uint32 urand(uint32 min, uint32 max)
Definition Random.cpp:42
TSpellSummary * SpellSummary
Targets
@ TRIGGERED_FULL_MASK
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_NONE
#define sSpellMgr
Definition SpellMgr.h:738
@ UNIT_FLAG_SILENCED
@ UNIT_STATE_CASTING
Definition Unit.h:235
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()
std::unordered_map< ObjectGuid, CombatReference * > const & GetPvECombatRefs() const
@ EVADE_REASON_SEQUENCE_BREAK
Definition CreatureAI.h:97
void DoZoneInCombat(Creature *creature=nullptr)
bool IsInBoundary(Position const *who=nullptr) const
bool UpdateVictim()
void SetBoundary(CreatureBoundary const *boundary, bool negativeBoundaries=false)
Creature *const me
Definition CreatureAI.h:82
virtual void EnterEvadeMode(EvadeReason why=EVADE_REASON_OTHER)
bool LoadCreaturesAddon()
void SetCombatPulseDelay(uint32 delay)
Definition Creature.h:269
int8 GetOriginalEquipmentId() const
Definition Creature.h:176
void ResetLootMode()
Definition Creature.h:227
uint32 m_spells[MAX_CREATURE_SPELLS]
Definition Creature.h:229
void SetLootRecipient(Unit *unit, bool withGroup=true)
void SetLastDamagedTime(time_t val)
Definition Creature.h:350
void LoadEquipment(int8 id=1, bool force=false)
void DoNotReacquireSpellFocusTarget()
bool IsEngaged() const override
void ResetPlayerDamageReq()
Definition Creature.h:323
void SetCannotReachTarget(bool cannotReach)
void DespawnOrUnsummon(Milliseconds timeToDespawn=0s, Seconds forceRespawnTime=0s)
CreatureAI * AI() const
Definition Creature.h:154
std::string GetDebugInfo() const override
void Update(uint32 time)
Definition EventMap.h:67
EventId ExecuteEvent()
Definition EventMap.cpp:73
void Reset()
Definition EventMap.cpp:21
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
Milliseconds CalculateTime(Milliseconds t_offset) const
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:281
bool IsDungeon() const
Definition Map.cpp:4236
uint8 GetSpawnMode() const
Definition Map.h:388
bool IsHeroic() const
Definition Map.cpp:4256
PlayerList const & GetPlayers() const
Definition Map.h:448
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
static ObjectGuid const Empty
Definition ObjectGuid.h:140
std::string ToString() const
uint32 GetEntry() const
Definition Object.h:81
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
static Player * ToPlayer(Object *o)
Definition Object.h:180
uint32 Mechanic
Definition SpellInfo.h:292
uint32 Id
Definition SpellInfo.h:289
Powers PowerType
Definition SpellInfo.h:331
uint32 SchoolMask
Definition SpellInfo.h:361
uint32 ManaCost
Definition SpellInfo.h:332
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:154
void DoMeleeAttackIfReady()
Definition UnitAI.cpp:54
Unit * SelectTarget(SelectTargetMethod targetType, uint32 offset=0, float dist=0.0f, bool playerOnly=false, bool withTank=true, int32 aura=0)
Definition UnitAI.cpp:96
virtual void AttackStart(Unit *)
Definition UnitAI.cpp:30
Definition Unit.h:769
bool HealthAbovePct(int32 pct) const
Definition Unit.h:919
ThreatManager & GetThreatManager()
Definition Unit.h:1155
void StopMoving(bool force=false)
Definition Unit.cpp:10312
MotionMaster * GetMotionMaster()
Definition Unit.h:1667
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:953
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:3063
bool IsAlive() const
Definition Unit.h:1234
TempSummon * ToTempSummon()
Definition Unit.h:1794
void SetVirtualItem(uint32 slot, uint32 itemId)
Definition Unit.cpp:13868
bool IsAIEnabled() const
Definition Unit.h:798
bool HealthBelowPct(int32 pct) const
Definition Unit.h:917
bool Attack(Unit *victim, bool meleeAttack)
Definition Unit.cpp:5535
void NearTeleportTo(Position const &pos, bool casting=false)
Definition Unit.cpp:12832
Unit * GetVictim() const
Definition Unit.h:859
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
bool IsControlledByPlayer() const
Definition Unit.h:1258
uint32 GetPower(Powers power) const
Definition Unit.h:934
void CombatStop(bool includingCast=false, bool mutualPvP=true)
Definition Unit.cpp:5691
CombatManager & GetCombatManager()
Definition Unit.h:1130
bool AttackStop()
Definition Unit.cpp:5645
bool IsInCombat() const
Definition Unit.h:1144
void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath=false, bool forceDestination=false)
Definition Unit.cpp:518
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
uint32 GetMapId() const
Definition Position.h:193
Map * GetMap() const
Definition Object.h:449
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2832
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:1992
void setActive(bool isActiveObject)
Definition Object.cpp:991
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1192
EventProcessor m_Events
Definition Object.h:591
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Object.cpp:2267
void PlayDirectSound(uint32 soundId, Player *target=nullptr)
Definition Object.cpp:3433
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1123
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Object.cpp:2253
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:66
static void VisitAllObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:192
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:168
static void VisitWorldObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:180
float GetPositionZ() const
Definition Position.h:81
float GetPositionX() const
Definition Position.h:79
void GetPosition(float &x, float &y) const
Definition Position.h:84
float GetPositionY() const
Definition Position.h:80
void Relocate(float x, float y)
Definition Position.h:66
void DoStartNoMovement(Unit *target)
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
void SetCombatMovement(bool allowMovement)
bool IsCombatMovementAllowed() const
bool HealthAbovePct(uint32 pct) const
Unit * DoSelectLowestHpFriendly(float range, uint32 minHPDiff=1)
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 _isCombatMovementAllowed
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, uint32 powerCostMin, uint32 powerCostMax, 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)
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 DoAddEvent(Milliseconds timer, BasicEvent *event, WorldObject *who=nullptr)
void ResetThreatList(Unit *who=nullptr)
void DoPlaySoundToSet(WorldObject *source, uint32 soundId)
void SetAggressiveStateAfter(Milliseconds timer, Creature *who=nullptr, bool startCombat=true, Creature *summoner=nullptr, StartCombatArgs const &combatArgs={ })
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