TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
PetAI Class Reference

#include <PetAI.h>

Public Member Functions

 PetAI (Creature *c)
 
void UpdateAI (uint32) override
 
void KilledUnit (Unit *) override
 
void AttackStart (Unit *target) override
 
void MovementInform (uint32 moveType, uint32 data) override
 
void OwnerAttackedBy (Unit *attacker) override
 
void OwnerAttacked (Unit *target) override
 
void AttackedBy (Unit *attacker) override
 
void ReceiveEmote (Player *player, uint32 textEmote) override
 
void MoveInLineOfSight (Unit *) override
 
void MoveInLineOfSight_Safe (Unit *)
 
void EnterEvadeMode (EvadeReason) override
 
- Public Member Functions inherited from CreatureAI
void Talk (uint8 id, WorldObject const *whisperTarget=nullptr)
 
 CreatureAI (Creature *creature)
 
virtual ~CreatureAI ()
 
void MoveInLineOfSight_Safe (Unit *who)
 == Reactions At ================================= More...
 
void TriggerAlert (Unit const *who) const
 
virtual bool CanRespawn ()
 
virtual void EnterCombat (Unit *)
 
virtual void JustDied (Unit *)
 
virtual void JustSummoned (Creature *)
 
virtual void IsSummonedBy (Unit *)
 
virtual void SummonedCreatureDespawn (Creature *)
 
virtual void SummonedCreatureDies (Creature *, Unit *)
 
virtual void SpellHit (Unit *, SpellInfo const *)
 
virtual void SpellHitTarget (Unit *, SpellInfo const *)
 
virtual bool IsEscorted () const
 
virtual void JustRespawned ()
 
void OnCharmed (bool apply) override
 
virtual void JustReachedHome ()
 
void DoZoneInCombat (Creature *creature=NULL, float maxRangeToNearestTarget=50.0f)
 
virtual void CorpseRemoved (uint32 &)
 == Triggered Actions Requested ================== More...
 
virtual void PassengerBoarded (Unit *, int8, bool)
 == Fields ======================================= More...
 
virtual void OnSpellClick (Unit *, bool &)
 
virtual bool CanSeeAlways (WorldObject const *)
 
int32 VisualizeBoundary (uint32 duration, Unit *owner=nullptr, bool fill=false) const
 
virtual bool CheckInRoom ()
 
CreatureBoundary constGetBoundary () const
 
- Public Member Functions inherited from UnitAI
 UnitAI (Unit *unit)
 
virtual ~UnitAI ()
 
virtual bool CanAIAttack (Unit const *) const
 
virtual void InitializeAI ()
 
virtual void Reset ()
 
virtual void DoAction (int32)
 
virtual uint32 GetData (uint32) const
 
virtual void SetData (uint32, uint32)
 
virtual void SetGUID (ObjectGuid, int32=0)
 
virtual ObjectGuid GetGUID (int32=0) const
 
UnitSelectTarget (SelectAggroTarget targetType, uint32 position=0, float dist=0.0f, bool playerOnly=false, int32 aura=0)
 
template<class PREDICATE >
UnitSelectTarget (SelectAggroTarget targetType, uint32 position, PREDICATE const &predicate)
 
void SelectTargetList (std::list< Unit * > &targetList, uint32 num, SelectAggroTarget targetType, float dist=0.0f, bool playerOnly=false, int32 aura=0)
 
template<class PREDICATE >
void SelectTargetList (std::list< Unit * > &targetList, PREDICATE const &predicate, uint32 maxTargets, SelectAggroTarget targetType)
 
virtual void DamageDealt (Unit *, uint32 &, DamageEffectType)
 
virtual void DamageTaken (Unit *, uint32 &)
 
virtual void HealReceived (Unit *, uint32 &)
 
virtual void HealDone (Unit *, uint32 &)
 
virtual void SpellInterrupted (uint32, uint32)
 
void AttackStartCaster (Unit *victim, float dist)
 
void DoCast (uint32 spellId)
 
void DoCast (Unit *victim, uint32 spellId, bool triggered=false)
 
void DoCastVictim (uint32 spellId, bool triggered=false)
 
void DoCastAOE (uint32 spellId, bool triggered=false)
 
void DoMeleeAttackIfReady ()
 
bool DoSpellAttackIfReady (uint32 spellId)
 
virtual void sGossipHello (Player *)
 
virtual void sGossipSelect (Player *, uint32, uint32)
 
virtual void sGossipSelectCode (Player *, uint32, uint32, char const *)
 
virtual void sQuestAccept (Player *, Quest const *)
 
virtual void sQuestSelect (Player *, Quest const *)
 
virtual void sQuestReward (Player *, Quest const *, uint32)
 
virtual bool sOnDummyEffect (Unit *, uint32, SpellEffIndex)
 
virtual void sOnGameEvent (bool, uint16)
 

Static Public Member Functions

static int Permissible (const Creature *)
 
- Static Public Member Functions inherited from UnitAI
static void FillAISpellInfo ()
 

Private Member Functions

bool _isVisible (Unit *) const
 
bool _needToStop (void)
 
void _stopAttack (void)
 
void UpdateAllies ()
 
UnitSelectNextTarget (bool allowAutoSelect) const
 
void HandleReturnMovement ()
 
void DoAttack (Unit *target, bool chase)
 
bool CanAttack (Unit *target)
 
void ClearCharmInfoFlags ()
 

Private Attributes

TimeTracker i_tracker
 
GuidSet m_AllySet
 
uint32 m_updateAlliesTimer
 

Additional Inherited Members

- Public Types inherited from CreatureAI
enum  EvadeReason { EVADE_REASON_NO_HOSTILES, EVADE_REASON_BOUNDARY, EVADE_REASON_SEQUENCE_BREAK, EVADE_REASON_OTHER }
 
- Static Public Attributes inherited from UnitAI
static AISpellInfoTypeAISpellInfo
 
- Protected Member Functions inherited from CreatureAI
bool UpdateVictim ()
 
bool UpdateVictimWithGaze ()
 
void SetGazeOn (Unit *target)
 
CreatureDoSummon (uint32 entry, Position const &pos, uint32 despawnTime=30000, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
 
CreatureDoSummon (uint32 entry, WorldObject *obj, float radius=5.0f, uint32 despawnTime=30000, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
 
CreatureDoSummonFlyer (uint32 entry, WorldObject *obj, float flightZ, float radius=5.0f, uint32 despawnTime=30000, TempSummonType summonType=TEMPSUMMON_CORPSE_TIMED_DESPAWN)
 
bool CheckBoundary (Position const *who=nullptr) const
 
void SetBoundary (CreatureBoundary const *boundary)
 
bool _EnterEvadeMode (EvadeReason why=EVADE_REASON_OTHER)
 
- Protected Attributes inherited from CreatureAI
Creature *const me
 
CreatureBoundary const_boundary
 
- Protected Attributes inherited from UnitAI
Unit *const me
 

Constructor & Destructor Documentation

PetAI::PetAI ( Creature c)
explicit
41 {
42  UpdateAllies();
43 }
#define TIME_INTERVAL_LOOK
Definition: CreatureAI.h:33
TimeTracker i_tracker
Definition: PetAI.h:59
void UpdateAllies()
Definition: PetAI.cpp:262
CreatureAI(Creature *creature)
Definition: CreatureAI.h:95

+ Here is the call graph for this function:

Member Function Documentation

bool PetAI::_isVisible ( Unit ) const
private
bool PetAI::_needToStop ( void  )
private
46 {
47  // This is needed for charmed creatures, as once their target was reset other effects can trigger threat
48  if (me->IsCharmed() && me->GetVictim() == me->GetCharmer())
49  return true;
50 
51  return !me->IsValidAttackTarget(me->GetVictim());
52 }
Unit * GetCharmer() const
Definition: Unit.cpp:7551
bool IsValidAttackTarget(Unit const *target) const
Definition: Unit.cpp:10002
Creature *const me
Definition: CreatureAI.h:71
Unit * GetVictim() const
Definition: Unit.h:1379
bool IsCharmed() const
Definition: Unit.h:1742

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::_stopAttack ( void  )
private
55 {
56  if (!me->IsAlive())
57  {
58  TC_LOG_DEBUG("misc", "Creature stoped attacking cuz his dead [%s]", me->GetGUID().ToString().c_str());
59  me->GetMotionMaster()->Clear();
61  me->CombatStop();
63  return;
64  }
65 
66  me->AttackStop();
68  me->SendMeleeAttackStop(); // Should stop pet's attack button from flashing
72 }
bool AttackStop()
Definition: Unit.cpp:7337
void MoveIdle()
Definition: MotionMaster.cpp:185
void Clear(bool reset=true)
Definition: MotionMaster.h:138
void ClearCharmInfoFlags()
Definition: PetAI.cpp:601
void SendMeleeAttackStop(Unit *victim=NULL)
Definition: Unit.cpp:2142
MotionMaster * GetMotionMaster()
Definition: Unit.h:2101
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
void HandleReturnMovement()
Definition: PetAI.cpp:421
Creature *const me
Definition: CreatureAI.h:71
HostileRefManager & getHostileRefManager()
Definition: Unit.h:2001
bool IsAlive() const
Definition: Unit.h:1692
void SetIsCommandAttack(bool val)
Definition: Unit.cpp:15700
ObjectGuid const & GetGUID() const
Definition: Object.h:105
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:2916
void deleteReferences()
Definition: HostileRefManager.cpp:114
void CombatStop(bool includingCast=false)
Definition: Unit.cpp:7371
std::string ToString() const
Definition: ObjectGuid.cpp:99

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::AttackedBy ( Unit attacker)
overridevirtual

Reimplemented from CreatureAI.

618 {
619  // Called when pet takes damage. This function helps keep pets from running off
620  // simply due to gaining aggro.
621 
622  if (!attacker)
623  return;
624 
625  // Passive pets don't do anything
627  return;
628 
629  // Prevent pet from disengaging from current target
630  if (me->GetVictim() && me->EnsureVictim()->IsAlive())
631  return;
632 
633  // Continue to evaluate and attack if necessary
634  AttackStart(attacker);
635 }
Unit * EnsureVictim() const
Definition: Unit.h:1381
Definition: Unit.h:1129
bool HasReactState(ReactStates state) const
Definition: Creature.h:504
Creature *const me
Definition: CreatureAI.h:71
bool IsAlive() const
Definition: Unit.h:1692
Unit * GetVictim() const
Definition: Unit.h:1379
void AttackStart(Unit *target) override
Definition: PetAI.cpp:324

+ Here is the call graph for this function:

void PetAI::AttackStart ( Unit target)
overridevirtual

Reimplemented from UnitAI.

325 {
326  // Overrides Unit::AttackStart to correctly evaluate Pet states
327 
328  // Check all pet states to decide if we can attack this target
329  if (!CanAttack(target))
330  return;
331 
332  // Only chase if not commanded to stay or if stay but commanded to attack
334 }
void DoAttack(Unit *target, bool chase)
Definition: PetAI.cpp:456
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
Creature *const me
Definition: CreatureAI.h:71
bool IsCommandAttack()
Definition: Unit.cpp:15705
bool HasCommandState(CommandStates state) const
Definition: Unit.h:1212
bool CanAttack(Unit *target)
Definition: PetAI.cpp:519
Definition: Unit.h:1137

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool PetAI::CanAttack ( Unit target)
private
520 {
521  // Evaluates wether a pet can attack a specific target based on CommandState, ReactState and other flags
522  // IMPORTANT: The order in which things are checked is important, be careful if you add or remove checks
523 
524  // Hmmm...
525  if (!target)
526  return false;
527 
528  if (!target->IsAlive())
529  {
530  // Clear target to prevent getting stuck on dead targets
531  me->AttackStop();
532  me->InterruptNonMeleeSpells(false);
534  return false;
535  }
536 
537  // Passive - passive pets can attack if told to
539  return me->GetCharmInfo()->IsCommandAttack();
540 
541  // CC - mobs under crowd control can be attacked if owner commanded
543  return me->GetCharmInfo()->IsCommandAttack();
544 
545  // Returning - pets ignore attacks only if owner clicked follow
546  if (me->GetCharmInfo()->IsReturning())
547  return !me->GetCharmInfo()->IsCommandFollow();
548 
549  // Stay - can attack if target is within range or commanded to
551  return (me->IsWithinMeleeRange(target) || me->GetCharmInfo()->IsCommandAttack());
552 
553  // Pets attacking something (or chasing) should only switch targets if owner tells them to
554  if (me->GetVictim() && me->GetVictim() != target)
555  {
556  // Check if our owner selected this target and clicked "attack"
557  Unit* ownerTarget = NULL;
558  if (Player* owner = me->GetCharmerOrOwner()->ToPlayer())
559  ownerTarget = owner->GetSelectedUnit();
560  else
561  ownerTarget = me->GetCharmerOrOwner()->GetVictim();
562 
563  if (ownerTarget && me->GetCharmInfo()->IsCommandAttack())
564  return (target->GetGUID() == ownerTarget->GetGUID());
565  }
566 
567  // Follow
569  return !me->GetCharmInfo()->IsReturning();
570 
571  // default, though we shouldn't ever get here
572  return false;
573 }
bool AttackStop()
Definition: Unit.cpp:7337
void SendMeleeAttackStop(Unit *victim=NULL)
Definition: Unit.cpp:2142
Definition: Unit.h:1129
arena_t NULL
Definition: jemalloc_internal.h:624
bool HasReactState(ReactStates state) const
Definition: Creature.h:504
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
Player * ToPlayer()
Definition: Object.h:191
bool IsReturning()
Definition: Unit.cpp:15766
Creature *const me
Definition: CreatureAI.h:71
bool IsCommandAttack()
Definition: Unit.cpp:15705
Unit * GetCharmerOrOwner() const
Definition: Unit.cpp:7627
bool IsAlive() const
Definition: Unit.h:1692
Unit * GetVictim() const
Definition: Unit.h:1379
bool IsWithinMeleeRange(const Unit *obj, float dist=MELEE_RANGE) const
Definition: Unit.cpp:508
bool HasBreakableByDamageCrowdControlAura(Unit *excludeCasterChannel=NULL) const
Definition: Unit.cpp:590
bool IsCommandFollow()
Definition: Unit.cpp:15715
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Definition: Unit.h:1138
bool HasCommandState(CommandStates state) const
Definition: Unit.h:1212
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:2916
Definition: Unit.h:1137
Definition: Unit.h:1305

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::ClearCharmInfoFlags ( )
private
602 {
603  // Quick access to set all flags to FALSE
604 
605  CharmInfo* ci = me->GetCharmInfo();
606 
607  if (ci)
608  {
609  ci->SetIsAtStay(false);
610  ci->SetIsCommandAttack(false);
611  ci->SetIsCommandFollow(false);
612  ci->SetIsFollowing(false);
613  ci->SetIsReturning(false);
614  }
615 }
void SetIsFollowing(bool val)
Definition: Unit.cpp:15751
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
Creature *const me
Definition: CreatureAI.h:71
void SetIsReturning(bool val)
Definition: Unit.cpp:15761
void SetIsAtStay(bool val)
Definition: Unit.cpp:15741
void SetIsCommandAttack(bool val)
Definition: Unit.cpp:15700
Definition: Unit.h:1201
void SetIsCommandFollow(bool val)
Definition: Unit.cpp:15710

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::DoAttack ( Unit target,
bool  chase 
)
private
457 {
458  // Handles attack with or without chase and also resets flags
459  // for next update / creature kill
460 
461  if (me->Attack(target, true))
462  {
463  // Play sound to let the player know the pet is attacking something it picked on its own
466 
467  if (chase)
468  {
469  bool oldCmdAttack = me->GetCharmInfo()->IsCommandAttack(); // This needs to be reset after other flags are cleared
471  me->GetCharmInfo()->SetIsCommandAttack(oldCmdAttack); // For passive pets commanded to attack so they will use spells
472  me->GetMotionMaster()->Clear();
473  me->GetMotionMaster()->MoveChase(target);
474  }
475  else // (Stay && ((Aggressive || Defensive) && In Melee Range)))
476  {
478  me->GetCharmInfo()->SetIsAtStay(true);
479  me->GetMotionMaster()->Clear();
481  }
482  }
483 }
bool Attack(Unit *victim, bool meleeAttack)
Definition: Unit.cpp:7222
void MoveIdle()
Definition: MotionMaster.cpp:185
Definition: Unit.h:1131
void Clear(bool reset=true)
Definition: MotionMaster.h:138
void ClearCharmInfoFlags()
Definition: PetAI.cpp:601
void MoveChase(Unit *target, float dist=0.0f, float angle=0.0f)
Definition: MotionMaster.cpp:241
MotionMaster * GetMotionMaster()
Definition: Unit.h:2101
bool HasReactState(ReactStates state) const
Definition: Creature.h:504
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
Creature *const me
Definition: CreatureAI.h:71
bool IsCommandAttack()
Definition: Unit.cpp:15705
void SendPetAIReaction(ObjectGuid guid)
Definition: Unit.cpp:12729
void SetIsAtStay(bool val)
Definition: Unit.cpp:15741
void SetIsCommandAttack(bool val)
Definition: Unit.cpp:15700
ObjectGuid const & GetGUID() const
Definition: Object.h:105

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::EnterEvadeMode ( EvadeReason  )
inlineoverridevirtual

Reimplemented from CreatureAI.

50 { } // For fleeing, pets don't use this type of Evade mechanic
void PetAI::HandleReturnMovement ( )
private
422 {
423  // Handles moving the pet back to stay or owner
424 
425  // Prevent activating movement when under control of spells
426  // such as "Eyes of the Beast"
427  if (me->IsCharmed())
428  return;
429 
431  {
432  if (!me->GetCharmInfo()->IsAtStay() && !me->GetCharmInfo()->IsReturning())
433  {
434  // Return to previous position where stay was clicked
435  float x, y, z;
436 
437  me->GetCharmInfo()->GetStayPosition(x, y, z);
439  me->GetCharmInfo()->SetIsReturning(true);
440  me->GetMotionMaster()->Clear();
442  }
443  }
444  else // COMMAND_FOLLOW
445  {
446  if (!me->GetCharmInfo()->IsFollowing() && !me->GetCharmInfo()->IsReturning())
447  {
449  me->GetCharmInfo()->SetIsReturning(true);
450  me->GetMotionMaster()->Clear();
452  }
453  }
454 }
void Clear(bool reset=true)
Definition: MotionMaster.h:138
void ClearCharmInfoFlags()
Definition: PetAI.cpp:601
MotionMaster * GetMotionMaster()
Definition: Unit.h:2101
bool IsAtStay()
Definition: Unit.cpp:15746
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
bool IsReturning()
Definition: Unit.cpp:15766
Creature *const me
Definition: CreatureAI.h:71
void MovePoint(uint32 id, Position const &pos, bool generatePath=true)
Definition: MotionMaster.h:172
bool IsFollowing()
Definition: Unit.cpp:15756
Unit * GetCharmerOrOwner() const
Definition: Unit.cpp:7627
void SetIsReturning(bool val)
Definition: Unit.cpp:15761
G3D::int16 z
Definition: Vector3int16.h:46
G3D::int16 y
Definition: Vector2int16.h:38
ObjectGuid const & GetGUID() const
Definition: Object.h:105
void GetStayPosition(float &x, float &y, float &z)
Definition: Unit.cpp:15734
bool HasCommandState(CommandStates state) const
Definition: Unit.h:1212
#define PET_FOLLOW_DIST
Definition: PetDefines.h:77
G3D::int16 x
Definition: Vector2int16.h:37
Definition: Unit.h:1137
bool IsCharmed() const
Definition: Unit.h:1742
virtual float GetFollowAngle() const
Definition: Unit.h:2194
LowType GetCounter() const
Definition: ObjectGuid.h:221
void MoveFollow(Unit *target, float dist, float angle, MovementSlot slot=MOTION_SLOT_ACTIVE)
Definition: MotionMaster.cpp:265

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::KilledUnit ( Unit victim)
overridevirtual

Reimplemented from CreatureAI.

303 {
304  // Called from Unit::Kill() in case where pet or owner kills something
305  // if owner killed this victim, pet may still be attacking something else
306  if (me->GetVictim() && me->GetVictim() != victim)
307  return;
308 
309  // Clear target just in case. May help problem where health / focus / mana
310  // regen gets stuck. Also resets attack command.
311  // Can't use _stopAttack() because that activates movement handlers and ignores
312  // next target selection
313  me->AttackStop();
314  me->InterruptNonMeleeSpells(false);
315  me->SendMeleeAttackStop(); // Stops the pet's 'Attack' button from flashing
316 
317  // Before returning to owner, see if there are more things to attack
318  if (Unit* nextTarget = SelectNextTarget(false))
319  AttackStart(nextTarget);
320  else
321  HandleReturnMovement(); // Return
322 }
bool AttackStop()
Definition: Unit.cpp:7337
Unit * SelectNextTarget(bool allowAutoSelect) const
Definition: PetAI.cpp:377
void SendMeleeAttackStop(Unit *victim=NULL)
Definition: Unit.cpp:2142
void HandleReturnMovement()
Definition: PetAI.cpp:421
Creature *const me
Definition: CreatureAI.h:71
Unit * GetVictim() const
Definition: Unit.h:1379
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:2916
void AttackStart(Unit *target) override
Definition: PetAI.cpp:324
Definition: Unit.h:1305

+ Here is the call graph for this function:

void PetAI::MoveInLineOfSight ( Unit )
inlineoverridevirtual

Reimplemented from CreatureAI.

48 { } // CreatureAI interferes with returning pets
void PetAI::MoveInLineOfSight_Safe ( Unit )
inline
49 { } // CreatureAI interferes with returning pets
void PetAI::MovementInform ( uint32  moveType,
uint32  data 
)
overridevirtual

Reimplemented from CreatureAI.

Reimplemented in npc_snufflenose_gopher::npc_snufflenose_gopherAI.

486 {
487  // Receives notification when pet reaches stay or follow owner
488  switch (moveType)
489  {
490  case POINT_MOTION_TYPE:
491  {
492  // Pet is returning to where stay was clicked. data should be
493  // pet's GUIDLow since we set that as the waypoint ID
494  if (data == me->GetGUID().GetCounter() && me->GetCharmInfo()->IsReturning())
495  {
497  me->GetCharmInfo()->SetIsAtStay(true);
498  me->GetMotionMaster()->Clear();
500  }
501  break;
502  }
503  case FOLLOW_MOTION_TYPE:
504  {
505  // If data is owner's GUIDLow then we've reached follow point,
506  // otherwise we're probably chasing a creature
508  {
510  me->GetCharmInfo()->SetIsFollowing(true);
511  }
512  break;
513  }
514  default:
515  break;
516  }
517 }
void MoveIdle()
Definition: MotionMaster.cpp:185
void Clear(bool reset=true)
Definition: MotionMaster.h:138
void SetIsFollowing(bool val)
Definition: Unit.cpp:15751
void ClearCharmInfoFlags()
Definition: PetAI.cpp:601
MotionMaster * GetMotionMaster()
Definition: Unit.h:2101
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
bool IsReturning()
Definition: Unit.cpp:15766
Creature *const me
Definition: CreatureAI.h:71
Unit * GetCharmerOrOwner() const
Definition: Unit.cpp:7627
void SetIsAtStay(bool val)
Definition: Unit.cpp:15741
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Definition: MotionMaster.h:46
Definition: MotionMaster.h:52
LowType GetCounter() const
Definition: ObjectGuid.h:221

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::OwnerAttacked ( Unit target)
overridevirtual

Reimplemented from CreatureAI.

357 {
358  // Called when owner attacks something. Allows defensive pets to know
359  // that they need to assist
360 
361  // Target might be NULL if called from spell with invalid cast targets
362  if (!target)
363  return;
364 
365  // Passive pets don't do anything
367  return;
368 
369  // Prevent pet from disengaging from current target
370  if (me->GetVictim() && me->EnsureVictim()->IsAlive())
371  return;
372 
373  // Continue to evaluate and attack if necessary
374  AttackStart(target);
375 }
Unit * EnsureVictim() const
Definition: Unit.h:1381
Definition: Unit.h:1129
bool HasReactState(ReactStates state) const
Definition: Creature.h:504
Creature *const me
Definition: CreatureAI.h:71
bool IsAlive() const
Definition: Unit.h:1692
Unit * GetVictim() const
Definition: Unit.h:1379
void AttackStart(Unit *target) override
Definition: PetAI.cpp:324

+ Here is the call graph for this function:

void PetAI::OwnerAttackedBy ( Unit attacker)
overridevirtual

Reimplemented from CreatureAI.

337 {
338  // Called when owner takes damage. This function helps keep pets from running off
339  // simply due to owner gaining aggro.
340 
341  if (!attacker)
342  return;
343 
344  // Passive pets don't do anything
346  return;
347 
348  // Prevent pet from disengaging from current target
349  if (me->GetVictim() && me->EnsureVictim()->IsAlive())
350  return;
351 
352  // Continue to evaluate and attack if necessary
353  AttackStart(attacker);
354 }
Unit * EnsureVictim() const
Definition: Unit.h:1381
Definition: Unit.h:1129
bool HasReactState(ReactStates state) const
Definition: Creature.h:504
Creature *const me
Definition: CreatureAI.h:71
bool IsAlive() const
Definition: Unit.h:1692
Unit * GetVictim() const
Definition: Unit.h:1379
void AttackStart(Unit *target) override
Definition: PetAI.cpp:324

+ Here is the call graph for this function:

int PetAI::Permissible ( const Creature creature)
static
33 {
34  if (creature->IsPet())
35  return PERMIT_BASE_SPECIAL;
36 
37  return PERMIT_BASE_NO;
38 }
Definition: CreatureAI.h:207
Definition: CreatureAI.h:212
bool IsPet() const
Definition: Unit.h:1403

+ Here is the call graph for this function:

void PetAI::ReceiveEmote ( Player player,
uint32  textEmote 
)
overridevirtual

Reimplemented from CreatureAI.

576 {
577  if (!me->GetOwnerGUID().IsEmpty() && me->GetOwnerGUID() == player->GetGUID())
578  {
579  switch (emote)
580  {
581  case TEXT_EMOTE_COWER:
582  if (me->IsPet() && me->ToPet()->IsPetGhoul())
583  me->HandleEmoteCommand(/*EMOTE_ONESHOT_ROAR*/EMOTE_ONESHOT_OMNICAST_GHOUL);
584  break;
585  case TEXT_EMOTE_ANGRY:
586  if (me->IsPet() && me->ToPet()->IsPetGhoul())
587  me->HandleEmoteCommand(/*EMOTE_ONESHOT_COWER*/EMOTE_STATE_STUN);
588  break;
589  case TEXT_EMOTE_GLARE:
590  if (me->IsPet() && me->ToPet()->IsPetGhoul())
592  break;
593  case TEXT_EMOTE_SOOTHE:
594  if (me->IsPet() && me->ToPet()->IsPetGhoul())
596  break;
597  }
598  }
599 }
bool IsPetGhoul() const
Definition: TemporarySummon.h:75
Definition: SharedDefines.h:2286
Pet * ToPet()
Definition: Unit.h:2200
Definition: SharedDefines.h:2546
Definition: SharedDefines.h:2180
Creature *const me
Definition: CreatureAI.h:71
Definition: SharedDefines.h:2155
Definition: SharedDefines.h:2458
Definition: SharedDefines.h:2198
bool IsPet() const
Definition: Unit.h:1403
void HandleEmoteCommand(uint32 anim_id)
Definition: Unit.cpp:1444
ObjectGuid GetOwnerGUID() const
Definition: Unit.h:1698
bool IsEmpty() const
Definition: ObjectGuid.h:242

+ Here is the call graph for this function:

Unit * PetAI::SelectNextTarget ( bool  allowAutoSelect) const
private
378 {
379  // Provides next target selection after current target death.
380  // This function should only be called internally by the AI
381  // Targets are not evaluated here for being valid targets, that is done in _CanAttack()
382  // The parameter: allowAutoSelect lets us disable aggressive pet auto targeting for certain situations
383 
384  // Passive pets don't do next target selection
386  return NULL;
387 
388  // Check pet attackers first so we don't drag a bunch of targets to the owner
389  if (Unit* myAttacker = me->getAttackerForHelper())
390  if (!myAttacker->HasBreakableByDamageCrowdControlAura())
391  return myAttacker;
392 
393  // Not sure why we wouldn't have an owner but just in case...
394  if (!me->GetCharmerOrOwner())
395  return NULL;
396 
397  // Check owner attackers
398  if (Unit* ownerAttacker = me->GetCharmerOrOwner()->getAttackerForHelper())
399  if (!ownerAttacker->HasBreakableByDamageCrowdControlAura())
400  return ownerAttacker;
401 
402  // Check owner victim
403  // 3.0.2 - Pets now start attacking their owners victim in defensive mode as soon as the hunter does
404  if (Unit* ownerVictim = me->GetCharmerOrOwner()->GetVictim())
405  return ownerVictim;
406 
407  // Neither pet or owner had a target and aggressive pets can pick any target
408  // To prevent aggressive pets from chain selecting targets and running off, we
409  // only select a random target if certain conditions are met.
410  if (me->HasReactState(REACT_AGGRESSIVE) && allowAutoSelect)
411  {
413  if (Unit* nearTarget = me->SelectNearestHostileUnitInAggroRange(true))
414  return nearTarget;
415  }
416 
417  // Default - no valid targets
418  return NULL;
419 }
Definition: Unit.h:1131
Definition: Unit.h:1129
arena_t NULL
Definition: jemalloc_internal.h:624
bool HasReactState(ReactStates state) const
Definition: Creature.h:504
bool IsAtStay()
Definition: Unit.cpp:15746
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
bool IsReturning()
Definition: Unit.cpp:15766
Creature *const me
Definition: CreatureAI.h:71
bool IsFollowing()
Definition: Unit.cpp:15756
Unit * GetCharmerOrOwner() const
Definition: Unit.cpp:7627
Unit * GetVictim() const
Definition: Unit.h:1379
Unit * getAttackerForHelper() const
Definition: Unit.cpp:7211
Unit * SelectNearestHostileUnitInAggroRange(bool useLOS=false) const
Definition: Creature.cpp:2606
Definition: Unit.h:1305

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::UpdateAI ( uint32  diff)
overridevirtual

Implements UnitAI.

Reimplemented in npc_egbert::npc_egbertAI, and npc_snufflenose_gopher::npc_snufflenose_gopherAI.

75 {
76  if (!me->IsAlive() || !me->GetCharmInfo())
77  return;
78 
79  Unit* owner = me->GetCharmerOrOwner();
80 
81  if (m_updateAlliesTimer <= diff)
82  // UpdateAllies self set update timer
83  UpdateAllies();
84  else
85  m_updateAlliesTimer -= diff;
86 
87  if (me->GetVictim() && me->EnsureVictim()->IsAlive())
88  {
89  // is only necessary to stop casting, the pet must not exit combat
90  if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL) && // ignore channeled spells (Pin, Seduction)
92  {
94  return;
95  }
96 
97  if (_needToStop())
98  {
99  TC_LOG_DEBUG("misc", "Pet AI stopped attacking [%s]", me->GetGUID().ToString().c_str());
100  _stopAttack();
101  return;
102  }
103 
104  // Check before attacking to prevent pets from leaving stay position
106  {
109  }
110  else
112  }
113  else
114  {
116  {
117  // Every update we need to check targets only in certain cases
118  // Aggressive - Allow auto select if owner or pet don't have a target
119  // Stay - Only pick from pet or owner targets / attackers so targets won't run by
120  // while chasing our owner. Don't do auto select.
121  // All other cases (ie: defensive) - Targets are assigned by AttackedBy(), OwnerAttackedBy(), OwnerAttacked(), etc.
123 
124  if (nextTarget)
125  AttackStart(nextTarget);
126  else
128  }
129  else
131  }
132 
133  // Autocast (cast only in combat or persistent spells in any state)
135  {
136  typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
137  TargetSpellList targetSpellStore;
138 
139  for (uint8 i = 0; i < me->GetPetAutoSpellSize(); ++i)
140  {
141  uint32 spellID = me->GetPetAutoSpellOnPos(i);
142  if (!spellID)
143  continue;
144 
145  SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
146  if (!spellInfo)
147  continue;
148 
149  if (me->GetCharmInfo() && me->GetSpellHistory()->HasGlobalCooldown(spellInfo))
150  continue;
151 
152  // check spell cooldown
153  if (!me->GetSpellHistory()->IsReady(spellInfo))
154  continue;
155 
156  if (spellInfo->IsPositive())
157  {
158  if (spellInfo->CanBeUsedInCombat())
159  {
160  // Check if we're in combat or commanded to attack
161  if (!me->IsInCombat() && !me->GetCharmInfo()->IsCommandAttack())
162  continue;
163  }
164 
165  Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE);
166  bool spellUsed = false;
167 
168  // Some spells can target enemy or friendly (DK Ghoul's Leap)
169  // Check for enemy first (pet then owner)
170  Unit* target = me->getAttackerForHelper();
171  if (!target && owner)
172  target = owner->getAttackerForHelper();
173 
174  if (target)
175  {
176  if (CanAttack(target) && spell->CanAutoCast(target))
177  {
178  targetSpellStore.push_back(std::make_pair(target, spell));
179  spellUsed = true;
180  }
181  }
182 
184  {
185  if (!spellUsed)
186  delete spell;
187  continue; // Pets must only jump to target
188  }
189 
190  // No enemy, check friendly
191  if (!spellUsed)
192  {
193  for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
194  {
195  Unit* ally = ObjectAccessor::GetUnit(*me, *tar);
196 
197  //only buff targets that are in combat, unless the spell can only be cast while out of combat
198  if (!ally)
199  continue;
200 
201  if (spell->CanAutoCast(ally))
202  {
203  targetSpellStore.push_back(std::make_pair(ally, spell));
204  spellUsed = true;
205  break;
206  }
207  }
208  }
209 
210  // No valid targets at all
211  if (!spellUsed)
212  delete spell;
213  }
214  else if (me->GetVictim() && CanAttack(me->GetVictim()) && spellInfo->CanBeUsedInCombat())
215  {
216  Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE);
217  if (spell->CanAutoCast(me->GetVictim()))
218  targetSpellStore.push_back(std::make_pair(me->GetVictim(), spell));
219  else
220  delete spell;
221  }
222  }
223 
224  //found units to cast on to
225  if (!targetSpellStore.empty())
226  {
227  uint32 index = urand(0, targetSpellStore.size() - 1);
228 
229  Spell* spell = targetSpellStore[index].second;
230  Unit* target = targetSpellStore[index].first;
231 
232  targetSpellStore.erase(targetSpellStore.begin() + index);
233 
234  SpellCastTargets targets;
235  targets.SetUnitTarget(target);
236 
237  if (!me->HasInArc(float(M_PI), target))
238  {
239  me->SetInFront(target);
240  if (target && target->GetTypeId() == TYPEID_PLAYER)
241  me->SendUpdateToPlayer(target->ToPlayer());
242 
243  if (owner && owner->GetTypeId() == TYPEID_PLAYER)
244  me->SendUpdateToPlayer(owner->ToPlayer());
245  }
246 
247  spell->prepare(&targets);
248  }
249 
250  // deleted cached Spell objects
251  for (TargetSpellList::const_iterator itr = targetSpellStore.begin(); itr != targetSpellStore.end(); ++itr)
252  delete itr->second;
253  }
254 
255  // Update speed as needed to prevent dropping too far behind and despawning
256  me->UpdateSpeed(MOVE_RUN, true);
257  me->UpdateSpeed(MOVE_WALK, true);
258  me->UpdateSpeed(MOVE_FLIGHT, true);
259 
260 }
Definition: DBCEnums.h:404
Unit * EnsureVictim() const
Definition: Unit.h:1381
uint32 m_updateAlliesTimer
Definition: PetAI.h:61
Definition: Unit.h:605
Definition: Unit.h:1131
virtual uint8 GetPetAutoSpellSize() const
Definition: Creature.h:664
bool CanBeUsedInCombat() const
Definition: SpellInfo.cpp:1490
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition: ObjectAccessor.cpp:163
Definition: Unit.h:565
#define M_PI
Definition: Common.h:163
Definition: SpellInfo.h:326
Unit * SelectNextTarget(bool allowAutoSelect) const
Definition: PetAI.cpp:377
void UpdateSpeed(UnitMoveType mtype, bool forced)
Definition: Unit.cpp:10378
Definition: Unit.h:1110
bool IsInCombat() const
Definition: Unit.h:1584
bool HasReactState(ReactStates state) const
Definition: Creature.h:504
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
Definition: Unit.h:599
bool IsAtStay()
Definition: Unit.cpp:15746
CharmInfo * GetCharmInfo()
Definition: Unit.h:1748
Player * ToPlayer()
Definition: Object.h:191
void HandleReturnMovement()
Definition: PetAI.cpp:421
void _stopAttack(void)
Definition: PetAI.cpp:54
Creature *const me
Definition: CreatureAI.h:71
TypeID GetTypeId() const
Definition: Object.h:113
SpellHistory * GetSpellHistory()
Definition: Unit.h:1926
bool IsCommandAttack()
Definition: Unit.cpp:15705
GuidSet m_AllySet
Definition: PetAI.h:60
Unit * GetCharmerOrOwner() const
Definition: Unit.cpp:7627
bool IsPositive() const
Definition: SpellInfo.cpp:1495
bool IsAlive() const
Definition: Unit.h:1692
Unit * GetVictim() const
Definition: Unit.h:1379
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:45
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:230
#define sSpellMgr
Definition: SpellMgr.h:756
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition: Unit.h:1920
uint32_t uint32
Definition: Define.h:150
bool IsWithinMeleeRange(const Unit *obj, float dist=MELEE_RANGE) const
Definition: Unit.cpp:508
bool HasEffect(uint32 difficulty, SpellEffectName effect) const
Definition: SpellInfo.cpp:1169
void UpdateAllies()
Definition: PetAI.cpp:262
bool HasInArc(float arcangle, Position const *pos, float border=2.0f) const
Definition: Position.cpp:129
bool HasBreakableByDamageCrowdControlAura(Unit *excludeCasterChannel=NULL) const
Definition: Unit.cpp:590
Definition: Spell.h:170
bool IsReady(SpellInfo const *spellInfo, uint32 itemId=0, bool ignoreCategoryCooldown=false) const
Definition: SpellHistory.cpp:262
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Definition: Unit.h:600
Definition: ObjectGuid.h:33
bool HasCommandState(CommandStates state) const
Definition: Unit.h:1212
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition: Unit.cpp:2916
void DoMeleeAttackIfReady()
Definition: UnitAI.cpp:49
Unit * getAttackerForHelper() const
Definition: Unit.cpp:7211
Definition: SharedDefines.h:1052
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1395
uint8_t uint8
Definition: Define.h:152
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition: SpellHistory.cpp:821
bool CanAttack(Unit *target)
Definition: PetAI.cpp:519
virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const
Definition: Creature.cpp:2529
void AttackStart(Unit *target) override
Definition: PetAI.cpp:324
Definition: Unit.h:1137
void SetInFront(WorldObject const *target)
Definition: Unit.cpp:15771
bool CanAutoCast(Unit *target)
Definition: Spell.cpp:5810
bool _needToStop(void)
Definition: PetAI.cpp:45
Definition: Unit.h:1305
void SendUpdateToPlayer(Player *player)
Definition: Object.cpp:251
std::string ToString() const
Definition: ObjectGuid.cpp:99
Definition: Unit.h:460
Definition: Spell.h:294

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PetAI::UpdateAllies ( )
private
263 {
264  m_updateAlliesTimer = 10 * IN_MILLISECONDS; // update friendly targets every 10 seconds, lesser checks increase performance
265 
266  Unit* owner = me->GetCharmerOrOwner();
267  if (!owner)
268  return;
269 
270  Group* group = NULL;
271  if (Player* player = owner->ToPlayer())
272  group = player->GetGroup();
273 
274  //only pet and owner/not in group->ok
275  if (m_AllySet.size() == 2 && !group)
276  return;
277 
278  //owner is in group; group members filled in already (no raid -> subgroupcount = whole count)
279  if (group && !group->isRaidGroup() && m_AllySet.size() == (group->GetMembersCount() + 2))
280  return;
281 
282  m_AllySet.clear();
283  m_AllySet.insert(me->GetGUID());
284  if (group) //add group
285  {
286  for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
287  {
288  Player* Target = itr->GetSource();
289  if (!Target || !group->SameSubGroup(owner->ToPlayer(), Target))
290  continue;
291 
292  if (Target->GetGUID() == owner->GetGUID())
293  continue;
294 
295  m_AllySet.insert(Target->GetGUID());
296  }
297  }
298  else //remove group
299  m_AllySet.insert(owner->GetGUID());
300 }
uint32 m_updateAlliesTimer
Definition: PetAI.h:61
bool isRaidGroup() const
Definition: Group.cpp:2509
arena_t NULL
Definition: jemalloc_internal.h:624
Player * ToPlayer()
Definition: Object.h:191
Creature *const me
Definition: CreatureAI.h:71
GuidSet m_AllySet
Definition: PetAI.h:60
Unit * GetCharmerOrOwner() const
Definition: Unit.cpp:7627
bool SameSubGroup(ObjectGuid guid1, ObjectGuid guid2) const
Definition: Group.cpp:2592
GroupReference * GetFirstMember()
Definition: Group.h:295
ObjectGuid const & GetGUID() const
Definition: Object.h:105
uint32 GetMembersCount() const
Definition: Group.h:297
Definition: Common.h:103
Definition: Unit.h:1305
Definition: Group.h:191
Definition: GroupReference.h:27

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

TimeTracker PetAI::i_tracker
private
GuidSet PetAI::m_AllySet
private
uint32 PetAI::m_updateAlliesTimer
private

The documentation for this class was generated from the following files: