diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Spell.cpp | 14 | ||||
-rw-r--r-- | src/game/Spell.h | 1 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 13 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 10 | ||||
-rw-r--r-- | src/game/SpellMgr.cpp | 31 | ||||
-rw-r--r-- | src/game/SpellMgr.h | 4 | ||||
-rw-r--r-- | src/game/Unit.cpp | 35 | ||||
-rw-r--r-- | src/game/Unit.h | 1 |
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 |