diff options
| author | ariel- <ariel-@users.noreply.github.com> | 2016-11-15 22:39:15 -0300 |
|---|---|---|
| committer | ariel- <ariel-@users.noreply.github.com> | 2016-11-15 22:39:15 -0300 |
| commit | ca1c4525c7da320da2c0a55bfd803879e3cf60b2 (patch) | |
| tree | cb5d58e7594adf2b623cb4087e972ed24281cd07 | |
| parent | 524d6637ad910c904133642a22ecdec14bb2929c (diff) | |
Core/Unit: damage immune improvements (9f5df023b746d324588f175e264c62205b69e165 follow up)
- Handling checked in sniffs: Spell 63710 Void Barrier vs 49143 Frost Strike
* Send spell miss immune only if spell consists of damage effects
- Checked with 348 Immolate:
* No packets sent if damage immune, aura is applied normally
Also... who the fuck uses 0 to compare against pointers
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 33 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 32 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 25 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellInfo.h | 1 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 16 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp | 6 |
8 files changed, 80 insertions, 40 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2b6c16c4d2a..2ba3b9365e4 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -665,12 +665,6 @@ void Unit::DealDamageMods(Unit const* victim, uint32 &damage, uint32* absorb) co uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss) { - if (victim->IsImmunedToDamage(spellProto)) - { - SendSpellDamageImmune(victim, spellProto->Id); - return 0; - } - if (victim->IsAIEnabled) victim->GetAI()->DamageTaken(this, damage); @@ -1086,23 +1080,6 @@ void Unit::CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castI CastSpell(targets, spellInfo, nullptr, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster); } -// Obsolete func need remove, here only for comotability vs another patches -uint32 Unit::SpellNonMeleeDamageLog(Unit* victim, uint32 spellID, uint32 damage) -{ - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID); - if (!spellInfo) - return 0; - SpellNonMeleeDamage damageInfo(this, victim, spellInfo->Id, spellInfo->SchoolMask); - damage = SpellDamageBonusDone(victim, spellInfo, damage, SPELL_DIRECT_DAMAGE); - damage = victim->SpellDamageBonusTaken(this, spellInfo, damage, SPELL_DIRECT_DAMAGE); - - CalculateSpellDamageTaken(&damageInfo, damage, spellInfo); - DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); - SendSpellNonMeleeDamageLog(&damageInfo); - DealSpellDamage(&damageInfo, true); - return damageInfo.damage; -} - void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit) { if (damage < 0) @@ -1216,11 +1193,10 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss) { - if (damageInfo == 0) + if (!damageInfo) return; Unit* victim = damageInfo->target; - if (!victim) return; @@ -1567,7 +1543,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) data << uint32(i_spellProto->SchoolMask); victim->SendMessageToSet(&data, true); - victim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true); + victim->DealDamage(this, damage, nullptr, SPELL_DIRECT_DAMAGE, spellInfo->GetSchoolMask(), spellInfo, true); } } } @@ -2693,6 +2669,11 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spellInfo, boo if (victim->IsImmunedToSpell(spellInfo)) return SPELL_MISS_IMMUNE; + // Damage immunity is only checked if the spell has damage effects, this immunity must not prevent aura apply + // returns SPELL_MISS_IMMUNE in that case, for other spells, the SMSG_SPELL_GO must show hit + if (spellInfo->HasOnlyDamageEffects() && victim->IsImmunedToDamage(spellInfo)) + return SPELL_MISS_IMMUNE; + // All positive spells can`t miss /// @todo client not show miss log for this spells - so need find info for this in dbc and use it! if (spellInfo->IsPositive() && !IsHostileTo(victim)) // prevent from affecting enemy by "positive" spell diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index f2135583c78..b0d90382d65 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1560,7 +1560,6 @@ class TC_GAME_API Unit : public WorldObject int32 HealBySpell(HealInfo& healInfo, bool critical = false); void SendEnergizeSpellLog(Unit* victim, uint32 spellID, int32 damage, Powers powerType); void EnergizeBySpell(Unit* victim, uint32 SpellID, int32 Damage, Powers powertype); - uint32 SpellNonMeleeDamageLog(Unit* victim, uint32 spellID, uint32 damage); void CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo, CustomSpellValues const* value, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); void CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 8631c94c98a..38e7ad0af89 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6176,6 +6176,12 @@ void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEv Unit* target = aurApp->GetTarget(); Unit* triggerTarget = eventInfo.GetProcTarget(); + if (triggerTarget->HasUnitState(UNIT_STATE_ISOLATED) || triggerTarget->IsImmunedToDamage(GetSpellInfo())) + { + SendTickImmune(triggerTarget, target); + return; + } + SpellNonMeleeDamage damageInfo(target, triggerTarget, GetId(), GetSpellInfo()->SchoolMask); uint32 damage = target->SpellDamageBonusDone(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE); damage = triggerTarget->SpellDamageBonusTaken(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 92eed603789..8336f458926 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2442,15 +2442,29 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) // Fill base damage struct (unitTarget - is real spell target) SpellNonMeleeDamage damageInfo(caster, unitTarget, m_spellInfo->Id, m_spellSchoolMask); - // Add bonuses and fill damageInfo struct - caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit); - caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); + // Check damage immunity + if (unitTarget->IsImmunedToDamage(m_spellInfo)) + { + hitMask = PROC_HIT_IMMUNE; + m_damage = 0; - // Send log damage message to client - caster->SendSpellNonMeleeDamageLog(&damageInfo); + // no packet found in sniffs + } + else + { + // Add bonuses and fill damageInfo struct + caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit); + caster->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb); - hitMask |= createProcHitMask(&damageInfo, missInfo); - procVictim |= PROC_FLAG_TAKEN_DAMAGE; + // Send log damage message to client + caster->SendSpellNonMeleeDamageLog(&damageInfo); + + hitMask |= createProcHitMask(&damageInfo, missInfo); + procVictim |= PROC_FLAG_TAKEN_DAMAGE; + + m_damage = damageInfo.damage; + caster->DealSpellDamage(&damageInfo, true); + } // Do triggers for unit if (canEffectTrigger) @@ -2462,10 +2476,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) (m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MELEE || m_spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)) caster->ToPlayer()->CastItemCombatSpell(spellDamageInfo); } - - m_damage = damageInfo.damage; - - caster->DealSpellDamage(&damageInfo, true); } // Passive spell hits/misses or active spells only misses (only triggers) else diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 8657b122de1..d2edbbc4d4f 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -895,6 +895,31 @@ bool SpellInfo::HasAreaAuraEffect() const return false; } +bool SpellInfo::HasOnlyDamageEffects() const +{ + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (Effects[i].IsEffect()) + { + switch (Effects[i].Effect) + { + case SPELL_EFFECT_WEAPON_DAMAGE: + case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL: + case SPELL_EFFECT_NORMALIZED_WEAPON_DMG: + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + case SPELL_EFFECT_SCHOOL_DAMAGE: + case SPELL_EFFECT_ENVIRONMENTAL_DAMAGE: + case SPELL_EFFECT_HEALTH_LEECH: + continue; + default: + return false; + } + } + } + + return true; +} + bool SpellInfo::IsExplicitDiscovery() const { return ((Effects[0].Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 4b2eff28bd6..d7b48ddb4d2 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -402,6 +402,7 @@ class TC_GAME_API SpellInfo bool HasEffect(SpellEffects effect) const; bool HasAura(AuraType aura) const; bool HasAreaAuraEffect() const; + bool HasOnlyDamageEffects() const; inline bool HasAttribute(SpellAttr0 attribute) const { return !!(Attributes & attribute); } inline bool HasAttribute(SpellAttr1 attribute) const { return !!(AttributesEx & attribute); } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 1e4daaea2d2..5487b9c7b2f 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -2289,10 +2289,22 @@ public: // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form uint32 spellid = handler->extractSpellIdFromLink((char*)args); - if (!spellid || !sSpellMgr->GetSpellInfo(spellid)) + if (!spellid) return false; - handler->GetSession()->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage); + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); + if (!spellInfo) + return false; + + Player* attacker = handler->GetSession()->GetPlayer(); + SpellNonMeleeDamage dmgInfo(attacker, target, spellid, spellInfo->GetSchoolMask()); + damage = attacker->SpellDamageBonusDone(target, spellInfo, damage, SPELL_DIRECT_DAMAGE); + damage = target->SpellDamageBonusTaken(attacker, spellInfo, damage, SPELL_DIRECT_DAMAGE); + + attacker->CalculateSpellDamageTaken(&dmgInfo, damage, spellInfo); + attacker->DealDamageMods(dmgInfo.target, dmgInfo.damage, &dmgInfo.absorb); + attacker->SendSpellNonMeleeDamageLog(&dmgInfo); + attacker->DealSpellDamage(&dmgInfo, true); return true; } diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index a2348119dff..f3021cdbab5 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -1099,6 +1099,12 @@ class spell_sindragosa_s_fury : public SpellScriptLoader if (!GetHitUnit()->IsAlive() || !_targetCount) return; + if (GetHitUnit()->IsImmunedToDamage(GetSpellInfo())) + { + GetCaster()->SendSpellDamageImmune(GetHitUnit(), GetSpellInfo()->Id); + return; + } + float resistance = float(GetHitUnit()->GetResistance(SpellSchoolMask(GetSpellInfo()->SchoolMask))); uint32 minResistFactor = uint32((resistance / (resistance + 510.0f)) * 10.0f) * 2; uint32 randomResist = urand(0, (9 - minResistFactor) * 100) / 100 + minResistFactor; |
