diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index cf6a2ee10..7a817d1a0 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -60,6 +60,11 @@ bool PetAI::_needToStop() return !me->CanCreatureAttack(me->GetVictim()); } +void PetAI::PetStopAttack() +{ + _stopAttack(); +} + void PetAI::_stopAttack() { if (!me->IsAlive()) @@ -174,7 +179,7 @@ void PetAI::UpdateAI(uint32 diff) else _doMeleeAttack(); } - else if (!me->GetCharmInfo() || (!me->GetCharmInfo()->GetForcedSpell() && !me->HasUnitState(UNIT_STATE_CASTING))) + else if (!me->GetCharmInfo() || (!me->GetCharmInfo()->GetForcedSpell() && !(me->IsPet() && me->ToPet()->HasTempSpell()) && !me->HasUnitState(UNIT_STATE_CASTING))) { if (me->HasReactState(REACT_AGGRESSIVE) || me->GetCharmInfo()->IsAtStay()) { diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h index 919faa04b..0e1235716 100644 --- a/src/server/game/AI/CoreAI/PetAI.h +++ b/src/server/game/AI/CoreAI/PetAI.h @@ -67,6 +67,8 @@ public: void EnterEvadeMode() override {} // For fleeing, pets don't use this type of Evade mechanic void SpellHit(Unit* caster, const SpellInfo* spellInfo) override; + void PetStopAttack() override; + private: bool _isVisible(Unit*) const; bool _needToStop(void); diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index b6f8791d8..6943971ce 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -177,6 +177,8 @@ public: virtual bool CanBeSeen(Player const* /*seer*/) { return true; } + virtual void PetStopAttack() { } + protected: virtual void MoveInLineOfSight(Unit* /*who*/); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 1e6c963b3..f7d7094bf 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -511,13 +511,18 @@ void Pet::Update(uint32 diff) } else { - GetCharmInfo()->SetCommandState(COMMAND_FOLLOW); - GetCharmInfo()->SetIsCommandAttack(false); - GetCharmInfo()->SetIsAtStay(false); - GetCharmInfo()->SetIsReturning(true); - GetCharmInfo()->SetIsCommandFollow(true); - GetCharmInfo()->SetIsFollowing(false); - GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, GetFollowAngle()); + if (IsAIEnabled) + AI()->PetStopAttack(); + else + { + GetCharmInfo()->SetCommandState(COMMAND_FOLLOW); + GetCharmInfo()->SetIsCommandAttack(false); + GetCharmInfo()->SetIsAtStay(false); + GetCharmInfo()->SetIsReturning(true); + GetCharmInfo()->SetIsCommandFollow(true); + GetCharmInfo()->SetIsFollowing(false); + GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, GetFollowAngle()); + } } m_tempoldTarget = nullptr; diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index be8a4327d..e09910b17 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -169,6 +169,9 @@ public: static void HandleAsynchLoadFailed(AsynchPetSummon* info, Player* player, uint8 asynchLoadType, uint8 loadResult); uint8 GetAsynchLoadType() const { return asynchLoadType; } void SetAsynchLoadType(uint8 type) { asynchLoadType = type; } + + [[nodiscard]] bool HasTempSpell() const { return m_tempspell != 0; } + protected: Player* m_owner; int32 m_happinessTimer; diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 6567baff9..c31dc68e5 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -890,7 +890,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe charmInfo->SetIsCommandFollow(false); charmInfo->SetIsReturning(false); - pet->GetMotionMaster()->MoveChase(unit_target); + pet->GetMotionMaster()->MoveFollow(unit_target, PET_FOLLOW_DIST, rand_norm() * 2 * M_PI); if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && urand(0, 100) < 10) pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);