Core/Unit: damage immune improvements
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user