diff options
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 50db01b3fec..86e1d7f292a 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2434,7 +2434,9 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= // Calculate hit result WorldObject* caster = m_originalCaster ? m_originalCaster : m_caster; - targetInfo.MissCondition = caster->SpellHitResult(target, m_spellInfo, m_canReflect && !(IsPositive() && m_caster->IsFriendlyTo(target))); + targetInfo.MissCondition = caster->SpellHitResult(target, m_spellInfo, + m_canReflect && !(IsPositive() && m_caster->IsFriendlyTo(target)), + false /*immunity will be checked after complete EffectMask is known*/); // Spell have speed - need calculate incoming time // Incoming time is zero for self casts. At least I think so. @@ -2479,7 +2481,9 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= { // Calculate reflected spell result on caster (shouldn't be able to reflect gameobject spells) Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit()); - targetInfo.ReflectResult = unitCaster->SpellHitResult(unitCaster, m_spellInfo, false); // can't reflect twice + targetInfo.ReflectResult = unitCaster->SpellHitResult(unitCaster, m_spellInfo, + false /*can't reflect twice*/, + false /*immunity will be checked after complete EffectMask is known*/); // Proc spell reflect aura when missile hits the original target target->m_Events.AddEvent(new ProcReflectDelayed(target, m_originalCasterGUID), target->m_Events.CalculateTime(Milliseconds(targetInfo.TimeDelay))); @@ -3099,7 +3103,7 @@ SpellMissInfo Spell::PreprocessSpellHit(Unit* unit, TargetInfo& hitInfo) return SPELL_MISS_EVADE; // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case - if (hitInfo.TimeDelay && unit->IsImmunedToSpell(m_spellInfo, m_caster)) + if (hitInfo.TimeDelay && unit->IsImmunedToSpell(m_spellInfo, hitInfo.EffectMask, m_caster)) return SPELL_MISS_IMMUNE; CallScriptBeforeHitHandlers(hitInfo.MissCondition); @@ -3620,8 +3624,6 @@ void Spell::cancel() SendChannelUpdate(0, SPELL_FAILED_INTERRUPTED); SendInterrupted(0); SendCastResult(SPELL_FAILED_INTERRUPTED); - - m_appliedMods.clear(); break; default: break; @@ -5086,7 +5088,7 @@ static std::pair<int32, SpellHealPredictionType> CalcPredictedHealing(SpellInfo case SPELL_AURA_OBS_MOD_HEALTH: points += unitCaster->SpellHealingBonusDone(target, spellInfo, spellEffectInfo.CalcValue(unitCaster, nullptr, target, nullptr, castItemEntry, castItemLevel), - DIRECT_DAMAGE, spellEffectInfo, 1, spell) * spellInfo->GetMaxTicks(); + DIRECT_DAMAGE, spellEffectInfo, 1, spell) * spellEffectInfo.GetPeriodicTickCount(); break; case SPELL_AURA_PERIODIC_TRIGGER_SPELL: if (SpellInfo const* triggered = sSpellMgr->GetSpellInfo(spellEffectInfo.TriggerSpell, spellInfo->Difficulty)) @@ -8612,6 +8614,10 @@ void Spell::PreprocessSpellLaunch(TargetInfo& targetInfo) if (!targetUnit) return; + // Check immunity now that EffectMask is known + if (targetUnit->IsImmunedToSpell(GetSpellInfo(), targetInfo.EffectMask, m_caster)) + targetInfo.MissCondition = SPELL_MISS_IMMUNE; + // This will only cause combat - the target will engage once the projectile hits (in Spell::TargetInfo::PreprocessTarget) if (m_originalCaster && targetInfo.MissCondition != SPELL_MISS_EVADE && !m_originalCaster->IsFriendlyTo(targetUnit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || targetUnit->IsEngaged())) m_originalCaster->SetInCombatWith(targetUnit, true); @@ -8622,7 +8628,11 @@ void Spell::PreprocessSpellLaunch(TargetInfo& targetInfo) unit = targetUnit; // In case spell reflect from target, do all effect on caster (if hit) else if (targetInfo.MissCondition == SPELL_MISS_REFLECT && targetInfo.ReflectResult == SPELL_MISS_NONE) + { unit = m_caster->ToUnit(); + if (unit && unit->IsImmunedToSpell(GetSpellInfo(), targetInfo.EffectMask, unit)) + targetInfo.ReflectResult = SPELL_MISS_IMMUNE; + } if (!unit) return; |
