aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.cpp37
-rw-r--r--src/server/game/AI/PlayerAI/PlayerAI.h4
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp20
3 files changed, 34 insertions, 27 deletions
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp
index f26522b8ed6..a103b34ff56 100644
--- a/src/server/game/AI/PlayerAI/PlayerAI.cpp
+++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp
@@ -769,18 +769,30 @@ Unit* PlayerAI::SelectAttackTarget() const
return me->GetCharmer() ? me->GetCharmer()->GetVictim() : nullptr;
}
-struct UncontrolledTargetSelectPredicate
+struct ValidTargetSelectPredicate
{
+ ValidTargetSelectPredicate(UnitAI const* ai) : _ai(ai) { }
+ UnitAI const* const _ai;
bool operator()(Unit const* target) const
{
- return !target->HasBreakableByDamageCrowdControlAura();
+ return _ai->CanAIAttack(target);
}
};
+bool SimpleCharmedPlayerAI::CanAIAttack(Unit const* who) const
+{
+ if (!me->IsValidAttackTarget(who) || who->HasBreakableByDamageCrowdControlAura())
+ return false;
+ if (Unit* charmer = me->GetCharmer())
+ if (!charmer->IsValidAttackTarget(who))
+ return false;
+ return UnitAI::CanAIAttack(who);
+}
+
Unit* SimpleCharmedPlayerAI::SelectAttackTarget() const
{
if (Unit* charmer = me->GetCharmer())
- return charmer->IsAIEnabled ? charmer->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, UncontrolledTargetSelectPredicate()) : charmer->GetVictim();
+ return charmer->IsAIEnabled ? charmer->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, ValidTargetSelectPredicate(this)) : charmer->GetVictim();
return nullptr;
}
@@ -1316,11 +1328,23 @@ void SimpleCharmedPlayerAI::UpdateAI(const uint32 diff)
if (charmer->IsEngaged())
{
Unit* target = me->GetVictim();
- if (!target || !charmer->IsValidAttackTarget(target) || !me->IsValidAttackTarget(target) || target->HasBreakableByDamageCrowdControlAura())
+ if (!target || !CanAIAttack(target))
{
target = SelectAttackTarget();
- if (!target)
+ if (!target || !CanAIAttack(target))
+ {
+ if (!_isFollowing)
+ {
+ _isFollowing = true;
+ me->AttackStop();
+ me->CastStop();
+ me->StopMoving();
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveFollow(charmer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ }
return;
+ }
+ _isFollowing = false;
if (IsRangedAttacker())
{
@@ -1373,8 +1397,9 @@ void SimpleCharmedPlayerAI::UpdateAI(const uint32 diff)
DoAutoAttackIfReady();
}
- else
+ else if (!_isFollowing)
{
+ _isFollowing = true;
me->AttackStop();
me->CastStop();
me->StopMoving();
diff --git a/src/server/game/AI/PlayerAI/PlayerAI.h b/src/server/game/AI/PlayerAI/PlayerAI.h
index 8afc5ab3ce9..faff09b6b6e 100644
--- a/src/server/game/AI/PlayerAI/PlayerAI.h
+++ b/src/server/game/AI/PlayerAI/PlayerAI.h
@@ -97,11 +97,12 @@ class TC_GAME_API PlayerAI : public UnitAI
class TC_GAME_API SimpleCharmedPlayerAI : public PlayerAI
{
public:
- SimpleCharmedPlayerAI(Player* player) : PlayerAI(player), _castCheckTimer(500), _chaseCloser(false), _forceFacing(true) { }
+ SimpleCharmedPlayerAI(Player* player) : PlayerAI(player), _castCheckTimer(2500), _chaseCloser(false), _forceFacing(true), _isFollowing(false) { }
void UpdateAI(uint32 diff) override;
void OnCharmed(bool apply) override;
protected:
+ bool CanAIAttack(Unit const* who) const override;
Unit* SelectAttackTarget() const override;
private:
@@ -109,6 +110,7 @@ class TC_GAME_API SimpleCharmedPlayerAI : public PlayerAI
uint32 _castCheckTimer;
bool _chaseCloser;
bool _forceFacing;
+ bool _isFollowing;
};
#endif
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp
index 7f9111cfffb..62a81af385c 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp
@@ -57,26 +57,6 @@ enum Events
class BlackheartCharmedPlayerAI : public SimpleCharmedPlayerAI
{
using SimpleCharmedPlayerAI::SimpleCharmedPlayerAI;
- Unit* SelectAttackTarget() const override
- {
- if (Unit* charmer = me->GetCharmer())
- {
- std::list<Player*> targets;
- for (ThreatReference const* ref : charmer->GetThreatManager().GetUnsortedThreatList())
- {
- if (Player* victim = ref->GetVictim()->ToPlayer())
- if (me->IsValidAttackTarget(victim))
- targets.push_back(victim);
- }
- if (targets.empty())
- return nullptr;
-
- auto it = targets.begin();
- std::advance(it, urand(0, targets.size() - 1));
- return *it;
- }
- return nullptr;
- }
void OnCharmed(bool apply) override
{
SimpleCharmedPlayerAI::OnCharmed(apply);