TrinityCore
PetAI.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 "PetAI.h"
19#include "AIException.h"
20#include "CharmInfo.h"
21#include "Creature.h"
22#include "Errors.h"
23#include "Group.h"
24#include "Log.h"
25#include "Map.h"
26#include "MotionMaster.h"
27#include "ObjectAccessor.h"
28#include "Pet.h"
29#include "Player.h"
30#include "Spell.h"
31#include "SpellHistory.h"
32#include "SpellInfo.h"
33#include "SpellMgr.h"
34
36{
38 {
39 if (reinterpret_cast<Guardian const*>(creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
42 }
43
44 return PERMIT_BASE_NO;
45}
46
47PetAI::PetAI(Creature* creature, uint32 scriptId) : CreatureAI(creature, scriptId), _tracker(TIME_INTERVAL_LOOK)
48{
49 if (!me->GetCharmInfo())
50 throw InvalidAIException("Creature doesn't have a valid charm info");
51
53}
54
56{
57 if (!me->IsAlive() || !me->GetCharmInfo())
58 return;
59
60 Unit* owner = me->GetCharmerOrOwner();
61
62 if (_updateAlliesTimer <= diff)
63 // UpdateAllies self set update timer
65 else
66 _updateAlliesTimer -= diff;
67
68 if (me->GetVictim() && me->EnsureVictim()->IsAlive())
69 {
70 // is only necessary to stop casting, the pet must not exit combat
71 if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL) && // ignore channeled spells (Pin, Seduction)
73 {
75 return;
76 }
77
78 if (NeedToStop())
79 {
80 TC_LOG_TRACE("scripts.ai.petai", "PetAI::UpdateAI: AI stopped attacking {}", me->GetGUID().ToString());
81 StopAttack();
82 return;
83 }
84 }
85 else
86 {
88 {
89 // Every update we need to check targets only in certain cases
90 // Aggressive - Allow auto select if owner or pet don't have a target
91 // Stay - Only pick from pet or owner targets / attackers so targets won't run by
92 // while chasing our owner. Don't do auto select.
93 // All other cases (ie: defensive) - Targets are assigned by DamageTaken(), OwnerAttackedBy(), OwnerAttacked(), etc.
95
96 if (nextTarget)
97 AttackStart(nextTarget);
98 else
100 }
101 else
103 }
104
105 // Autocast (cast only in combat or persistent spells in any state)
107 {
108 TargetSpellList targetSpellStore;
109
110 for (uint8 i = 0; i < me->GetPetAutoSpellSize(); ++i)
111 {
112 uint32 spellID = me->GetPetAutoSpellOnPos(i);
113 if (!spellID)
114 continue;
115
116 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID, me->GetMap()->GetDifficultyID());
117 if (!spellInfo)
118 continue;
119
120 if (me->GetSpellHistory()->HasGlobalCooldown(spellInfo))
121 continue;
122
123 // check spell cooldown
124 if (!me->GetSpellHistory()->IsReady(spellInfo))
125 continue;
126
127 if (spellInfo->IsPositive())
128 {
129 if (spellInfo->CanBeUsedInCombat(me))
130 {
131 // Check if we're in combat or commanded to attack
132 if (!me->IsInCombat() && !me->GetCharmInfo()->IsCommandAttack())
133 continue;
134 }
135
136 Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE);
137 bool spellUsed = false;
138
139 // Some spells can target enemy or friendly (DK Ghoul's Leap)
140 // Check for enemy first (pet then owner)
141 Unit* target = me->getAttackerForHelper();
142 if (!target && owner)
143 target = owner->getAttackerForHelper();
144
145 if (target)
146 {
147 if (CanAttack(target) && spell->CanAutoCast(target))
148 {
149 targetSpellStore.push_back(std::make_pair(target, spell));
150 spellUsed = true;
151 }
152 }
153
154 if (spellInfo->HasEffect(SPELL_EFFECT_JUMP_DEST))
155 {
156 if (!spellUsed)
157 delete spell;
158 continue; // Pets must only jump to target
159 }
160
161 // No enemy, check friendly
162 if (!spellUsed)
163 {
164 for (ObjectGuid target : _allySet)
165 {
166 Unit* ally = ObjectAccessor::GetUnit(*me, target);
167
168 //only buff targets that are in combat, unless the spell can only be cast while out of combat
169 if (!ally)
170 continue;
171
172 if (spell->CanAutoCast(ally))
173 {
174 targetSpellStore.push_back(std::make_pair(ally, spell));
175 spellUsed = true;
176 break;
177 }
178 }
179 }
180
181 // No valid targets at all
182 if (!spellUsed)
183 delete spell;
184 }
185 else if (me->GetVictim() && CanAttack(me->GetVictim()) && spellInfo->CanBeUsedInCombat(me))
186 {
187 Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE);
188 if (spell->CanAutoCast(me->GetVictim()))
189 targetSpellStore.push_back(std::make_pair(me->GetVictim(), spell));
190 else
191 delete spell;
192 }
193 }
194
195 // found units to cast on to
196 if (!targetSpellStore.empty())
197 {
198 TargetSpellList::iterator it = targetSpellStore.begin();
199 std::advance(it, urand(0, targetSpellStore.size() - 1));
200
201 Spell* spell = (*it).second;
202 Unit* target = (*it).first;
203
204 targetSpellStore.erase(it);
205
206 SpellCastTargets targets;
207 targets.SetUnitTarget(target);
208
209 spell->prepare(targets);
210 }
211
212 // deleted cached Spell objects
213 for (std::pair<Unit*, Spell*> const& unitspellpair : targetSpellStore)
214 delete unitspellpair.second;
215 }
216
217 // Update speed as needed to prevent dropping too far behind and despawning
221
222}
223
225{
226 // Called from Unit::Kill() in case where pet or owner kills something
227 // if owner killed this victim, pet may still be attacking something else
228 if (me->GetVictim() && me->GetVictim() != victim)
229 return;
230
231 // Clear target just in case. May help problem where health / focus / mana
232 // regen gets stuck. Also resets attack command.
233 // Can't use StopAttack() because that activates movement handlers and ignores
234 // next target selection
235 me->AttackStop();
237
238 // Before returning to owner, see if there are more things to attack
239 if (Unit* nextTarget = SelectNextTarget(false))
240 AttackStart(nextTarget);
241 else
242 HandleReturnMovement(); // Return
243}
244
246{
247 // Overrides Unit::AttackStart to prevent pet from switching off its assigned target
248 if (!target || target == me)
249 return;
250
251 if (me->GetVictim() && me->EnsureVictim()->IsAlive())
252 return;
253
254 _AttackStart(target);
255}
256
258{
259 // Check all pet states to decide if we can attack this target
260 if (!CanAttack(target))
261 return;
262
263 // Only chase if not commanded to stay or if stay but commanded to attack
265}
266
268{
269 // Called when owner takes damage. This function helps keep pets from running off
270 // simply due to owner gaining aggro.
271
272 if (!attacker || !me->IsAlive())
273 return;
274
275 // Passive pets don't do anything
277 return;
278
279 // Prevent pet from disengaging from current target
280 if (me->GetVictim() && me->EnsureVictim()->IsAlive())
281 return;
282
283 // Continue to evaluate and attack if necessary
284 AttackStart(attacker);
285}
286
288{
289 // Called when owner attacks something. Allows defensive pets to know
290 // that they need to assist
291
292 // Target might be NULL if called from spell with invalid cast targets
293 if (!target || !me->IsAlive())
294 return;
295
296 // Passive pets don't do anything
298 return;
299
300 // Prevent pet from disengaging from current target
301 if (me->GetVictim() && me->EnsureVictim()->IsAlive())
302 return;
303
304 // Continue to evaluate and attack if necessary
305 AttackStart(target);
306}
307
308Unit* PetAI::SelectNextTarget(bool allowAutoSelect) const
309{
310 // Provides next target selection after current target death.
311 // This function should only be called internally by the AI
312 // Targets are not evaluated here for being valid targets, that is done in _CanAttack()
313 // The parameter: allowAutoSelect lets us disable aggressive pet auto targeting for certain situations
314
315 // Passive pets don't do next target selection
317 return nullptr;
318
319 // Check pet attackers first so we don't drag a bunch of targets to the owner
320 if (Unit* myAttacker = me->getAttackerForHelper())
321 if (!myAttacker->HasBreakableByDamageCrowdControlAura())
322 return myAttacker;
323
324 // Not sure why we wouldn't have an owner but just in case...
325 if (!me->GetCharmerOrOwner())
326 return nullptr;
327
328 // Check owner attackers
329 if (Unit* ownerAttacker = me->GetCharmerOrOwner()->getAttackerForHelper())
330 if (!ownerAttacker->HasBreakableByDamageCrowdControlAura())
331 return ownerAttacker;
332
333 // Check owner victim
334 // 3.0.2 - Pets now start attacking their owners victim in defensive mode as soon as the hunter does
335 if (Unit* ownerVictim = me->GetCharmerOrOwner()->GetVictim())
336 return ownerVictim;
337
338 // Neither pet or owner had a target and aggressive pets can pick any target
339 // To prevent aggressive pets from chain selecting targets and running off, we
340 // only select a random target if certain conditions are met.
341 if (me->HasReactState(REACT_AGGRESSIVE) && allowAutoSelect)
342 {
344 if (Unit* nearTarget = me->SelectNearestHostileUnitInAggroRange(true, true))
345 return nearTarget;
346 }
347
348 // Default - no valid targets
349 return nullptr;
350}
351
353{
354 // Handles moving the pet back to stay or owner
355
356 // Prevent activating movement when under control of spells
357 // such as "Eyes of the Beast"
358 if (me->IsCharmed())
359 return;
360
361 if (!me->GetCharmInfo())
362 {
363 TC_LOG_WARN("scripts.ai.petai", "me->GetCharmInfo() is NULL in PetAI::HandleReturnMovement(). Debug info: {}", GetDebugInfo());
364 return;
365 }
366
368 {
369 if (!me->GetCharmInfo()->IsAtStay() && !me->GetCharmInfo()->IsReturning())
370 {
371 // Return to previous position where stay was clicked
372 float x, y, z;
373
374 me->GetCharmInfo()->GetStayPosition(x, y, z);
377
380
381 me->GetMotionMaster()->MovePoint(me->GetGUID().GetCounter(), x, y, z);
382 }
383 }
384 else // COMMAND_FOLLOW
385 {
387 {
390
393
395 }
396 }
397 me->RemoveUnitFlag(UNIT_FLAG_PET_IN_COMBAT); // on player pets, this flag indicates that we're actively going after a target - we're returning, so remove it
398}
399
400void PetAI::DoAttack(Unit* target, bool chase)
401{
402 // Handles attack with or without chase and also resets flags
403 // for next update / creature kill
404
405 if (me->Attack(target, true))
406 {
407 me->SetUnitFlag(UNIT_FLAG_PET_IN_COMBAT); // on player pets, this flag indicates we're actively going after a target - that's what we're doing, so set it
408 // Play sound to let the player know the pet is attacking something it picked on its own
411
412 if (chase)
413 {
414 bool oldCmdAttack = me->GetCharmInfo()->IsCommandAttack(); // This needs to be reset after other flags are cleared
416 me->GetCharmInfo()->SetIsCommandAttack(oldCmdAttack); // For passive pets commanded to attack so they will use spells
417
420
421 // Pets with ranged attacks should not care about the chase angle at all.
422 float chaseDistance = me->GetPetChaseDistance();
423 float angle = chaseDistance == 0.f ? float(M_PI) : 0.f;
424 float tolerance = chaseDistance == 0.f ? float(M_PI_4) : float(M_PI * 2);
425 me->GetMotionMaster()->MoveChase(target, ChaseRange(0.f, chaseDistance), ChaseAngle(angle, tolerance));
426 }
427 else // (Stay && ((Aggressive || Defensive) && In Melee Range)))
428 {
430 me->GetCharmInfo()->SetIsAtStay(true);
431
434
436 }
437 }
438}
439
441{
442 // Receives notification when pet reaches stay or follow owner
443 switch (type)
444 {
446 {
447 // Pet is returning to where stay was clicked. data should be
448 // pet's GUIDLow since we set that as the waypoint ID
449 if (id == me->GetGUID().GetCounter() && me->GetCharmInfo()->IsReturning())
450 {
452 me->GetCharmInfo()->SetIsAtStay(true);
454 }
455 break;
456 }
458 {
459 // If data is owner's GUIDLow then we've reached follow point,
460 // otherwise we're probably chasing a creature
462 {
465 }
466 break;
467 }
468 default:
469 break;
470 }
471}
472
474{
475 // Evaluates wether a pet can attack a specific target based on CommandState, ReactState and other flags
476 // IMPORTANT: The order in which things are checked is important, be careful if you add or remove checks
477
478 // Hmmm...
479 if (!target)
480 return false;
481
482 if (!target->IsAlive())
483 {
484 // if target is invalid, pet should evade automaticly
485 // Clear target to prevent getting stuck on dead targets
486 //me->AttackStop();
487 //me->InterruptNonMeleeSpells(false);
488 return false;
489 }
490
491 if (!me->GetCharmInfo())
492 {
493 TC_LOG_WARN("scripts.ai.petai", "me->GetCharmInfo() is NULL in PetAI::CanAttack(). Debug info: {}", GetDebugInfo());
494 return false;
495 }
496
497 // Passive - passive pets can attack if told to
499 return me->GetCharmInfo()->IsCommandAttack();
500
501 // CC - mobs under crowd control can be attacked if owner commanded
503 return me->GetCharmInfo()->IsCommandAttack();
504
505 // Returning - pets ignore attacks only if owner clicked follow
506 if (me->GetCharmInfo()->IsReturning())
507 return !me->GetCharmInfo()->IsCommandFollow();
508
509 // Stay - can attack if target is within range or commanded to
511 return (me->IsWithinMeleeRange(target) || me->GetCharmInfo()->IsCommandAttack());
512
513 // Pets attacking something (or chasing) should only switch targets if owner tells them to
514 if (me->GetVictim() && me->GetVictim() != target)
515 {
516 // Check if our owner selected this target and clicked "attack"
517 Unit* ownerTarget = nullptr;
518 if (Player* owner = me->GetCharmerOrOwner()->ToPlayer())
519 ownerTarget = owner->GetSelectedUnit();
520 else
521 ownerTarget = me->GetCharmerOrOwner()->GetVictim();
522
523 if (ownerTarget && me->GetCharmInfo()->IsCommandAttack())
524 return (target->GetGUID() == ownerTarget->GetGUID());
525 }
526
527 // Follow
529 return !me->GetCharmInfo()->IsReturning();
530
531 // default, though we shouldn't ever get here
532 return false;
533}
534
536{
537 if (me->GetOwnerGUID() != player->GetGUID())
538 return;
539
540 switch (emote)
541 {
542 case TEXT_EMOTE_COWER:
543 if (me->IsPet() && me->ToPet()->IsPetGhoul())
544 me->HandleEmoteCommand(/*EMOTE_ONESHOT_ROAR*/EMOTE_ONESHOT_OMNICAST_GHOUL);
545 break;
546 case TEXT_EMOTE_ANGRY:
547 if (me->IsPet() && me->ToPet()->IsPetGhoul())
548 me->HandleEmoteCommand(/*EMOTE_ONESHOT_COWER*/EMOTE_STATE_STUN);
549 break;
550 case TEXT_EMOTE_GLARE:
551 if (me->IsPet() && me->ToPet()->IsPetGhoul())
553 break;
555 if (me->IsPet() && me->ToPet()->IsPetGhoul())
557 break;
558 }
559}
560
562{
563 // This is needed for charmed creatures, as once their target was reset other effects can trigger threat
564 if (me->IsCharmed() && me->GetVictim() == me->GetCharmer())
565 return true;
566
567 // dont allow pets to follow targets far away from owner
568 if (Unit* owner = me->GetCharmerOrOwner())
569 if (owner->GetExactDist(me) >= (owner->GetVisibilityRange() - 10.0f))
570 return true;
571
572 return !me->IsValidAttackTarget(me->GetVictim());
573}
574
576{
577 if (!me->IsAlive())
578 {
581 me->CombatStop();
582 return;
583 }
584
585 me->AttackStop();
590}
591
593{
594 _updateAlliesTimer = 10 * IN_MILLISECONDS; // update friendly targets every 10 seconds, lesser checks increase performance
595
596 Unit* owner = me->GetCharmerOrOwner();
597 if (!owner)
598 return;
599
600 Group* group = nullptr;
601 if (Player* player = owner->ToPlayer())
602 group = player->GetGroup();
603
604 // only pet and owner/not in group->ok
605 if (_allySet.size() == 2 && !group)
606 return;
607
608 // owner is in group; group members filled in already (no raid -> subgroupcount = whole count)
609 if (group && !group->isRaidGroup() && _allySet.size() == (group->GetMembersCount() + 2))
610 return;
611
612 _allySet.clear();
613 _allySet.insert(me->GetGUID());
614 if (group) // add group
615 {
616 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
617 {
618 Player* Target = itr->GetSource();
619 if (!Target || !Target->IsInMap(owner) || !group->SameSubGroup(owner->ToPlayer(), Target))
620 continue;
621
622 if (Target->GetGUID() == owner->GetGUID())
623 continue;
624
625 _allySet.insert(Target->GetGUID());
626 }
627 }
628 else // remove group
629 _allySet.insert(owner->GetGUID());
630}
631
632void PetAI::OnCharmed(bool isNew)
633{
634 if (!me->isPossessedByPlayer() && me->IsCharmed())
636
638}
639
641{
642 CharmInfo* ci = me->GetCharmInfo();
643 if (ci)
644 {
645 ci->SetIsAtStay(false);
646 ci->SetIsCommandAttack(false);
647 ci->SetIsCommandFollow(false);
648 ci->SetIsFollowing(false);
649 ci->SetIsReturning(false);
650 }
651}
@ IN_MILLISECONDS
Definition: Common.h:35
#define M_PI
Definition: Common.h:115
#define M_PI_4
Definition: Common.h:119
#define TIME_INTERVAL_LOOK
Definition: CreatureAI.h:39
@ PERMIT_BASE_PROACTIVE
Definition: CreatureAI.h:47
@ PERMIT_BASE_NO
Definition: CreatureAI.h:44
@ PERMIT_BASE_REACTIVE
Definition: CreatureAI.h:46
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_WARN(filterType__,...)
Definition: Log.h:162
#define TC_LOG_TRACE(filterType__,...)
Definition: Log.h:153
@ CHASE_MOTION_TYPE
@ POINT_MOTION_TYPE
@ FOLLOW_MOTION_TYPE
@ TYPEID_PLAYER
Definition: ObjectGuid.h:41
std::vector< std::pair< Unit *, Spell * > > TargetSpellList
Definition: PetAI.h:27
#define PET_FOLLOW_DIST
Definition: PetDefines.h:97
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
@ EMOTE_ONESHOT_OMNICAST_GHOUL
@ EMOTE_STATE_STUN
@ TEXT_EMOTE_ANGRY
@ TEXT_EMOTE_SOOTHE
@ TEXT_EMOTE_COWER
@ TEXT_EMOTE_GLARE
@ SPELL_EFFECT_JUMP_DEST
@ TRIGGERED_NONE
Not triggered.
Definition: SpellDefines.h:246
#define sSpellMgr
Definition: SpellMgr.h:849
@ MOVE_FLIGHT
Definition: UnitDefines.h:123
@ MOVE_RUN
Definition: UnitDefines.h:118
@ MOVE_WALK
Definition: UnitDefines.h:117
@ REACT_PASSIVE
Definition: UnitDefines.h:506
@ REACT_AGGRESSIVE
Definition: UnitDefines.h:508
@ COMMAND_STAY
Definition: UnitDefines.h:526
@ COMMAND_FOLLOW
Definition: UnitDefines.h:527
@ UNIT_FLAG_PET_IN_COMBAT
Definition: UnitDefines.h:155
@ UNIT_MASK_CONTROLABLE_GUARDIAN
Definition: Unit.h:358
@ CURRENT_CHANNELED_SPELL
Definition: Unit.h:591
@ UNIT_STATE_CHASE
Definition: Unit.h:260
@ UNIT_STATE_FOLLOW
Definition: Unit.h:264
@ UNIT_STATE_CASTING
Definition: Unit.h:270
void OnCharmed(bool isNew) override
Definition: CreatureAI.cpp:62
Creature *const me
Definition: CreatureAI.h:61
bool HasReactState(ReactStates state) const
Definition: Creature.h:162
Unit * SelectNearestHostileUnitInAggroRange(bool useLOS=false, bool ignoreCivilians=false) const
Definition: Creature.cpp:3371
float GetPetChaseDistance() const
Definition: Creature.cpp:3283
virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const
Definition: Creature.cpp:3275
virtual uint8 GetPetAutoSpellSize() const
Definition: Creature.cpp:3270
GroupReference * next()
Definition: Group.h:197
uint32 GetMembersCount() const
Definition: Group.h:327
GroupReference * GetFirstMember()
Definition: Group.h:325
bool SameSubGroup(ObjectGuid guid1, ObjectGuid guid2) const
Definition: Group.cpp:1721
bool isRaidGroup() const
Definition: Group.cpp:1638
Difficulty GetDifficultyID() const
Definition: Map.h:324
bool IsPetGhoul() const
void MoveChase(Unit *target, Optional< ChaseRange > dist={}, Optional< ChaseAngle > angle={})
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void MoveFollow(Unit *target, float dist, ChaseAngle angle, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_ACTIVE)
void Remove(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
LowType GetCounter() const
Definition: ObjectGuid.h:293
std::string ToString() const
Definition: ObjectGuid.cpp:554
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
static Player * ToPlayer(Object *o)
Definition: Object.h:213
void ReceiveEmote(Player *player, uint32 textEmote) override
Definition: PetAI.cpp:535
uint32 _updateAlliesTimer
Definition: PetAI.h:72
void OwnerAttackedBy(Unit *attacker) override
Definition: PetAI.cpp:267
void AttackStart(Unit *target) override
Definition: PetAI.cpp:245
void OwnerAttacked(Unit *target) override
Definition: PetAI.cpp:287
void MovementInform(uint32 type, uint32 id) override
Definition: PetAI.cpp:440
bool NeedToStop()
Definition: PetAI.cpp:561
bool CanAttack(Unit *target)
Definition: PetAI.cpp:473
void OnCharmed(bool isNew) override
Definition: PetAI.cpp:632
static int32 Permissible(Creature const *creature)
Definition: PetAI.cpp:35
void UpdateAllies()
Definition: PetAI.cpp:592
PetAI(Creature *creature, uint32 scriptId={})
Definition: PetAI.cpp:47
void DoAttack(Unit *target, bool chase)
Definition: PetAI.cpp:400
void StopAttack()
Definition: PetAI.cpp:575
void _AttackStart(Unit *target)
Definition: PetAI.cpp:257
void ClearCharmInfoFlags()
Definition: PetAI.cpp:640
void KilledUnit(Unit *) override
Definition: PetAI.cpp:224
GuidSet _allySet
Definition: PetAI.h:71
Unit * SelectNextTarget(bool allowAutoSelect) const
Definition: PetAI.cpp:308
void UpdateAI(uint32) override
Definition: PetAI.cpp:55
void HandleReturnMovement()
Definition: PetAI.cpp:352
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:226
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
bool IsReady(SpellInfo const *spellInfo, uint32 itemId=0) const
bool HasEffect(SpellEffectName effect) const
Definition: SpellInfo.cpp:1391
bool IsPositive() const
Definition: SpellInfo.cpp:1709
bool CanBeUsedInCombat(Unit const *caster) const
Definition: SpellInfo.cpp:1703
Definition: Spell.h:255
SpellCastResult prepare(SpellCastTargets const &targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3426
bool CanAutoCast(Unit *target)
Definition: Spell.cpp:7091
virtual std::string GetDebugInfo() const
Definition: UnitAI.cpp:395
Definition: Unit.h:627
bool IsWithinMeleeRange(Unit const *obj) const
Definition: Unit.h:699
bool IsCharmed() const
Definition: Unit.h:1215
void CombatStop(bool includingCast=false, bool mutualPvP=true, bool(*unitFilter)(Unit const *otherUnit)=nullptr)
Definition: Unit.cpp:5827
Pet * ToPet()
Definition: Unit.h:1750
bool HasBreakableByDamageCrowdControlAura(Unit *excludeCasterChannel=nullptr) const
Definition: Unit.cpp:734
bool isPossessedByPlayer() const
Definition: Unit.cpp:6455
void UpdateSpeed(UnitMoveType mtype)
Definition: Unit.cpp:8361
ObjectGuid GetOwnerGUID() const override
Definition: Unit.h:1170
Unit * GetCharmer() const
Definition: Unit.h:1188
Unit * getAttackerForHelper() const
Definition: Unit.cpp:5647
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:3089
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
bool IsPet() const
Definition: Unit.h:740
bool IsAlive() const
Definition: Unit.h:1164
CharmInfo * GetCharmInfo()
Definition: Unit.h:1221
Unit * EnsureVictim() const
Definition: Unit.h:717
Unit * GetCharmerOrOwner() const
Definition: Unit.h:1200
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:5670
void SendPetAIReaction(ObjectGuid guid)
Definition: Unit.cpp:10025
virtual float GetFollowAngle() const
Definition: Unit.h:1744
Unit * GetVictim() const
Definition: Unit.h:715
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:736
SpellHistory * GetSpellHistory()
Definition: Unit.h:1457
void HandleEmoteCommand(Emote emoteId, Player *target=nullptr, Trinity::IteratorPair< int32 const * > spellVisualKitIds={}, int32 sequenceVariation=0)
Definition: Unit.cpp:1598
void SetUnitFlag(UnitFlags flags)
Definition: Unit.h:833
bool AttackStop()
Definition: Unit.cpp:5781
bool IsInCombat() const
Definition: Unit.h:1043
void RemoveUnitFlag(UnitFlags flags)
Definition: Unit.h:834
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1442
Map * GetMap() const
Definition: Object.h:624
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition: Object.cpp:2991
bool IsInMap(WorldObject const *obj) const
Definition: Object.cpp:1115
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
void SetIsCommandFollow(bool val)
Definition: Unit.cpp:12586
bool IsCommandAttack()
Definition: Unit.cpp:12581
void SetIsAtStay(bool val)
Definition: Unit.cpp:12617
bool IsFollowing()
Definition: Unit.cpp:12632
bool IsReturning()
Definition: Unit.cpp:12642
void SetIsFollowing(bool val)
Definition: Unit.cpp:12627
void SetIsReturning(bool val)
Definition: Unit.cpp:12637
bool IsAtStay()
Definition: Unit.cpp:12622
bool HasCommandState(CommandStates state) const
Definition: CharmInfo.h:99
void GetStayPosition(float &x, float &y, float &z)
Definition: Unit.cpp:12610
bool IsCommandFollow()
Definition: Unit.cpp:12591
void SetIsCommandAttack(bool val)
Definition: Unit.cpp:12576