aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Spell.cpp14
-rw-r--r--src/game/Spell.h1
-rw-r--r--src/game/SpellAuras.cpp13
-rw-r--r--src/game/SpellEffects.cpp10
-rw-r--r--src/game/SpellMgr.cpp31
-rw-r--r--src/game/SpellMgr.h4
-rw-r--r--src/game/Unit.cpp35
-rw-r--r--src/game/Unit.h1
8 files changed, 64 insertions, 45 deletions
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 378e6f0b2bc..07a70f6bc17 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -671,11 +671,6 @@ void Spell::prepareDataForTriggerSystem()
// Create base triggers flags for Attacker and Victim ( m_procAttacker and m_procVictim)
//==========================================================================================
- m_canTrigger = true;
-
- if (m_CastItem && m_spellInfo->SpellFamilyName != SPELLFAMILY_POTION)
- m_canTrigger = false; // Do not trigger from item cast spell(except potions)
-
// Get data for type of attack and fill base info for trigger
switch (m_spellInfo->DmgClass)
{
@@ -958,7 +953,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
procEx |= PROC_EX_NORMAL_HIT;
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
+ if (missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo);
if (m_spellAura)
@@ -983,7 +978,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE;
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
+ if (missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo);
if (m_spellAura)
@@ -1005,7 +1000,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask);
procEx |= createProcExtendMask(&damageInfo, missInfo);
// Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
- if (m_canTrigger && missInfo != SPELL_MISS_REFLECT)
+ if (missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo);
}
@@ -1039,8 +1034,7 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
// Recheck immune (only for delayed spells)
if( m_spellInfo->speed &&
- !(m_spellInfo->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
- && (unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo)) ||
+ (unit->IsImmunedToDamage(m_spellInfo) ||
unit->IsImmunedToSpell(m_spellInfo)))
{
m_caster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_IMMUNE);
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 9470849c168..a18538879b4 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -542,7 +542,6 @@ class Spell
//******************************************
// Spell trigger system
//******************************************
- bool m_canTrigger; // Can start trigger (m_IsTriggeredSpell can`t use for this)
uint32 m_procAttacker; // Attacker trigger flags
uint32 m_procVictim; // Victim trigger flags
void prepareDataForTriggerSystem();
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index bba2dee3973..2be8a8e890e 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -4102,8 +4102,7 @@ void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real)
for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
{
SpellEntry const *spell = iter->second->GetSpellProto();
- if (!( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) && // spells unaffected by invulnerability
- spell->Id != GetId())
+ if (spell->Id != GetId())
{
//check for mechanic mask
if(GetAllSpellMechanicMask(spell) & mechanic)
@@ -4228,7 +4227,7 @@ void AuraEffect::HandleAuraModSchoolImmunity(bool apply, bool Real)
{
SpellEntry const *spell = iter->second->GetSpellProto();
if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
- && !( spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) //Spells unaffected by invulnerability
+ && IsDispelableBySpell(GetSpellProto(),spell->Id, true)
&& !iter->second->IsPositive() //Don't remove positive spells
&& spell->Id != GetId() ) //Don't remove self
{
@@ -5650,7 +5649,7 @@ void AuraEffect::PeriodicTick()
return;
// Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
// some auras remove at specific health level or more
@@ -5789,7 +5788,7 @@ void AuraEffect::PeriodicTick()
return;
// Check for immune
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
uint32 absorb=0;
@@ -5967,7 +5966,7 @@ void AuraEffect::PeriodicTick()
return;
// Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
// ignore non positive values (can be result apply spellmods to aura damage
@@ -6126,7 +6125,7 @@ void AuraEffect::PeriodicTick()
return;
// Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellSchoolMask(GetSpellProto())))
+ if(m_target->IsImmunedToDamage(GetSpellProto()))
return;
int32 pdamage = m_amount > 0 ? m_amount : 0;
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 6e619b0e36c..e1fcae5f1a0 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -338,14 +338,6 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
switch(m_spellInfo->Id) // better way to check unknown
{
- case 35354: //Hand of Death
- {
- if(unitTarget && unitTarget->HasAura(38528)) //Protection of Elune
- {
- damage = 0;
- }
- break;
- }
// percent from health with min
case 25599: // Thundercrash
{
@@ -451,7 +443,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
Unit::AuraEffectList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
for(Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
{
- if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags[0] & 4) &&
+ if( (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && ((*i)->GetSpellProto()->SpellFamilyFlags[0] & 4 || (*i)->GetSpellProto()->SpellFamilyFlags[2] & 2) &&
(*i)->GetCasterGUID()==m_caster->GetGUID() )
{
unitTarget->RemoveAurasDueToSpell((*i)->GetId(), m_caster->GetGUID());
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 0bd5832d354..15d6279bcd0 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -751,6 +751,24 @@ bool IsPositiveSpell(uint32 spellId, bool deep)
return true;
}
+bool IsDispelableBySpell(SpellEntry const * dispelSpell, uint32 spellId, bool def)
+{
+ if (!dispelSpell) return false;
+ SpellEntry const *spellproto = sSpellStore.LookupEntry(spellId);
+ if (!spellproto) return false;
+
+ if (spellproto->Mechanic == MECHANIC_IMMUNE_SHIELD)
+ {
+ if (dispelSpell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
+ {
+ return true;
+ }
+ else
+ return false;
+ }
+ return def;
+}
+
bool IsSingleTargetSpell(SpellEntry const *spellInfo)
{
// all other single target spells have if it has AttributesEx5
@@ -1201,14 +1219,13 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
}
else // For spells need check school/spell family/family mask
{
- // Potions can trigger only if spellfamily given
- if (procSpell->SpellFamilyName == SPELLFAMILY_POTION)
+ // Item cast can trigger only with spells with spellfamily
+ if (procExtra & PROC_EX_INTERNAL_ITEM_CAST && procSpell->SpellFamilyName)
{
if (procSpell->SpellFamilyName == spellProcEvent->spellFamilyName)
return true;
return false;
}
-
// Check (if set) for school
if(spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpell->SchoolMask) == 0)
return false;
@@ -1226,8 +1243,8 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
}
}
}
- // potions can trigger only if have spell_proc entry
- else if (procSpell && procSpell->SpellFamilyName==SPELLFAMILY_POTION)
+ // Item cast can trigger only with spells with spellfamily
+ else if (procExtra & PROC_EX_INTERNAL_ITEM_CAST)
return false;
// Check for extra req (if none) and hit/crit
@@ -2310,10 +2327,10 @@ void SpellMgr::LoadSpellCustomAttr()
spellInfo->speed = SPEED_CHARGE;
mSpellCustomAttr[i] |= SPELL_ATTR_CU_CHARGE;
case SPELL_EFFECT_TRIGGER_SPELL:
- //if(spellInfo->Targets & (TARGET_FLAG_SOURCE_LOCATION|TARGET_FLAG_DEST_LOCATION))
if (SpellTargetType[spellInfo->EffectImplicitTargetA[j]]== TARGET_TYPE_DEST_CASTER ||
SpellTargetType[spellInfo->EffectImplicitTargetA[j]]== TARGET_TYPE_DEST_TARGET ||
- SpellTargetType[spellInfo->EffectImplicitTargetA[j]]== TARGET_TYPE_DEST_DEST)
+ SpellTargetType[spellInfo->EffectImplicitTargetA[j]]== TARGET_TYPE_DEST_DEST ||
+ spellInfo->Targets & (TARGET_FLAG_SOURCE_LOCATION|TARGET_FLAG_DEST_LOCATION))
spellInfo->Effect[j] = SPELL_EFFECT_TRIGGER_MISSILE;
break;
}
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 976a147dbd1..e7f9d81d5dd 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -240,6 +240,7 @@ inline bool IsNonCombatSpell(SpellEntry const *spellInfo)
bool IsPositiveSpell(uint32 spellId, bool deep = false);
bool IsPositiveEffect(uint32 spellId, uint32 effIndex, bool deep = false);
bool IsPositiveTarget(uint32 targetA, uint32 targetB);
+bool IsDispelableBySpell(SpellEntry const * dispelSpell, uint32 spellId, bool def = false);
bool IsSingleTargetSpell(SpellEntry const *spellInfo);
bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2);
@@ -436,7 +437,8 @@ enum ProcFlagsEx
PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, // aura remove by default and by cancel
PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always ( no matter another flags) used for drop charges
PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not used)
- PROC_EX_INTERNAL_TRIGGERED = 0x4000000 // Only for internal use
+ PROC_EX_INTERNAL_TRIGGERED = 0x4000000, // Only for internal use
+ PROC_EX_INTERNAL_ITEM_CAST = 0x8000000
};
#define AURA_REMOVE_PROC_EX_MASK \
(PROC_EX_AURA_REMOVE_DESTROY | PROC_EX_AURA_REMOVE_EXPIRE)
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index bd6e494c23a..1ebbd606c2f 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -2890,10 +2890,6 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
if (pVictim->GetTypeId()==TYPEID_UNIT && ((Creature*)pVictim)->IsInEvadeMode())
return SPELL_MISS_EVADE;
- // If Spel has this flag cannot be resisted/immuned/etc
- if (spell->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)
- return SPELL_MISS_NONE;
-
// Check for immune
if (pVictim->IsImmunedToSpell(spell))
return SPELL_MISS_IMMUNE;
@@ -2903,9 +2899,8 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
if (IsPositiveSpell(spell->Id)
&&(!IsHostileTo(pVictim))) //prevent from affecting enemy by "positive" spell
return SPELL_MISS_NONE;
-
// Check for immune
- if (pVictim->IsImmunedToDamage(GetSpellSchoolMask(spell)))
+ if (pVictim->IsImmunedToDamage(spell))
return SPELL_MISS_IMMUNE;
if(this == pVictim)
@@ -9266,6 +9261,29 @@ bool Unit::IsImmunedToDamage(SpellSchoolMask shoolMask)
return false;
}
+bool Unit::IsImmunedToDamage(SpellEntry const* spellInfo)
+{
+ uint32 shoolMask = GetSpellSchoolMask(spellInfo);
+ if( !(spellInfo->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE) && // unaffected by school immunity
+ !(spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) // can remove immune (by dispell or immune it)
+ && (spellInfo->Id != 42292))
+ {
+ //If m_immuneToSchool type contain this school type, IMMUNE damage.
+ SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
+ for (SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
+ if(itr->type & shoolMask &&!IsDispelableBySpell(spellInfo, itr->spellId))
+ return true;
+ }
+
+ //If m_immuneToDamage type contain magic, IMMUNE damage.
+ SpellImmuneList const& damageList = m_spellImmune[IMMUNITY_DAMAGE];
+ for (SpellImmuneList::const_iterator itr = damageList.begin(); itr != damageList.end(); ++itr)
+ if(itr->type & shoolMask)
+ return true;
+
+ return false;
+}
+
bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
{
if (!spellInfo)
@@ -9283,7 +9301,7 @@ bool Unit::IsImmunedToSpell(SpellEntry const* spellInfo)
SpellImmuneList const& schoolList = m_spellImmune[IMMUNITY_SCHOOL];
for(SpellImmuneList::const_iterator itr = schoolList.begin(); itr != schoolList.end(); ++itr)
if( !(IsPositiveSpell(itr->spellId) && IsPositiveSpell(spellInfo->Id)) &&
- (itr->type & GetSpellSchoolMask(spellInfo)) )
+ (itr->type & GetSpellSchoolMask(spellInfo)) && !IsDispelableBySpell(spellInfo, itr->spellId))
return true;
}
@@ -11635,7 +11653,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
if(!IsTriggeredAtSpellProcEvent(pTarget, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, (damage > 0), triggerData.spellProcEvent))
continue;
-
for (uint8 i=0; i<MAX_SPELL_EFFECTS;++i)
{
if (AuraEffect * aurEff = itr->second->GetPartAura(i))
@@ -11646,7 +11663,6 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
// If not trigger by default and spellProcEvent==NULL - skip
if (!isTriggerAura[aurEff->GetAuraName()] && triggerData.spellProcEvent==NULL)
continue;
-
triggerData.effMask |= 1<<i;
}
}
@@ -12456,7 +12472,6 @@ bool Unit::IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry co
// Check spellProcEvent data requirements
if(!spellmgr.IsSpellProcEventCanTriggeredBy(spellProcEvent, EventProcFlag, procSpell, procFlag, procExtra, active))
return false;
-
// In most cases req get honor or XP from kill
if (EventProcFlag & PROC_FLAG_KILL && GetTypeId() == TYPEID_PLAYER)
{
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 06ed28d9f0f..983f6a023ef 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1528,6 +1528,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
virtual bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefined in Creature
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask);
+ bool IsImmunedToDamage(SpellEntry const* spellInfo);
virtual bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
// redefined in Creature