From e394cd298bd051102deec4ee6dae37c0de213fd2 Mon Sep 17 00:00:00 2001 From: treeston Date: Wed, 24 Feb 2016 19:35:19 +0100 Subject: Core/PlayerAI: Some more helper methods added. Also, charmed players no longer break crowd control. (cherry picked from commit a8f760b69213514f16f24f7af85449c5929f2032) --- src/server/game/AI/PlayerAI/PlayerAI.cpp | 25 ++++++++++++++++++++----- src/server/game/AI/PlayerAI/PlayerAI.h | 2 ++ 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp index 5f15994b32c..38db081e5e5 100644 --- a/src/server/game/AI/PlayerAI/PlayerAI.cpp +++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp @@ -150,9 +150,23 @@ void PlayerAI::DoAutoAttackIfReady() DoMeleeAttackIfReady(); } +struct UncontrolledTargetSelectPredicate : public std::unary_function +{ + bool operator()(Unit const* target) const + { + return !target->HasBreakableByDamageCrowdControlAura(); + } +}; +Unit* SimpleCharmedPlayerAI::SelectAttackTarget() const +{ + if (Unit* charmer = me->GetCharmer()) + return charmer->IsAIEnabled ? charmer->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, UncontrolledTargetSelectPredicate()) : charmer->GetVictim(); + return nullptr; +} + void SimpleCharmedPlayerAI::UpdateAI(const uint32 /*diff*/) { - Creature* charmer = me->GetCharmer()->ToCreature(); + Creature* charmer = me->GetCharmer() ? me->GetCharmer()->ToCreature() : nullptr; //kill self if charm aura has infinite duration if (charmer->IsInEvadeMode()) @@ -169,9 +183,9 @@ void SimpleCharmedPlayerAI::UpdateAI(const uint32 /*diff*/) if (charmer->IsInCombat()) { Unit* target = me->GetVictim(); - if (!target || !charmer->IsValidAttackTarget(target)) + if (!target || !charmer->IsValidAttackTarget(target) || target->HasBreakableByDamageCrowdControlAura()) { - target = charmer->SelectNearestTarget(); + target = SelectAttackTarget(); if (!target) return; @@ -180,15 +194,16 @@ void SimpleCharmedPlayerAI::UpdateAI(const uint32 /*diff*/) else AttackStart(target); } + DoAutoAttackIfReady(); } else { me->AttackStop(); me->CastStop(); + me->StopMoving(); + me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); } - - DoAutoAttackIfReady(); } void SimpleCharmedPlayerAI::OnCharmed(bool apply) diff --git a/src/server/game/AI/PlayerAI/PlayerAI.h b/src/server/game/AI/PlayerAI/PlayerAI.h index 226789cc277..467c1dfd51a 100644 --- a/src/server/game/AI/PlayerAI/PlayerAI.h +++ b/src/server/game/AI/PlayerAI/PlayerAI.h @@ -39,6 +39,7 @@ class TC_GAME_API PlayerAI : public UnitAI Player* const me; void SetIsRangedAttacker(bool state) { _isSelfRangedAttacker = state; } // this allows overriding of the default ranged attacker detection + virtual Unit* SelectAttackTarget() const { return me->GetCharmer() ? me->GetCharmer()->GetVictim() : nullptr; } void DoRangedAttackIfReady(); void DoAutoAttackIfReady(); @@ -53,6 +54,7 @@ class TC_GAME_API SimpleCharmedPlayerAI : public PlayerAI SimpleCharmedPlayerAI(Player* player) : PlayerAI(player) { } void UpdateAI(uint32 diff) override; void OnCharmed(bool apply) override; + Unit* SelectAttackTarget() const; }; #endif -- cgit v1.2.3