Core/Spells: fixed up block mechanics
Port From (https://github.com/TrinityCore/TrinityCore/commit/9f084718277b01936435c66696084fc049f8f8cf)
This commit is contained in:
@@ -766,7 +766,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
bool canDodge = !spellInfo.HasAttribute(SpellAttr7.NoAttackDodge);
|
bool canDodge = !spellInfo.HasAttribute(SpellAttr7.NoAttackDodge);
|
||||||
bool canParry = !spellInfo.HasAttribute(SpellAttr7.NoAttackParry);
|
bool canParry = !spellInfo.HasAttribute(SpellAttr7.NoAttackParry);
|
||||||
bool canBlock = spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked);
|
bool canBlock = true;
|
||||||
|
|
||||||
// if victim is casting or cc'd it can't avoid attacks
|
// if victim is casting or cc'd it can't avoid attacks
|
||||||
if (victim.IsNonMeleeSpellCast(false, false, true) || victim.HasUnitState(UnitState.Controlled))
|
if (victim.IsNonMeleeSpellCast(false, false, true) || victim.HasUnitState(UnitState.Controlled))
|
||||||
@@ -776,7 +776,7 @@ namespace Game.Entities
|
|||||||
canBlock = false;
|
canBlock = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ranged attacks can only miss, resist and deflect
|
// Ranged attacks can only miss, resist and deflect and get blocked
|
||||||
if (attType == WeaponAttackType.RangedAttack)
|
if (attType == WeaponAttackType.RangedAttack)
|
||||||
{
|
{
|
||||||
canParry = false;
|
canParry = false;
|
||||||
@@ -790,7 +790,6 @@ namespace Game.Entities
|
|||||||
if (roll < tmp)
|
if (roll < tmp)
|
||||||
return SpellMissInfo.Deflect;
|
return SpellMissInfo.Deflect;
|
||||||
}
|
}
|
||||||
return SpellMissInfo.None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for attack from behind
|
// Check for attack from behind
|
||||||
@@ -1800,25 +1799,6 @@ namespace Game.Entities
|
|||||||
return (uint)crit_bonus;
|
return (uint)crit_bonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSpellBlocked(Unit victim, SpellInfo spellProto, WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
|
||||||
{
|
|
||||||
// These spells can't be blocked
|
|
||||||
if (spellProto != null && (spellProto.HasAttribute(SpellAttr0.NoActiveDefense) || spellProto.HasAttribute(SpellAttr3.AlwaysHit)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Can't block when casting/controlled
|
|
||||||
if (victim.IsNonMeleeSpellCast(false) || victim.HasUnitState(UnitState.Controlled))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (victim.HasAuraType(AuraType.IgnoreHitDirection) || victim.HasInArc(MathFunctions.PI, this))
|
|
||||||
{
|
|
||||||
float blockChance = GetUnitBlockChance(attackType, victim);
|
|
||||||
if (blockChance != 0 && RandomHelper.randChance(blockChance))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void _DeleteRemovedAuras()
|
public void _DeleteRemovedAuras()
|
||||||
{
|
{
|
||||||
while (!m_removedAuras.Empty())
|
while (!m_removedAuras.Empty())
|
||||||
@@ -1974,7 +1954,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateSpellDamageTaken(SpellNonMeleeDamage damageInfo, int damage, SpellInfo spellInfo, WeaponAttackType attackType = WeaponAttackType.BaseAttack, bool crit = false, Spell spell = null)
|
public void CalculateSpellDamageTaken(SpellNonMeleeDamage damageInfo, int damage, SpellInfo spellInfo, WeaponAttackType attackType = WeaponAttackType.BaseAttack, bool crit = false, bool blocked = false, Spell spell = null)
|
||||||
{
|
{
|
||||||
if (damage < 0)
|
if (damage < 0)
|
||||||
return;
|
return;
|
||||||
@@ -1991,7 +1971,6 @@ namespace Game.Entities
|
|||||||
if (IsDamageReducedByArmor(damageSchoolMask, spellInfo))
|
if (IsDamageReducedByArmor(damageSchoolMask, spellInfo))
|
||||||
damage = (int)CalcArmorReducedDamage(damageInfo.attacker, victim, (uint)damage, spellInfo, attackType);
|
damage = (int)CalcArmorReducedDamage(damageInfo.attacker, victim, (uint)damage, spellInfo, attackType);
|
||||||
|
|
||||||
bool blocked = false;
|
|
||||||
// Per-school calc
|
// Per-school calc
|
||||||
switch (spellInfo.DmgClass)
|
switch (spellInfo.DmgClass)
|
||||||
{
|
{
|
||||||
@@ -1999,17 +1978,6 @@ namespace Game.Entities
|
|||||||
case SpellDmgClass.Ranged:
|
case SpellDmgClass.Ranged:
|
||||||
case SpellDmgClass.Melee:
|
case SpellDmgClass.Melee:
|
||||||
{
|
{
|
||||||
// Physical Damage
|
|
||||||
if (damageSchoolMask.HasAnyFlag(SpellSchoolMask.Normal))
|
|
||||||
{
|
|
||||||
// Spells with this attribute were already calculated in MeleeSpellHitResult
|
|
||||||
if (!spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked))
|
|
||||||
{
|
|
||||||
// Get blocked status
|
|
||||||
blocked = IsSpellBlocked(victim, spellInfo, attackType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crit)
|
if (crit)
|
||||||
{
|
{
|
||||||
damageInfo.HitInfo |= HitInfo.CriticalHit;
|
damageInfo.HitInfo |= HitInfo.CriticalHit;
|
||||||
|
|||||||
@@ -3920,7 +3920,7 @@ namespace Game.Spells
|
|||||||
// possibly SPELL_MISS_IMMUNE2 for this??
|
// possibly SPELL_MISS_IMMUNE2 for this??
|
||||||
targetInfo.MissCondition = SpellMissInfo.Immune2;
|
targetInfo.MissCondition = SpellMissInfo.Immune2;
|
||||||
|
|
||||||
if (targetInfo.MissCondition == SpellMissInfo.None) // hits
|
if (targetInfo.MissCondition == SpellMissInfo.None || (targetInfo.MissCondition == SpellMissInfo.Block && !m_spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked))) // Add only hits and partial blocked
|
||||||
{
|
{
|
||||||
data.HitTargets.Add(targetInfo.TargetGUID);
|
data.HitTargets.Add(targetInfo.TargetGUID);
|
||||||
data.HitStatus.Add(new SpellHitStatus(SpellMissInfo.None));
|
data.HitStatus.Add(new SpellHitStatus(SpellMissInfo.None));
|
||||||
@@ -7238,7 +7238,7 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
Unit unit = null;
|
Unit unit = null;
|
||||||
// In case spell hit target, do all effect on that target
|
// In case spell hit target, do all effect on that target
|
||||||
if (targetInfo.MissCondition == SpellMissInfo.None)
|
if (targetInfo.MissCondition == SpellMissInfo.None || (targetInfo.MissCondition == SpellMissInfo.Block && !m_spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked)))
|
||||||
unit = m_caster.GetGUID() == targetInfo.TargetGUID ? m_caster.ToUnit() : Global.ObjAccessor.GetUnit(m_caster, targetInfo.TargetGUID);
|
unit = m_caster.GetGUID() == targetInfo.TargetGUID ? m_caster.ToUnit() : Global.ObjAccessor.GetUnit(m_caster, targetInfo.TargetGUID);
|
||||||
// In case spell reflect from target, do all effect on caster (if hit)
|
// In case spell reflect from target, do all effect on caster (if hit)
|
||||||
else if (targetInfo.MissCondition == SpellMissInfo.Reflect && targetInfo.ReflectResult == SpellMissInfo.None)
|
else if (targetInfo.MissCondition == SpellMissInfo.Reflect && targetInfo.ReflectResult == SpellMissInfo.None)
|
||||||
@@ -8280,7 +8280,7 @@ namespace Game.Spells
|
|||||||
spell.m_healing = Healing;
|
spell.m_healing = Healing;
|
||||||
|
|
||||||
_spellHitTarget = null;
|
_spellHitTarget = null;
|
||||||
if (MissCondition == SpellMissInfo.None)
|
if (MissCondition == SpellMissInfo.None || (MissCondition == SpellMissInfo.Block && !spell.GetSpellInfo().HasAttribute(SpellAttr3.CompletelyBlocked)))
|
||||||
_spellHitTarget = unit;
|
_spellHitTarget = unit;
|
||||||
else if (MissCondition == SpellMissInfo.Reflect && ReflectResult == SpellMissInfo.None)
|
else if (MissCondition == SpellMissInfo.Reflect && ReflectResult == SpellMissInfo.None)
|
||||||
_spellHitTarget = spell.GetCaster().ToUnit();
|
_spellHitTarget = spell.GetCaster().ToUnit();
|
||||||
@@ -8485,7 +8485,7 @@ namespace Game.Spells
|
|||||||
caster.SetLastDamagedTargetGuid(spell.unitTarget.GetGUID());
|
caster.SetLastDamagedTargetGuid(spell.unitTarget.GetGUID());
|
||||||
|
|
||||||
// Add bonuses and fill damageInfo struct
|
// Add bonuses and fill damageInfo struct
|
||||||
caster.CalculateSpellDamageTaken(damageInfo, spell.m_damage, spell.m_spellInfo, spell.m_attackType, IsCrit);
|
caster.CalculateSpellDamageTaken(damageInfo, spell.m_damage, spell.m_spellInfo, spell.m_attackType, IsCrit, MissCondition == SpellMissInfo.Block, spell);
|
||||||
Unit.DealDamageMods(damageInfo.attacker, damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
|
Unit.DealDamageMods(damageInfo.attacker, damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
|
||||||
|
|
||||||
hitMask |= Unit.CreateProcHitMask(damageInfo, MissCondition);
|
hitMask |= Unit.CreateProcHitMask(damageInfo, MissCondition);
|
||||||
|
|||||||
Reference in New Issue
Block a user