aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2016-11-15 22:39:15 -0300
committerariel- <ariel-@users.noreply.github.com>2016-11-15 22:39:15 -0300
commitca1c4525c7da320da2c0a55bfd803879e3cf60b2 (patch)
treecb5d58e7594adf2b623cb4087e972ed24281cd07
parent524d6637ad910c904133642a22ecdec14bb2929c (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.cpp33
-rw-r--r--src/server/game/Entities/Unit/Unit.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp6
-rw-r--r--src/server/game/Spells/Spell.cpp32
-rw-r--r--src/server/game/Spells/SpellInfo.cpp25
-rw-r--r--src/server/game/Spells/SpellInfo.h1
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp16
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp6
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;