aboutsummaryrefslogtreecommitdiff
path: root/src/game/Unit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Unit.cpp')
-rw-r--r--src/game/Unit.cpp77
1 files changed, 56 insertions, 21 deletions
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 093e5f03643..34513e87b82 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -8409,19 +8409,32 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
return false;
}
-bool Unit::IsImmunedToSpellEffect(uint32 effect, uint32 mechanic) const
+bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const
{
//If m_immuneToEffect type contain this effect type, IMMUNE effect.
+ uint32 effect = spellInfo->Effect[index];
SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
if(itr->type == effect)
return true;
- SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
- for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
- if(itr->type == mechanic)
- return true;
+ uint32 mechanic = spellInfo->EffectMechanic[index];
+ if (mechanic)
+ {
+ SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
+ for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
+ if(itr->type == mechanic)
+ return true;
+ }
+ uint32 aura = spellInfo->EffectApplyAuraName[index];
+ if (aura)
+ {
+ SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE];
+ for(SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
+ if(itr->type == aura)
+ return true;
+ }
return false;
}
@@ -9435,22 +9448,48 @@ bool Unit::SelectHostilTarget()
//threat list sorting etc.
assert(GetTypeId()== TYPEID_UNIT);
- Unit* target = NULL;
//This function only useful once AI has been initialized
if (!((Creature*)this)->AI())
return false;
- if(!m_ThreatManager.isThreatListEmpty())
+ Unit* target = NULL;
+
+ // First checking if we have some taunt on us
+ const AuraList& tauntAuras = GetAurasByType(SPELL_AURA_MOD_TAUNT);
+ if ( !tauntAuras.empty() )
{
- if(!HasAuraType(SPELL_AURA_MOD_TAUNT))
+ Unit* caster;
+
+ // The last taunt aura caster is alive an we are happy to attack him
+ if ( (caster = tauntAuras.back()->GetCaster()) && caster->isAlive() )
+ return true;
+ else if (tauntAuras.size() > 1)
{
- target = m_ThreatManager.getHostilTarget();
+ // We do not have last taunt aura caster but we have more taunt auras,
+ // so find first available target
+
+ // Auras are pushed_back, last caster will be on the end
+ AuraList::const_iterator aura = --tauntAuras.end();
+ do
+ {
+ --aura;
+ if ( (caster = (*aura)->GetCaster()) &&
+ caster->IsInMap(this) && canAttack(caster) && caster->isInAccessiblePlaceFor((Creature*)this) )
+ {
+ target = caster;
+ break;
+ }
+ }while (aura != tauntAuras.begin());
}
else
target = getVictim();
}
+ if ( !target && !m_ThreatManager.isThreatListEmpty() )
+ // No taunt aura or taunt aura caster is dead standart target selection
+ target = m_ThreatManager.getHostilTarget();
+
if(target)
{
if(!hasUnitState(UNIT_STAT_STUNNED))
@@ -9640,21 +9679,15 @@ DiminishingLevels Unit::GetDiminishing(DiminishingGroup group)
void Unit::IncrDiminishing(DiminishingGroup group)
{
// Checking for existing in the table
- bool IsExist = false;
for(Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
{
if(i->DRGroup != group)
continue;
-
- IsExist = true;
if(i->hitCount < DIMINISHING_LEVEL_IMMUNE)
i->hitCount += 1;
-
- break;
+ return;
}
-
- if(!IsExist)
- m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2));
+ m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2));
}
void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level)
@@ -9703,13 +9736,15 @@ void Unit::ApplyDiminishingAura( DiminishingGroup group, bool apply )
if(i->DRGroup != group)
continue;
- i->hitTime = getMSTime();
-
if(apply)
i->stack += 1;
else if(i->stack)
+ {
i->stack -= 1;
-
+ // Remember time after last aura from group removed
+ if (i->stack == 0)
+ i->hitTime = getMSTime();
+ }
break;
}
}
@@ -12100,7 +12135,7 @@ void Unit::AddAura(uint32 spellId, Unit* target)
{
if(spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
{
- if(target->IsImmunedToSpellEffect(spellInfo->Effect[i], spellInfo->EffectMechanic[i]))
+ if(target->IsImmunedToSpellEffect(spellInfo, i))
continue;
if(spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_CASTER)