Core/Unit: damage immune improvements

This commit is contained in:
hondacrx
2017-12-30 17:53:28 -05:00
parent 0713188d5f
commit 01caaecf0f
6 changed files with 87 additions and 38 deletions
+12 -8
View File
@@ -2039,12 +2039,14 @@ namespace Game.Chat
string schoolStr = args.NextString();
Player attacker = handler.GetSession().GetPlayer();
// flat melee damage without resistence/etc reduction
if (string.IsNullOrEmpty(schoolStr))
{
handler.GetSession().GetPlayer().DealDamage(target, damage_, null, DamageEffectType.Direct, SpellSchoolMask.Normal, null, false);
if (target != handler.GetSession().GetPlayer())
handler.GetSession().GetPlayer().SendAttackStateUpdate(HitInfo.AffectsVictim, target, SpellSchoolMask.Normal, damage_, 0, 0, VictimState.Hit, 0);
attacker.DealDamage(target, damage_, null, DamageEffectType.Direct, SpellSchoolMask.Normal, null, false);
if (target != attacker)
attacker.SendAttackStateUpdate(HitInfo.AffectsVictim, target, SpellSchoolMask.Normal, damage_, 0, 0, VictimState.Hit, 0);
return true;
}
@@ -2053,15 +2055,14 @@ namespace Game.Chat
SpellSchoolMask schoolmask = (SpellSchoolMask)(1 << school);
if (handler.GetSession().GetPlayer().IsDamageReducedByArmor(schoolmask))
damage_ = handler.GetSession().GetPlayer().CalcArmorReducedDamage(handler.GetPlayer(), target, damage_, null, WeaponAttackType.BaseAttack);
if (attacker.IsDamageReducedByArmor(schoolmask))
damage_ = attacker.CalcArmorReducedDamage(handler.GetPlayer(), target, damage_, null, WeaponAttackType.BaseAttack);
string spellStr = args.NextString();
// melee damage by specific school
if (string.IsNullOrEmpty(spellStr))
{
Player attacker = handler.GetSession().GetPlayer();
DamageInfo dmgInfo = new DamageInfo(attacker, target, damage_, null, schoolmask, DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack);
attacker.CalcAbsorbResist(dmgInfo);
@@ -2081,13 +2082,16 @@ namespace Game.Chat
// non-melee damage
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint spellid = handler.extractSpellIdFromLink(args);
if (spellid == 0)
return false;
SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellid);
if (spellInfo == null)
return false;
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(handler.GetSession().GetPlayer(), target, spellid, spellInfo.GetSpellXSpellVisualId(handler.GetSession().GetPlayer()), spellInfo.SchoolMask);
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(attacker, target, spellid, spellInfo.GetSpellXSpellVisualId(attacker), spellInfo.SchoolMask);
damageInfo.damage = damage_;
handler.GetSession().GetPlayer().DealDamageMods(damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
attacker.DealDamageMods(damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
target.DealSpellDamage(damageInfo, true);
target.SendSpellNonMeleeDamageLog(damageInfo);
return true;
+13 -18
View File
@@ -810,19 +810,20 @@ namespace Game.Entities
var vDamageShieldsCopy = victim.GetAuraEffectsByType(AuraType.DamageShield);
foreach (var dmgShield in vDamageShieldsCopy)
{
SpellInfo i_spellProto = dmgShield.GetSpellInfo();
SpellInfo spellInfo = dmgShield.GetSpellInfo();
// Damage shield can be resisted...
var missInfo = victim.SpellHitResult(this, i_spellProto, false);
if (missInfo != 0)
var missInfo = victim.SpellHitResult(this, spellInfo, false);
if (missInfo != SpellMissInfo.None)
{
victim.SendSpellMiss(this, i_spellProto.Id, missInfo);
victim.SendSpellMiss(this, spellInfo.Id, missInfo);
continue;
}
// ...or immuned
if (IsImmunedToDamage(i_spellProto))
if (IsImmunedToDamage(spellInfo))
{
victim.SendSpellDamageImmune(this, i_spellProto.Id, false);
victim.SendSpellDamageImmune(this, spellInfo.Id, false);
continue;
}
@@ -830,11 +831,11 @@ namespace Game.Entities
Unit caster = dmgShield.GetCaster();
if (caster)
{
damage = caster.SpellDamageBonusDone(this, i_spellProto, damage, DamageEffectType.SpellDirect, dmgShield.GetSpellEffectInfo());
damage = SpellDamageBonusTaken(caster, i_spellProto, damage, DamageEffectType.SpellDirect, dmgShield.GetSpellEffectInfo());
damage = caster.SpellDamageBonusDone(this, spellInfo, damage, DamageEffectType.SpellDirect, dmgShield.GetSpellEffectInfo());
damage = SpellDamageBonusTaken(caster, spellInfo, damage, DamageEffectType.SpellDirect, dmgShield.GetSpellEffectInfo());
}
DamageInfo damageInfo1 = new DamageInfo(this, victim, damage, i_spellProto, i_spellProto.GetSchoolMask(), DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack);
DamageInfo damageInfo1 = new DamageInfo(this, victim, damage, spellInfo, spellInfo.GetSchoolMask(), DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack);
victim.CalcAbsorbResist(damageInfo1);
damage = damageInfo1.GetDamage();
// No Unit.CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that
@@ -843,13 +844,13 @@ namespace Game.Entities
SpellDamageShield damageShield = new SpellDamageShield();
damageShield.Attacker = victim.GetGUID();
damageShield.Defender = GetGUID();
damageShield.SpellID = i_spellProto.Id;
damageShield.SpellID = spellInfo.Id;
damageShield.TotalDamage = damage;
damageShield.OverKill = (uint)Math.Max(damage - GetHealth(), 0);
damageShield.SchoolMask = (uint)i_spellProto.SchoolMask;
damageShield.SchoolMask = (uint)spellInfo.SchoolMask;
damageShield.LogAbsorbed = damageInfo1.GetAbsorb();
victim.DealDamage(this, damage, null, DamageEffectType.SpellDirect, i_spellProto.GetSchoolMask(), i_spellProto, true);
victim.DealDamage(this, damage, null, DamageEffectType.SpellDirect, spellInfo.GetSchoolMask(), spellInfo, true);
damageShield.LogData.Initialize(this);
victim.SendCombatLogMessage(damageShield);
@@ -858,12 +859,6 @@ namespace Game.Entities
}
public uint DealDamage(Unit victim, uint damage, CleanDamage cleanDamage = null, DamageEffectType damagetype = DamageEffectType.Direct, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal, SpellInfo spellProto = null, bool durabilityLoss = true)
{
if (victim.IsImmunedToDamage(spellProto))
{
SendSpellDamageImmune(victim, spellProto.Id, false);
return 0;
}
if (victim.IsAIEnabled)
victim.GetAI().DamageTaken(this, ref damage);
+5
View File
@@ -803,6 +803,11 @@ namespace Game.Entities
if (victim.IsImmunedToSpell(spellInfo))
return SpellMissInfo.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 SpellMissInfo.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()
+6
View File
@@ -5797,6 +5797,12 @@ namespace Game.Spells
{
Unit target = aurApp.GetTarget();
Unit triggerTarget = eventInfo.GetProcTarget();
if (triggerTarget.HasUnitState(UnitState.Isolated) || triggerTarget.IsImmunedToDamage(GetSpellInfo()))
{
SendTickImmune(triggerTarget, target);
return;
}
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(target, triggerTarget, GetId(), GetBase().GetSpellXSpellVisualId(), GetSpellInfo().SchoolMask, GetBase().GetCastGUID());
int damage = (int)target.SpellDamageBonusDone(triggerTarget, GetSpellInfo(), (uint)GetAmount(), DamageEffectType.SpellDirect, GetSpellEffectInfo());
damage = (int)triggerTarget.SpellDamageBonusTaken(target, GetSpellInfo(), (uint)damage, DamageEffectType.SpellDirect, GetSpellEffectInfo());
+22 -12
View File
@@ -2001,12 +2001,29 @@ namespace Game.Spells
// Fill base damage struct (unitTarget - is real spell target)
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, unitTarget, m_spellInfo.Id, m_SpellVisual, m_spellSchoolMask, m_castId);
// Add bonuses and fill damageInfo struct
caster.CalculateSpellDamageTaken(damageInfo, m_damage, m_spellInfo, m_attackType, target.crit);
caster.DealDamageMods(damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
// Check damage immunity
if (unitTarget.IsImmunedToDamage(m_spellInfo))
{
hitMask = ProcFlagsHit.Immune;
m_damage = 0;
// 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, ref damageInfo.damage, ref damageInfo.absorb);
hitMask |= Unit.createProcHitMask(damageInfo, missInfo);
procVictim |= ProcFlags.TakenDamage;
hitMask |= Unit.createProcHitMask(damageInfo, missInfo);
procVictim |= ProcFlags.TakenDamage;
m_damage = (int)damageInfo.damage;
caster.DealSpellDamage(damageInfo, true);
// Send log damage message to client
caster.SendSpellNonMeleeDamageLog(damageInfo);
}
// Do triggers for unit
if (canEffectTrigger)
@@ -2018,13 +2035,6 @@ namespace Game.Spells
(m_spellInfo.DmgClass == SpellDmgClass.Melee || m_spellInfo.DmgClass == SpellDmgClass.Ranged))
caster.ToPlayer().CastItemCombatSpell(spellDamageInfo);
}
m_damage = (int)damageInfo.damage;
caster.DealSpellDamage(damageInfo, true);
// Send log damage message to client
caster.SendSpellNonMeleeDamageLog(damageInfo);
}
// Passive spell hits/misses or active spells only misses (only triggers)
else
+29
View File
@@ -311,6 +311,35 @@ namespace Game.Spells
return false;
}
public bool HasOnlyDamageEffects()
{
foreach (var pair in _effects)
{
foreach (SpellEffectInfo effect in pair.Value)
{
if (effect == null)
continue;
switch (effect.Effect)
{
case SpellEffectName.WeaponDamage:
case SpellEffectName.WeaponDamageNoschool:
case SpellEffectName.NormalizedWeaponDmg:
case SpellEffectName.WeaponPercentDamage:
case SpellEffectName.SchoolDamage:
case SpellEffectName.EnvironmentalDamage:
case SpellEffectName.HealthLeech:
case SpellEffectName.DamageFromMaxHealthPCT:
continue;
default:
return false;
}
}
}
return true;
}
public bool IsExplicitDiscovery()
{
SpellEffectInfo effect0 = GetEffect(Difficulty.None, 0);