diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/CoreAI/PetAI.cpp | 35 | ||||
-rw-r--r-- | src/server/game/AI/CoreAI/PetAI.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 2 |
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); |