aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp35
-rw-r--r--src/server/game/AI/CoreAI/PetAI.h4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp4
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
4 files changed, 30 insertions, 15 deletions
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index cae50668a3a..0eb8e024adb 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -48,12 +48,15 @@ void PetAI::EnterEvadeMode()
{
}
-bool PetAI::_needToStop() const
+bool PetAI::_needToStop()
{
// This is needed for charmed creatures, as once their target was reset other effects can trigger threat
if (me->isCharmed() && me->getVictim() == me->GetCharmer())
return true;
+ if (_CheckTargetCC(me->getVictim()) != targetHasCC)
+ return true;
+
return !me->canAttack(me->getVictim());
}
@@ -295,6 +298,9 @@ void PetAI::AttackStart(Unit *target)
if (!_CanAttack(target))
return;
+ if (_CheckTargetCC(target))
+ targetHasCC = true;
+
// We can attack, should we chase or not?
if (me->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
DoAttack(target,true); // FOLLOW, attack with chase
@@ -315,21 +321,20 @@ Unit *PetAI::SelectNextTarget()
if (me->HasReactState(REACT_PASSIVE))
return NULL;
+ Unit *target = NULL;
+ targetHasCC = false;
+
// Check pet's attackers first to prevent dragging mobs back
// to owner
- if (me->getAttackerForHelper())
- return me->getAttackerForHelper();
-
+ if ((target = me->getAttackerForHelper()) && !_CheckTargetCC(target)) {}
// Check owner's attackers if pet didn't have any
- if (me->GetCharmerOrOwner()->getAttackerForHelper())
- return me->GetCharmerOrOwner()->getAttackerForHelper();
-
+ else if ((target = me->GetCharmerOrOwner()->getAttackerForHelper()) && !_CheckTargetCC(target)) {}
// 3.0.2 - Pets now start attacking their owners target in defensive mode as soon as the hunter does
- if (me->GetCharmerOrOwner()->getVictim())
- return me->GetCharmerOrOwner()->getVictim();
-
+ else if ((target = me->GetCharmerOrOwner()->getVictim()) && !_CheckTargetCC(target)) {}
// Default
- return NULL;
+ else return NULL;
+
+ return target;
}
void PetAI::HandleReturnMovement()
@@ -469,3 +474,11 @@ bool PetAI::_CanAttack(Unit *target)
// default, though we shouldn't ever get here
return false;
}
+
+bool PetAI::_CheckTargetCC(Unit *target)
+{
+ if (me->GetOwnerGUID() && target->HasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE, me->GetOwnerGUID()))
+ return true;
+
+ return false;
+}
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index f6087a129ae..b1c2cd6872f 100644
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -45,13 +45,14 @@ class PetAI : public CreatureAI
private:
bool _isVisible(Unit *) const;
- bool _needToStop(void) const;
+ bool _needToStop(void);
void _stopAttack(void);
void UpdateAllies();
TimeTracker i_tracker;
bool inCombat;
+ bool targetHasCC;
std::set<uint64> m_AllySet;
uint32 m_updateAlliesTimer;
@@ -59,6 +60,7 @@ class PetAI : public CreatureAI
void HandleReturnMovement();
void DoAttack(Unit *target, bool chase);
bool _CanAttack(Unit *target);
+ bool _CheckTargetCC(Unit *target);
};
#endif
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 950d8b5e975..2394613d731 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -4625,13 +4625,13 @@ bool Unit::HasAuraTypeWithValue(AuraType auratype, int32 value) const
return false;
}
-bool Unit::HasNegativeAuraWithInterruptFlag(uint32 flag)
+bool Unit::HasNegativeAuraWithInterruptFlag(uint32 flag, uint64 guid)
{
if (!(m_interruptMask & flag))
return false;
for (AuraApplicationList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); ++iter)
{
- if (!(*iter)->IsPositive() && (*iter)->GetBase()->GetSpellProto()->AuraInterruptFlags & flag)
+ if (!(*iter)->IsPositive() && (*iter)->GetBase()->GetSpellProto()->AuraInterruptFlags & flag && (!guid || (*iter)->GetBase()->GetCasterGUID() == guid))
return true;
}
return false;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 0822ae1cb7b..291aa758c71 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1624,7 +1624,7 @@ class Unit : public WorldObject
bool HasAuraType(AuraType auraType) const;
bool HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const;
bool HasAuraTypeWithValue(AuraType auratype, int32 value) const;
- bool HasNegativeAuraWithInterruptFlag(uint32 flag);
+ bool HasNegativeAuraWithInterruptFlag(uint32 flag, uint64 guid = 0);
AuraEffect * IsScriptOverriden(SpellEntry const * spell, int32 script) const;
uint32 GetDiseasesByCaster(uint64 casterGUID, bool remove = false);