Core/Spells: calculate crit chance only for spells that do damage/healing
Port From (https://github.com/TrinityCore/TrinityCore/commit/85e5509e91a1370b16851d375a26121797870921)
This commit is contained in:
@@ -2060,6 +2060,7 @@ namespace Framework.Constants
|
|||||||
NoInitialThreat = 0x10,
|
NoInitialThreat = 0x10,
|
||||||
AuraCC = 0x20,
|
AuraCC = 0x20,
|
||||||
DontBreakStealth = 0x40,
|
DontBreakStealth = 0x40,
|
||||||
|
CanCrit = 0x80,
|
||||||
DirectDamage = 0x100,
|
DirectDamage = 0x100,
|
||||||
Charge = 0x200,
|
Charge = 0x200,
|
||||||
PickPocket = 0x400,
|
PickPocket = 0x400,
|
||||||
|
|||||||
@@ -645,14 +645,15 @@ namespace Game.Entities
|
|||||||
return (uint)Math.Max(heal, 0.0f);
|
return (uint)Math.Max(heal, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float SpellCritChanceDone(SpellInfo spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
public float SpellCritChanceDone(Spell spell, AuraEffect aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
||||||
{
|
{
|
||||||
|
SpellInfo spellInfo = spell != null ? spell.GetSpellInfo() : aurEff.GetSpellInfo();
|
||||||
//! Mobs can't crit with spells. (Except player controlled)
|
//! Mobs can't crit with spells. (Except player controlled)
|
||||||
if (IsCreature() && !GetSpellModOwner())
|
if (IsCreature() && !GetSpellModOwner())
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
// not critting spell
|
// not critting spell
|
||||||
if (spellInfo.HasAttribute(SpellAttr2.CantCrit))
|
if (spell != null && !spellInfo.HasAttribute(SpellCustomAttributes.CanCrit))
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
float crit_chance = 0.0f;
|
float crit_chance = 0.0f;
|
||||||
@@ -691,7 +692,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
SpellInfo spellInfo = spell != null ? spell.GetSpellInfo() : aurEff.GetSpellInfo();
|
SpellInfo spellInfo = spell != null ? spell.GetSpellInfo() : aurEff.GetSpellInfo();
|
||||||
// not critting spell
|
// not critting spell
|
||||||
if (spellInfo.HasAttribute(SpellAttr2.CantCrit))
|
if (spell != null && !spellInfo.HasAttribute(SpellCustomAttributes.CanCrit))
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
|
|
||||||
float crit_chance = doneChance;
|
float crit_chance = doneChance;
|
||||||
|
|||||||
@@ -355,19 +355,6 @@ namespace Game.Spells
|
|||||||
_effects[effect.EffectIndex] = new AuraEffect(this, effect, baseAmount != null ? baseAmount[effect.EffectIndex] : (int?)null, caster);
|
_effects[effect.EffectIndex] = new AuraEffect(this, effect, baseAmount != null ? baseAmount[effect.EffectIndex] : (int?)null, caster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CalcPeriodicCritChance(Unit caster)
|
|
||||||
{
|
|
||||||
if (!caster)
|
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
Player modOwner = caster.GetSpellModOwner();
|
|
||||||
if (modOwner == null)
|
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
float critChance = modOwner.SpellCritChanceDone(GetSpellInfo(), GetSpellInfo().GetSchoolMask(), GetSpellInfo().GetAttackType());
|
|
||||||
return Math.Max(0.0f, critChance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Unit GetCaster()
|
public Unit GetCaster()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -446,7 +446,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
public float GetCritChanceFor(Unit caster, Unit target)
|
public float GetCritChanceFor(Unit caster, Unit target)
|
||||||
{
|
{
|
||||||
return target.SpellCritChanceTaken(caster, null, this, GetSpellInfo().GetSchoolMask(), GetBase().CalcPeriodicCritChance(caster), GetSpellInfo().GetAttackType());
|
return target.SpellCritChanceTaken(caster, null, this, GetSpellInfo().GetSchoolMask(), CalcPeriodicCritChance(caster), GetSpellInfo().GetAttackType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAffectingSpell(SpellInfo spell)
|
public bool IsAffectingSpell(SpellInfo spell)
|
||||||
@@ -595,6 +595,11 @@ namespace Game.Spells
|
|||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case AuraType.ModSpellCritChance:
|
||||||
|
// skip spells that can't crit
|
||||||
|
if (spellInfo == null || !spellInfo.HasAttribute(SpellCustomAttributes.CanCrit))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5380,6 +5385,27 @@ namespace Game.Spells
|
|||||||
caster.SendSpellNonMeleeDamageLog(damageInfo);
|
caster.SendSpellNonMeleeDamageLog(damageInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CanPeriodicTickCrit()
|
||||||
|
{
|
||||||
|
if (GetSpellInfo().HasAttribute(SpellAttr2.CantCrit))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CalcPeriodicCritChance(Unit caster)
|
||||||
|
{
|
||||||
|
if (!caster || !CanPeriodicTickCrit())
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
Player modOwner = caster.GetSpellModOwner();
|
||||||
|
if (!modOwner)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
float critChance = modOwner.SpellCritChanceDone(null, this, GetSpellInfo().GetSchoolMask(), GetSpellInfo().GetAttackType());
|
||||||
|
return Math.Max(0.0f, critChance);
|
||||||
|
}
|
||||||
|
|
||||||
void HandleBreakableCCAuraProc(AuraApplication aurApp, ProcEventInfo eventInfo)
|
void HandleBreakableCCAuraProc(AuraApplication aurApp, ProcEventInfo eventInfo)
|
||||||
{
|
{
|
||||||
int damageLeft = (int)(GetAmount() - eventInfo.GetDamageInfo().GetDamage());
|
int damageLeft = (int)(GetAmount() - eventInfo.GetDamageInfo().GetDamage());
|
||||||
|
|||||||
@@ -6872,7 +6872,7 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float critChance = m_caster.SpellCritChanceDone(m_spellInfo, m_spellSchoolMask, m_attackType);
|
float critChance = m_caster.SpellCritChanceDone(this, null, m_spellSchoolMask, m_attackType);
|
||||||
targetInfo.crit = RandomHelper.randChance(unit.SpellCritChanceTaken(m_caster, this, null, m_spellSchoolMask, critChance, m_attackType));
|
targetInfo.crit = RandomHelper.randChance(unit.SpellCritChanceTaken(m_caster, this, null, m_spellSchoolMask, critChance, m_attackType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2661,6 +2661,23 @@ namespace Game.Entities
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (effect.Effect)
|
||||||
|
{
|
||||||
|
case SpellEffectName.SchoolDamage:
|
||||||
|
case SpellEffectName.HealthLeech:
|
||||||
|
case SpellEffectName.Heal:
|
||||||
|
case SpellEffectName.WeaponDamageNoSchool:
|
||||||
|
case SpellEffectName.WeaponPercentDamage:
|
||||||
|
case SpellEffectName.WeaponDamage:
|
||||||
|
case SpellEffectName.PowerBurn:
|
||||||
|
case SpellEffectName.HealMechanical:
|
||||||
|
case SpellEffectName.NormalizedWeaponDmg:
|
||||||
|
case SpellEffectName.HealPct:
|
||||||
|
case SpellEffectName.DamageFromMaxHealthPCT:
|
||||||
|
spellInfo.AttributesCu |= SpellCustomAttributes.CanCrit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
switch (effect.Effect)
|
switch (effect.Effect)
|
||||||
{
|
{
|
||||||
case SpellEffectName.SchoolDamage:
|
case SpellEffectName.SchoolDamage:
|
||||||
@@ -2846,38 +2863,43 @@ namespace Game.Entities
|
|||||||
// addition for binary spells, ommit spells triggering other spells
|
// addition for binary spells, ommit spells triggering other spells
|
||||||
foreach (var spellInfo in mSpellInfoMap.Values)
|
foreach (var spellInfo in mSpellInfoMap.Values)
|
||||||
{
|
{
|
||||||
if (spellInfo.HasAttribute(SpellCustomAttributes.BinarySpell))
|
if (!spellInfo.HasAttribute(SpellCustomAttributes.BinarySpell))
|
||||||
continue;
|
|
||||||
|
|
||||||
bool allNonBinary = true;
|
|
||||||
bool overrideAttr = false;
|
|
||||||
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
|
|
||||||
{
|
{
|
||||||
if (effect == null)
|
bool allNonBinary = true;
|
||||||
continue;
|
bool overrideAttr = false;
|
||||||
|
foreach (SpellEffectInfo effect in spellInfo.GetEffects())
|
||||||
if (effect.IsAura() && effect.TriggerSpell != 0)
|
|
||||||
{
|
{
|
||||||
switch (effect.ApplyAuraName)
|
if (effect == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (effect.IsAura() && effect.TriggerSpell != 0)
|
||||||
{
|
{
|
||||||
case AuraType.PeriodicTriggerSpell:
|
switch (effect.ApplyAuraName)
|
||||||
case AuraType.PeriodicTriggerSpellWithValue:
|
{
|
||||||
SpellInfo triggerSpell = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty.None);
|
case AuraType.PeriodicTriggerSpell:
|
||||||
if (triggerSpell != null)
|
case AuraType.PeriodicTriggerSpellWithValue:
|
||||||
{
|
SpellInfo triggerSpell = Global.SpellMgr.GetSpellInfo(effect.TriggerSpell, Difficulty.None);
|
||||||
overrideAttr = true;
|
if (triggerSpell != null)
|
||||||
if (triggerSpell.HasAttribute(SpellCustomAttributes.BinarySpell))
|
{
|
||||||
allNonBinary = false;
|
overrideAttr = true;
|
||||||
}
|
if (triggerSpell.HasAttribute(SpellCustomAttributes.BinarySpell))
|
||||||
break;
|
allNonBinary = false;
|
||||||
default:
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (overrideAttr && allNonBinary)
|
||||||
|
spellInfo.AttributesCu &= ~SpellCustomAttributes.BinarySpell;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overrideAttr && allNonBinary)
|
// remove attribute from spells that can't crit
|
||||||
spellInfo.AttributesCu &= ~SpellCustomAttributes.BinarySpell;
|
if (spellInfo.HasAttribute(SpellCustomAttributes.CanCrit))
|
||||||
|
if (spellInfo.HasAttribute(SpellAttr2.CantCrit))
|
||||||
|
spellInfo.AttributesCu &= ~SpellCustomAttributes.CanCrit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded spell custom attributes in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded spell custom attributes in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
|
|||||||
Reference in New Issue
Block a user