First part of petAI logic cleanup : Hunter PetAI change: Ignore attacking CC'ed targets unless explicitly asked for by player

(thanks to QAston, Shauren, Liberate for the discussions and codehelp to sort this out properly)

--HG--
branch : trunk
This commit is contained in:
click
2010-07-28 19:39:56 +02:00
parent c173e84f25
commit c595eb8ae9
4 changed files with 30 additions and 15 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);