aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorQAston <qaston@gmail.com>2012-02-05 00:13:56 -0800
committerQAston <qaston@gmail.com>2012-02-05 00:13:56 -0800
commit7be73a0667f29c857511e9989d10a15969d2f96a (patch)
treef373304970053f8379df9b1769e41bbca7fdd145 /src
parent3b10122c1324a48bacca06771df378b2c1ea953a (diff)
parent14bc551862d95d9827b1a17c0c16dcbc15691893 (diff)
Merge pull request #5075 from devilcoredev/fix_004
Core/AI: Fix pet and other types of minion pet attack on targets with Crowd Controls.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/AI/CoreAI/CombatAI.cpp6
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.cpp29
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.h2
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp18
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/scripts/World/npcs_special.cpp6
6 files changed, 42 insertions, 21 deletions
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp
index e178efc7eee..03d1b9793d9 100755
--- a/src/server/game/AI/CoreAI/CombatAI.cpp
+++ b/src/server/game/AI/CoreAI/CombatAI.cpp
@@ -158,6 +158,12 @@ void CasterAI::UpdateAI(const uint32 diff)
events.Update(diff);
+ if (me->getVictim()->HasBreakableByDamageCrowdControlAura())
+ {
+ me->InterruptNonMeleeSpells(false);
+ return;
+ }
+
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 83a89a966c5..e07042df149 100755
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -42,7 +42,6 @@ PetAI::PetAI(Creature* c) : CreatureAI(c), i_tracker(TIME_INTERVAL_LOOK)
{
m_AllySet.clear();
UpdateAllies();
- targetHasCC = false;
}
void PetAI::EnterEvadeMode()
@@ -55,9 +54,6 @@ bool PetAI::_needToStop()
if (me->isCharmed() && me->getVictim() == me->GetCharmer())
return true;
- if (_CheckTargetCC(me->getVictim()) && !targetHasCC)
- return true;
-
return !me->IsValidAttackTarget(me->getVictim());
}
@@ -95,13 +91,19 @@ void PetAI::UpdateAI(const uint32 diff)
// me->getVictim() can't be used for check in case stop fighting, me->getVictim() clear at Unit death etc.
if (me->getVictim())
{
+ // is only necessary to stop casting, the pet must not exit combat
+ if (me->getVictim()->HasBreakableByDamageCrowdControlAura())
+ {
+ me->InterruptNonMeleeSpells(false);
+ return;
+ }
+
if (_needToStop())
{
sLog->outStaticDebug("Pet AI stopped attacking [guid=%u]", me->GetGUIDLow());
_stopAttack();
return;
}
- targetHasCC = _CheckTargetCC(me->getVictim());
DoMeleeAttackIfReady();
}
@@ -293,8 +295,6 @@ void PetAI::AttackStart(Unit* target)
if (!CanAttack(target))
return;
- targetHasCC = _CheckTargetCC(target);
-
if (Unit* owner = me->GetOwner())
owner->SetInCombatWith(target);
@@ -310,22 +310,21 @@ Unit* PetAI::SelectNextTarget()
return NULL;
Unit* target = me->getAttackerForHelper();
- targetHasCC = false;
// Check pet's attackers first to prevent dragging mobs back to owner
- if (target && !_CheckTargetCC(target))
+ if (target && !target->HasBreakableByDamageCrowdControlAura())
return target;
if (me->GetCharmerOrOwner())
{
// Check owner's attackers if pet didn't have any
target = me->GetCharmerOrOwner()->getAttackerForHelper();
- if (target && !_CheckTargetCC(target))
+ if (target && !target->HasBreakableByDamageCrowdControlAura())
return target;
// 3.0.2 - Pets now start attacking their owners target in defensive mode as soon as the hunter does
target = me->GetCharmerOrOwner()->getVictim();
- if (target && !_CheckTargetCC(target))
+ if (target && !target->HasBreakableByDamageCrowdControlAura())
return target;
}
@@ -467,11 +466,3 @@ bool PetAI::CanAttack(Unit* target)
// default, though we shouldn't ever get here
return false;
}
-
-bool PetAI::_CheckTargetCC(Unit* target)
-{
- if (me->GetCharmerOrOwnerGUID() && target->HasNegativeAuraWithAttribute(SPELL_ATTR0_BREAKABLE_BY_DAMAGE, me->GetCharmerOrOwnerGUID()))
- return true;
-
- return false;
-}
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index 847b4140285..730ab12a3ca 100755
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -50,7 +50,6 @@ class PetAI : public CreatureAI
TimeTracker i_tracker;
bool inCombat;
- bool targetHasCC;
std::set<uint64> m_AllySet;
uint32 m_updateAlliesTimer;
@@ -58,7 +57,6 @@ 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 59c091f353d..9f87f236d56 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -516,6 +516,24 @@ bool Unit::HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint
return false;
}
+bool Unit::HasBreakableByDamageAuraType(AuraType type) const
+{
+ AuraEffectList const& auras = GetAuraEffectsByType(type);
+ for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ if ((*itr)->GetSpellInfo()->Attributes & SPELL_ATTR0_BREAKABLE_BY_DAMAGE || (*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_TAKE_DAMAGE)
+ return true;
+ return false;
+}
+
+bool Unit::HasBreakableByDamageCrowdControlAura() const
+{
+ return ( HasBreakableByDamageAuraType(SPELL_AURA_MOD_CONFUSE)
+ || HasBreakableByDamageAuraType(SPELL_AURA_MOD_FEAR)
+ || HasBreakableByDamageAuraType(SPELL_AURA_MOD_STUN)
+ || HasBreakableByDamageAuraType(SPELL_AURA_MOD_ROOT)
+ || HasBreakableByDamageAuraType(SPELL_AURA_TRANSFORM));
+}
+
void Unit::DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb)
{
if (!victim || !victim->isAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode()))
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index ea5e2d5052b..abcdf13c49b 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1555,6 +1555,8 @@ class Unit : public WorldObject
bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const;
bool virtual HasSpell(uint32 /*spellID*/) const { return false; }
+ bool HasBreakableByDamageAuraType(AuraType type) const;
+ bool HasBreakableByDamageCrowdControlAura() const;
bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); }
bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); }
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index fcf5f56c539..04e9c05e02d 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -1738,6 +1738,12 @@ public:
if (!UpdateVictim())
return;
+ if (me->getVictim()->HasBreakableByDamageCrowdControlAura())
+ {
+ me->InterruptNonMeleeSpells(false);
+ return;
+ }
+
if (SpellTimer <= diff)
{
if (IsViper) //Viper