aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortreeston <treeston.mmoc@gmail.com>2016-02-24 19:35:19 +0100
committerShauren <shauren.trinity@gmail.com>2016-04-08 20:17:56 +0200
commite394cd298bd051102deec4ee6dae37c0de213fd2 (patch)
tree7cd35b87075c4e548d68308abe3774e61b29d8fc /src
parentf5a1b75fbdd3b7ea99bea35f2239d1cd4d96be3c (diff)
Core/PlayerAI: Some more helper methods added. Also, charmed players no longer break crowd control.
(cherry picked from commit a8f760b69213514f16f24f7af85449c5929f2032)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.cpp25
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.h2
2 files changed, 22 insertions, 5 deletions
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<Unit*, bool>
+{
+ 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