Core/Spells: Define all spell modifier types and implement ProcCooldown mod and PeriodicHealingAndDamage for melee periodic damage
Port From (https://github.com/TrinityCore/TrinityCore/commit/6585666e6e34ade0333e4c23876acdf847d169c0)
This commit is contained in:
@@ -878,7 +878,7 @@ namespace Game.Spells
|
||||
{
|
||||
Player modOwner = caster.GetSpellModOwner();
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.MaxStackAmount, ref maxStackAmount);
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.MaxAuraStacks, ref maxStackAmount);
|
||||
}
|
||||
return maxStackAmount;
|
||||
}
|
||||
@@ -1025,7 +1025,7 @@ namespace Game.Spells
|
||||
{
|
||||
Player modOwner = caster.GetSpellModOwner();
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ResistDispelChance, ref resistChance);
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.DispelResistance, ref resistChance);
|
||||
}
|
||||
|
||||
resistChance = resistChance < 0 ? 0 : resistChance;
|
||||
@@ -1652,7 +1652,16 @@ namespace Game.Spells
|
||||
}
|
||||
|
||||
// cooldowns should be added to the whole aura (see 51698 area aura)
|
||||
AddProcCooldown(now + TimeSpan.FromMilliseconds(procEntry.Cooldown));
|
||||
int procCooldown = (int)procEntry.Cooldown;
|
||||
Unit caster = GetCaster();
|
||||
if (caster != null)
|
||||
{
|
||||
Player modOwner = caster.GetSpellModOwner();
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ProcCooldown, ref procCooldown);
|
||||
}
|
||||
|
||||
AddProcCooldown(now + TimeSpan.FromMilliseconds(procCooldown));
|
||||
|
||||
SetLastProcSuccessTime(now);
|
||||
}
|
||||
@@ -1807,7 +1816,7 @@ namespace Game.Spells
|
||||
// apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell)
|
||||
Player modOwner = caster.GetSpellModOwner();
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ChanceOfSuccess, ref chance);
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ProcChance, ref chance);
|
||||
}
|
||||
|
||||
// proc chance is reduced by an additional 3.333% per level past 60
|
||||
@@ -2321,7 +2330,7 @@ namespace Game.Spells
|
||||
{
|
||||
Player modOwner = caster.GetSpellModOwner();
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.Charges, ref maxProcCharges);
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ProcCharges, ref maxProcCharges);
|
||||
}
|
||||
return (byte)maxProcCharges;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ using Game.Networking.Packets;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections;
|
||||
|
||||
namespace Game.Spells
|
||||
{
|
||||
@@ -188,7 +189,7 @@ namespace Game.Spells
|
||||
{
|
||||
// Apply periodic time mod
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ActivationTime, ref _period);
|
||||
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.Period, ref _period);
|
||||
|
||||
if (caster != null)
|
||||
{
|
||||
@@ -346,71 +347,54 @@ namespace Game.Spells
|
||||
return;
|
||||
// reapply some passive spells after add/remove related spellmods
|
||||
// Warning: it is a dead loop if 2 auras each other amount-shouldn't happen
|
||||
BitSet recalculateEffectMask = new(SpellConst.MaxEffects);
|
||||
switch ((SpellModOp)GetMiscValue())
|
||||
{
|
||||
case SpellModOp.AllEffects:
|
||||
case SpellModOp.Effect1:
|
||||
case SpellModOp.Effect2:
|
||||
case SpellModOp.Effect3:
|
||||
case SpellModOp.Effect4:
|
||||
case SpellModOp.Effect5:
|
||||
{
|
||||
ObjectGuid guid = target.GetGUID();
|
||||
foreach (var iter in target.GetAppliedAuras())
|
||||
{
|
||||
if (iter.Value == null)
|
||||
continue;
|
||||
Aura aura = iter.Value.GetBase();
|
||||
// only passive and permament auras-active auras should have amount set on spellcast and not be affected
|
||||
// if aura is casted by others, it will not be affected
|
||||
if ((aura.IsPassive() || aura.IsPermanent()) && aura.GetCasterGUID() == guid && aura.GetSpellInfo().IsAffectedBySpellMod(m_spellmod))
|
||||
{
|
||||
AuraEffect aurEff;
|
||||
if ((SpellModOp)GetMiscValue() == SpellModOp.AllEffects)
|
||||
{
|
||||
for (byte i = 0; i < SpellConst.MaxEffects; ++i)
|
||||
{
|
||||
if ((aurEff = aura.GetEffect(i)) != null)
|
||||
aurEff.RecalculateAmount();
|
||||
}
|
||||
}
|
||||
else if ((SpellModOp)GetMiscValue() == SpellModOp.Effect1)
|
||||
{
|
||||
aurEff = aura.GetEffect(0);
|
||||
if (aurEff != null)
|
||||
aurEff.RecalculateAmount();
|
||||
}
|
||||
else if ((SpellModOp)GetMiscValue() == SpellModOp.Effect2)
|
||||
{
|
||||
aurEff = aura.GetEffect(1);
|
||||
if (aurEff != null)
|
||||
aurEff.RecalculateAmount();
|
||||
}
|
||||
else if ((SpellModOp)GetMiscValue() == SpellModOp.Effect3)
|
||||
{
|
||||
aurEff = aura.GetEffect(2);
|
||||
if (aurEff != null)
|
||||
aurEff.RecalculateAmount();
|
||||
}
|
||||
else if ((SpellModOp)GetMiscValue() == SpellModOp.Effect4)
|
||||
{
|
||||
aurEff = aura.GetEffect(3);
|
||||
if (aurEff != null)
|
||||
aurEff.RecalculateAmount();
|
||||
}
|
||||
else if ((SpellModOp)GetMiscValue() == SpellModOp.Effect5)
|
||||
{
|
||||
aurEff = aura.GetEffect(4);
|
||||
if (aurEff != null)
|
||||
aurEff.RecalculateAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case SpellModOp.Points:
|
||||
recalculateEffectMask.SetAll(true);
|
||||
break;
|
||||
case SpellModOp.PointsIndex0:
|
||||
recalculateEffectMask.Set(0, true);
|
||||
break;
|
||||
case SpellModOp.PointsIndex1:
|
||||
recalculateEffectMask.Set(1, true);
|
||||
break;
|
||||
case SpellModOp.PointsIndex2:
|
||||
recalculateEffectMask.Set(2, true);
|
||||
break;
|
||||
case SpellModOp.PointsIndex3:
|
||||
recalculateEffectMask.Set(3, true);
|
||||
break;
|
||||
case SpellModOp.PointsIndex4:
|
||||
recalculateEffectMask.Set(4, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (recalculateEffectMask.Any())
|
||||
{
|
||||
ObjectGuid guid = target.GetGUID();
|
||||
var auras = target.GetAppliedAuras();
|
||||
foreach (var iter in auras)
|
||||
{
|
||||
Aura aura = iter.Value.GetBase();
|
||||
// only passive and permament auras-active auras should have amount set on spellcast and not be affected
|
||||
// if aura is cast by others, it will not be affected
|
||||
if ((aura.IsPassive() || aura.IsPermanent()) && aura.GetCasterGUID() == guid && aura.GetSpellInfo().IsAffectedBySpellMod(m_spellmod))
|
||||
{
|
||||
for (uint i = 0; i < recalculateEffectMask.Count; ++i)
|
||||
{
|
||||
if (recalculateEffectMask[(int)i])
|
||||
{
|
||||
AuraEffect aurEff = aura.GetEffect(i);
|
||||
if (aurEff != null)
|
||||
aurEff.RecalculateAmount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Update(uint diff, Unit caster)
|
||||
@@ -4910,7 +4894,7 @@ namespace Game.Spells
|
||||
uint weaponDamage = MathFunctions.CalculatePct(caster.CalculateDamage(attackType, false, true), GetAmount());
|
||||
|
||||
// Add melee damage bonuses (also check for negative)
|
||||
uint damageBonusDone = caster.MeleeDamageBonusDone(target, Math.Max(weaponDamage, 0), attackType, GetSpellInfo());
|
||||
uint damageBonusDone = caster.MeleeDamageBonusDone(target, Math.Max(weaponDamage, 0), attackType, DamageEffectType.DOT, GetSpellInfo());
|
||||
|
||||
damage = target.MeleeDamageBonusTaken(caster, damageBonusDone, attackType, DamageEffectType.DOT, GetSpellInfo());
|
||||
break;
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Game.Spells
|
||||
|
||||
Player modOwner = caster.GetSpellModOwner();
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(info, SpellModOp.StackAmount, ref m_spellValue.AuraStackAmount, this);
|
||||
modOwner.ApplySpellMod(info, SpellModOp.Doses, ref m_spellValue.AuraStackAmount, this);
|
||||
|
||||
if (!originalCasterGUID.IsEmpty())
|
||||
m_originalCasterGUID = originalCasterGUID;
|
||||
@@ -1089,7 +1089,7 @@ namespace Game.Spells
|
||||
int maxTargets = effect.ChainTargets;
|
||||
Player modOwner = m_caster.GetSpellModOwner();
|
||||
if (modOwner)
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.JumpTargets, ref maxTargets, this);
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.ChainTargets, ref maxTargets, this);
|
||||
|
||||
if (maxTargets > 1)
|
||||
{
|
||||
@@ -1411,7 +1411,7 @@ namespace Game.Spells
|
||||
|
||||
Player modOwner = m_caster.GetSpellModOwner();
|
||||
if (modOwner)
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.JumpDistance, ref jumpRadius, this);
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.ChainJumpDistance, ref jumpRadius, this);
|
||||
|
||||
// chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
|
||||
bool isBouncingFar = (m_spellInfo.HasAttribute(SpellAttr4.AreaTargetChain)
|
||||
@@ -4210,7 +4210,7 @@ namespace Game.Spells
|
||||
//lower spell cost on fail (by talent aura)
|
||||
Player modOwner = m_caster.ToPlayer().GetSpellModOwner();
|
||||
if (modOwner)
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.SpellCostRefundOnFail, ref cost.Amount);
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.PowerCostOnMiss, ref cost.Amount);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -6434,7 +6434,7 @@ namespace Game.Spells
|
||||
//check pushback reduce
|
||||
int delaytime = 500; // spellcasting delay is normally 500ms
|
||||
int delayReduce = 100; // must be initialized to 100 for percent modifiers
|
||||
m_caster.ToPlayer().ApplySpellMod(m_spellInfo, SpellModOp.NotLoseCastingTime, ref delayReduce, this);
|
||||
m_caster.ToPlayer().ApplySpellMod(m_spellInfo, SpellModOp.ResistPushback, ref delayReduce, this);
|
||||
delayReduce += m_caster.GetTotalAuraModifier(AuraType.ReducePushback) - 100;
|
||||
if (delayReduce >= 100)
|
||||
return;
|
||||
@@ -6469,7 +6469,7 @@ namespace Game.Spells
|
||||
//check pushback reduce
|
||||
int delaytime = MathFunctions.CalculatePct(m_spellInfo.GetDuration(), 25); // channeling delay is normally 25% of its time per hit
|
||||
int delayReduce = 100; // must be initialized to 100 for percent modifiers
|
||||
m_caster.ToPlayer().ApplySpellMod(m_spellInfo, SpellModOp.NotLoseCastingTime, ref delayReduce, this);
|
||||
m_caster.ToPlayer().ApplySpellMod(m_spellInfo, SpellModOp.ResistPushback, ref delayReduce, this);
|
||||
delayReduce += m_caster.GetTotalAuraModifier(AuraType.ReducePushback) - 100;
|
||||
if (delayReduce >= 100)
|
||||
return;
|
||||
@@ -7236,7 +7236,7 @@ namespace Game.Spells
|
||||
// gcd modifier auras are applied only to own spells and only players have such mods
|
||||
Player modOwner = m_caster.GetSpellModOwner();
|
||||
if (modOwner)
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.GlobalCooldown, ref gcd, this);
|
||||
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.StartCooldown, ref gcd, this);
|
||||
|
||||
bool isMeleeOrRangedSpell = m_spellInfo.DmgClass == SpellDmgClass.Melee || m_spellInfo.DmgClass == SpellDmgClass.Ranged ||
|
||||
m_spellInfo.HasAttribute(SpellAttr0.ReqAmmo) || m_spellInfo.HasAttribute(SpellAttr0.Ability);
|
||||
@@ -7724,7 +7724,7 @@ namespace Game.Spells
|
||||
{
|
||||
public SpellModifier(Aura _ownerAura)
|
||||
{
|
||||
op = SpellModOp.Damage;
|
||||
op = SpellModOp.HealingAndDamage;
|
||||
type = SpellModType.Flat;
|
||||
value = 0;
|
||||
mask = new FlagArray128();
|
||||
|
||||
@@ -2635,7 +2635,7 @@ namespace Game.Spells
|
||||
uint eff_damage = Math.Max(weaponDamage, 0);
|
||||
|
||||
// Add melee damage bonuses (also check for negative)
|
||||
uint damage = m_caster.MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo);
|
||||
uint damage = m_caster.MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, DamageEffectType.Direct, m_spellInfo);
|
||||
|
||||
m_damage += (int)unitTarget.MeleeDamageBonusTaken(m_caster, damage, m_attackType, DamageEffectType.SpellDirect, m_spellInfo);
|
||||
}
|
||||
|
||||
@@ -2839,13 +2839,13 @@ namespace Game.Spells
|
||||
switch (power.OrderIndex)
|
||||
{
|
||||
case 0:
|
||||
mod = SpellModOp.Cost;
|
||||
mod = SpellModOp.PowerCost0;
|
||||
break;
|
||||
case 1:
|
||||
mod = SpellModOp.SpellCost2;
|
||||
mod = SpellModOp.PowerCost1;
|
||||
break;
|
||||
case 2:
|
||||
mod = SpellModOp.SpellCost3;
|
||||
mod = SpellModOp.PowerCost2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -3410,7 +3410,9 @@ namespace Game.Spells
|
||||
// non-positive mods
|
||||
switch ((SpellModOp)effect.MiscValue)
|
||||
{
|
||||
case SpellModOp.Cost: // dependent from bas point sign (negative . positive)
|
||||
case SpellModOp.PowerCost0: // dependent from bas point sign (negative . positive)
|
||||
case SpellModOp.PowerCost1:
|
||||
case SpellModOp.PowerCost2:
|
||||
if (effect.CalcValue() > 0)
|
||||
{
|
||||
if (!deep)
|
||||
@@ -3963,7 +3965,7 @@ namespace Game.Spells
|
||||
float multiplier = Amplitude;
|
||||
Player modOwner = (caster != null ? caster.GetSpellModOwner() : null);
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(_spellInfo, SpellModOp.ValueMultiplier, ref multiplier, spell);
|
||||
modOwner.ApplySpellMod(_spellInfo, SpellModOp.Amplitude, ref multiplier, spell);
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
@@ -3972,7 +3974,7 @@ namespace Game.Spells
|
||||
float multiplierPercent = ChainAmplitude * 100.0f;
|
||||
Player modOwner = (caster != null ? caster.GetSpellModOwner() : null);
|
||||
if (modOwner != null)
|
||||
modOwner.ApplySpellMod(_spellInfo, SpellModOp.DamageMultiplier, ref multiplierPercent, spell);
|
||||
modOwner.ApplySpellMod(_spellInfo, SpellModOp.ChainAmplitude, ref multiplierPercent, spell);
|
||||
return multiplierPercent / 100.0f;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user