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:
hondacrx
2021-03-17 18:52:59 -04:00
parent f667df1b11
commit 4568cdad48
16 changed files with 168 additions and 158 deletions
+11
View File
@@ -192,6 +192,17 @@ namespace System.Collections
return this; return this;
} }
public bool Any()
{
for (var i = 0; i < Length; ++i)
{
if (Get(i))
return true;
}
return false;
}
public int Length public int Length
{ {
get get
+37 -37
View File
@@ -317,50 +317,50 @@ namespace Framework.Constants
public enum SpellModOp public enum SpellModOp
{ {
Damage = 0, HealingAndDamage = 0,
Duration = 1, Duration = 1,
Threat = 2, Hate = 2,
Effect1 = 3, PointsIndex0 = 3,
Charges = 4, ProcCharges = 4,
Range = 5, Range = 5,
Radius = 6, Radius = 6,
CriticalChance = 7, CritChance = 7,
AllEffects = 8, Points = 8,
NotLoseCastingTime = 9, ResistPushback = 9,
CastingTime = 10, ChangeCastTime = 10,
Cooldown = 11, Cooldown = 11,
Effect2 = 12, PointsIndex1 = 12,
IgnoreArmor = 13, TargetResistance = 13,
Cost = 14, // Used when SpellPowerEntry.PowerIndex == 0 PowerCost0 = 14, // Used when SpellPowerEntry::PowerIndex == 0
CritDamageBonus = 15, CritDamageAndHealing = 15,
ResistMissChance = 16, HitChance = 16,
JumpTargets = 17, ChainTargets = 17,
ChanceOfSuccess = 18, ProcChance = 18,
ActivationTime = 19, Period = 19,
DamageMultiplier = 20, ChainAmplitude = 20,
GlobalCooldown = 21, StartCooldown = 21,
Dot = 22, PeriodicHealingAndDamage = 22,
Effect3 = 23, PointsIndex2 = 23,
BonusMultiplier = 24, BonusCoefficient = 24,
// Spellmod 25 TriggerDamage = 25, // NYI
ProcPerMinute = 26, ProcFrequency = 26,
ValueMultiplier = 27, Amplitude = 27,
ResistDispelChance = 28, DispelResistance = 28,
CritDamageBonus2 = 29, //One Not Used Spell CrowdDamage = 29, // NYI
SpellCostRefundOnFail = 30, PowerCostOnMiss = 30,
StackAmount = 31, Doses = 31,
Effect4 = 32, PointsIndex3 = 32,
Effect5 = 33, PointsIndex4 = 33,
SpellCost2 = 34, // Used when SpellPowerEntry.PowerIndex == 1 PowerCost1 = 34, // Used when SpellPowerEntry::PowerIndex == 1
JumpDistance = 35, ChainJumpDistance = 35,
// spellmod 36 AreaTriggerMaxSummons = 36, // NYI
MaxStackAmount = 37, MaxAuraStacks = 37,
// spellmod 38 ProcCooldown = 38,
SpellCost3 = 39, PowerCost2 = 39, // Used when SpellPowerEntry::PowerIndex == 2
Max = 40 Max = 40
} }
// Note: SPELLMOD_* values is aura types in fact
public enum SpellModType public enum SpellModType
{ {
Flat = 0, // SPELL_AURA_ADD_FLAT_MODIFIER Flat = 0, // SPELL_AURA_ADD_FLAT_MODIFIER
+1 -1
View File
@@ -49,7 +49,7 @@ namespace Game.AI
// Get spell range // Get spell range
float max_range = spellInfo.GetMaxRange(false); float max_range = spellInfo.GetMaxRange(false);
// SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems // SpellModOp.Range not applied in this place just because not existence range mods for attacking totems
Unit victim = !i_victimGuid.IsEmpty() ? Global.ObjAccessor.GetUnit(me, i_victimGuid) : null; Unit victim = !i_victimGuid.IsEmpty() ? Global.ObjAccessor.GetUnit(me, i_victimGuid) : null;
+1 -1
View File
@@ -352,7 +352,7 @@ namespace Game.Combat
Player modOwner = hatedUnit.GetSpellModOwner(); Player modOwner = hatedUnit.GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(threatSpell, SpellModOp.Threat, ref threat); modOwner.ApplySpellMod(threatSpell, SpellModOp.Hate, ref threat);
} }
return hatedUnit.ApplyTotalThreatModifier(threat, schoolMask); return hatedUnit.ApplyTotalThreatModifier(threat, schoolMask);
+4 -4
View File
@@ -2729,7 +2729,7 @@ namespace Game.Entities
switch (op) switch (op)
{ {
// special case, if a mod makes spell instant, only consume that mod // special case, if a mod makes spell instant, only consume that mod
case SpellModOp.CastingTime: case SpellModOp.ChangeCastTime:
{ {
SpellModifier modInstantSpell = null; SpellModifier modInstantSpell = null;
foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Pct]) foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Pct])
@@ -2753,7 +2753,7 @@ namespace Game.Entities
break; break;
} }
// special case if two mods apply 100% critical chance, only consume one // special case if two mods apply 100% critical chance, only consume one
case SpellModOp.CriticalChance: case SpellModOp.CritChance:
{ {
SpellModifier modCritical = null; SpellModifier modCritical = null;
foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Flat]) foreach (SpellModifier mod in m_spellMods[(int)op][(int)SpellModType.Flat])
@@ -2799,7 +2799,7 @@ namespace Game.Entities
continue; continue;
// special case (skip > 10sec spell casts for instant cast setting) // special case (skip > 10sec spell casts for instant cast setting)
if (op == SpellModOp.CastingTime) if (op == SpellModOp.ChangeCastTime)
{ {
if (baseValue.CompareTo(10000) > 0 && mod.value <= -100) if (baseValue.CompareTo(10000) > 0 && mod.value <= -100)
continue; continue;
@@ -3213,7 +3213,7 @@ namespace Game.Entities
} }
// Apply spell mods // Apply spell mods
ApplySpellMod(spellInfo, SpellModOp.ChanceOfSuccess, ref chance); ApplySpellMod(spellInfo, SpellModOp.ProcChance, ref chance);
// Shiv has 100% chance to apply the poison // Shiv has 100% chance to apply the poison
if (FindCurrentSpellBySpellId(5938) != null && e_slot == (byte)EnchantmentSlot.Temp) if (FindCurrentSpellBySpellId(5938) != null && e_slot == (byte)EnchantmentSlot.Temp)
+2 -2
View File
@@ -771,13 +771,13 @@ namespace Game.Entities
if (spellInfo == null && HaveOffhandWeapon() && !IsInFeralForm()) if (spellInfo == null && HaveOffhandWeapon() && !IsInFeralForm())
missChance += 19.0f; missChance += 19.0f;
// Spellmod from SPELLMOD_RESIST_MISS_CHANCE // Spellmod from SpellModOp.HitChance
float resistMissChance = 100.0f; float resistMissChance = 100.0f;
if (spellInfo != null) if (spellInfo != null)
{ {
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellInfo, SpellModOp.ResistMissChance, ref resistMissChance); modOwner.ApplySpellMod(spellInfo, SpellModOp.HitChance, ref resistMissChance);
} }
missChance += resistMissChance - 100.0f; missChance += resistMissChance - 100.0f;
+10 -5
View File
@@ -1772,7 +1772,7 @@ namespace Game.Entities
{ {
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellProto, SpellModOp.ProcPerMinute, ref PPM); modOwner.ApplySpellMod(spellProto, SpellModOp.ProcFrequency, ref PPM);
} }
return (float)Math.Floor((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60)) return (float)Math.Floor((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60))
@@ -1916,7 +1916,7 @@ namespace Game.Entities
damage += CalculateDamage(damageInfo.attackType, false, true); damage += CalculateDamage(damageInfo.attackType, false, true);
// Add melee damage bonus // Add melee damage bonus
damage = MeleeDamageBonusDone(damageInfo.target, damage, damageInfo.attackType); damage = MeleeDamageBonusDone(damageInfo.target, damage, damageInfo.attackType, DamageEffectType.Direct);
damage = damageInfo.target.MeleeDamageBonusTaken(this, damage, damageInfo.attackType, DamageEffectType.Direct); damage = damageInfo.target.MeleeDamageBonusTaken(this, damage, damageInfo.attackType, DamageEffectType.Direct);
// Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations // Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations
@@ -2737,7 +2737,7 @@ namespace Game.Entities
{ {
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellInfo, SpellModOp.IgnoreArmor, ref armor); modOwner.ApplySpellMod(spellInfo, SpellModOp.TargetResistance, ref armor);
} }
var resIgnoreAuras = GetAuraEffectsByType(AuraType.ModIgnoreTargetResist); var resIgnoreAuras = GetAuraEffectsByType(AuraType.ModIgnoreTargetResist);
@@ -2780,7 +2780,7 @@ namespace Game.Entities
return Math.Max((uint)(damage * (1.0f - mitigation)), 1); return Math.Max((uint)(damage * (1.0f - mitigation)), 1);
} }
public uint MeleeDamageBonusDone(Unit victim, uint pdamage, WeaponAttackType attType, SpellInfo spellProto = null) public uint MeleeDamageBonusDone(Unit victim, uint pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null)
{ {
if (victim == null || pdamage == 0) if (victim == null || pdamage == 0)
return 0; return 0;
@@ -2874,7 +2874,12 @@ namespace Game.Entities
{ {
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellProto, SpellModOp.Damage, ref tmpDamage); {
if (damagetype == DamageEffectType.DOT)
modOwner.ApplySpellMod(spellProto, SpellModOp.PeriodicHealingAndDamage, ref tmpDamage);
else
modOwner.ApplySpellMod(spellProto, SpellModOp.HealingAndDamage, ref tmpDamage);
}
} }
// bonus result can be negative // bonus result can be negative
+1 -2
View File
@@ -286,6 +286,7 @@ namespace Game.Entities
case MeleeHitOutcome.Evade: case MeleeHitOutcome.Evade:
m_hitMask |= ProcFlagsHit.Evade; m_hitMask |= ProcFlagsHit.Evade;
break; break;
case MeleeHitOutcome.Block:
case MeleeHitOutcome.Crushing: case MeleeHitOutcome.Crushing:
case MeleeHitOutcome.Glancing: case MeleeHitOutcome.Glancing:
case MeleeHitOutcome.Normal: case MeleeHitOutcome.Normal:
@@ -296,8 +297,6 @@ namespace Game.Entities
if (!damageNullified) if (!damageNullified)
m_hitMask |= ProcFlagsHit.Critical; m_hitMask |= ProcFlagsHit.Critical;
break; break;
default:
break;
} }
} }
+23 -23
View File
@@ -121,7 +121,7 @@ namespace Game.Entities
if (modOwner) if (modOwner)
{ {
ApCoeffMod *= 100.0f; ApCoeffMod *= 100.0f;
modOwner.ApplySpellMod(spellProto, SpellModOp.BonusMultiplier, ref ApCoeffMod); modOwner.ApplySpellMod(spellProto, SpellModOp.BonusCoefficient, ref ApCoeffMod);
ApCoeffMod /= 100.0f; ApCoeffMod /= 100.0f;
} }
@@ -145,7 +145,7 @@ namespace Game.Entities
if (modOwner) if (modOwner)
{ {
coeff *= 100.0f; coeff *= 100.0f;
modOwner.ApplySpellMod(spellProto, SpellModOp.BonusMultiplier, ref coeff); modOwner.ApplySpellMod(spellProto, SpellModOp.BonusCoefficient, ref coeff);
coeff /= 100.0f; coeff /= 100.0f;
} }
DoneTotal += (int)(DoneAdvertisedBenefit * coeff * stack); DoneTotal += (int)(DoneAdvertisedBenefit * coeff * stack);
@@ -158,9 +158,9 @@ namespace Game.Entities
if (_modOwner) if (_modOwner)
{ {
if (damagetype == DamageEffectType.DOT) if (damagetype == DamageEffectType.DOT)
_modOwner.ApplySpellMod(spellProto, SpellModOp.Dot, ref tmpDamage); _modOwner.ApplySpellMod(spellProto, SpellModOp.PeriodicHealingAndDamage, ref tmpDamage);
else else
_modOwner.ApplySpellMod(spellProto, SpellModOp.Damage, ref tmpDamage); _modOwner.ApplySpellMod(spellProto, SpellModOp.HealingAndDamage, ref tmpDamage);
} }
return (uint)Math.Max(tmpDamage, 0.0f); return (uint)Math.Max(tmpDamage, 0.0f);
@@ -321,7 +321,7 @@ namespace Game.Entities
if (modOwner) if (modOwner)
{ {
coeff *= 100.0f; coeff *= 100.0f;
modOwner.ApplySpellMod(spellProto, SpellModOp.BonusMultiplier, ref coeff); modOwner.ApplySpellMod(spellProto, SpellModOp.BonusCoefficient, ref coeff);
coeff /= 100.0f; coeff /= 100.0f;
} }
TakenTotal += (int)(TakenAdvertisedBenefit * coeff * stack); TakenTotal += (int)(TakenAdvertisedBenefit * coeff * stack);
@@ -400,7 +400,7 @@ namespace Game.Entities
// adds additional damage to critBonus (from talents) // adds additional damage to critBonus (from talents)
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellProto, SpellModOp.CritDamageBonus, ref crit_bonus); modOwner.ApplySpellMod(spellProto, SpellModOp.CritDamageAndHealing, ref crit_bonus);
damage += crit_bonus; damage += crit_bonus;
@@ -467,7 +467,7 @@ namespace Game.Entities
if (modOwner) if (modOwner)
{ {
coeff *= 100.0f; coeff *= 100.0f;
modOwner.ApplySpellMod(spellProto, SpellModOp.BonusMultiplier, ref coeff); modOwner.ApplySpellMod(spellProto, SpellModOp.BonusCoefficient, ref coeff);
coeff /= 100.0f; coeff /= 100.0f;
} }
@@ -498,9 +498,9 @@ namespace Game.Entities
if (_modOwner) if (_modOwner)
{ {
if (damagetype == DamageEffectType.DOT) if (damagetype == DamageEffectType.DOT)
_modOwner.ApplySpellMod(spellProto, SpellModOp.Dot, ref heal); _modOwner.ApplySpellMod(spellProto, SpellModOp.PeriodicHealingAndDamage, ref heal);
else else
_modOwner.ApplySpellMod(spellProto, SpellModOp.Damage, ref heal); _modOwner.ApplySpellMod(spellProto, SpellModOp.HealingAndDamage, ref heal);
} }
return (uint)Math.Max(heal, 0.0f); return (uint)Math.Max(heal, 0.0f);
@@ -599,7 +599,7 @@ namespace Game.Entities
if (modOwner) if (modOwner)
{ {
coeff *= 100.0f; coeff *= 100.0f;
modOwner.ApplySpellMod(spellProto, SpellModOp.BonusMultiplier, ref coeff); modOwner.ApplySpellMod(spellProto, SpellModOp.BonusCoefficient, ref coeff);
coeff /= 100.0f; coeff /= 100.0f;
} }
@@ -763,7 +763,7 @@ namespace Game.Entities
// only players use intelligence for critical chance computations // only players use intelligence for critical chance computations
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellProto, SpellModOp.CriticalChance, ref crit_chance); modOwner.ApplySpellMod(spellProto, SpellModOp.CritChance, ref crit_chance);
// for this types the bonus was already added in GetUnitCriticalChance, do not add twice // for this types the bonus was already added in GetUnitCriticalChance, do not add twice
if (spellProto.DmgClass != SpellDmgClass.Melee && spellProto.DmgClass != SpellDmgClass.Ranged) if (spellProto.DmgClass != SpellDmgClass.Melee && spellProto.DmgClass != SpellDmgClass.Ranged)
@@ -1012,10 +1012,10 @@ namespace Game.Entities
else else
modHitChance = 97 - levelBasedHitDiff; modHitChance = 97 - levelBasedHitDiff;
// Spellmod from SPELLMOD_RESIST_MISS_CHANCE // Spellmod from SpellModOp.HitChance
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spell, SpellModOp.ResistMissChance, ref modHitChance); modOwner.ApplySpellMod(spell, SpellModOp.HitChance, ref modHitChance);
// Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects
if (!spell.HasAttribute(SpellAttr3.IgnoreHitResult)) if (!spell.HasAttribute(SpellAttr3.IgnoreHitResult))
@@ -2021,7 +2021,7 @@ namespace Game.Entities
// called from caster // called from caster
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellInfo, SpellModOp.CastingTime, ref castTime, spell); modOwner.ApplySpellMod(spellInfo, SpellModOp.ChangeCastTime, ref castTime, spell);
if (!(spellInfo.HasAttribute(SpellAttr0.Ability | SpellAttr0.Tradespell) || spellInfo.HasAttribute(SpellAttr3.NoDoneBonus)) if (!(spellInfo.HasAttribute(SpellAttr0.Ability | SpellAttr0.Tradespell) || spellInfo.HasAttribute(SpellAttr3.NoDoneBonus))
&& (IsTypeId(TypeId.Player) && spellInfo.SpellFamilyName != 0) || IsTypeId(TypeId.Unit)) && (IsTypeId(TypeId.Player) && spellInfo.SpellFamilyName != 0) || IsTypeId(TypeId.Unit))
@@ -2042,7 +2042,7 @@ namespace Game.Entities
// called from caster // called from caster
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner) if (modOwner)
modOwner.ApplySpellMod(spellInfo, SpellModOp.CastingTime, ref duration, spell); modOwner.ApplySpellMod(spellInfo, SpellModOp.ChangeCastTime, ref duration, spell);
if (!(spellInfo.HasAttribute(SpellAttr0.Ability) || spellInfo.HasAttribute(SpellAttr0.Tradespell) || spellInfo.HasAttribute(SpellAttr3.NoDoneBonus)) && if (!(spellInfo.HasAttribute(SpellAttr0.Ability) || spellInfo.HasAttribute(SpellAttr0.Tradespell) || spellInfo.HasAttribute(SpellAttr3.NoDoneBonus)) &&
(IsTypeId(TypeId.Player) && spellInfo.SpellFamilyName != 0) || IsTypeId(TypeId.Unit)) (IsTypeId(TypeId.Player) && spellInfo.SpellFamilyName != 0) || IsTypeId(TypeId.Unit))
@@ -2055,23 +2055,23 @@ namespace Game.Entities
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
{ {
modOwner.ApplySpellMod(spellProto, SpellModOp.AllEffects, ref value); modOwner.ApplySpellMod(spellProto, SpellModOp.Points, ref value);
switch (effect_index) switch (effect_index)
{ {
case 0: case 0:
modOwner.ApplySpellMod(spellProto, SpellModOp.Effect1, ref value); modOwner.ApplySpellMod(spellProto, SpellModOp.PointsIndex0, ref value);
break; break;
case 1: case 1:
modOwner.ApplySpellMod(spellProto, SpellModOp.Effect2, ref value); modOwner.ApplySpellMod(spellProto, SpellModOp.PointsIndex1, ref value);
break; break;
case 2: case 2:
modOwner.ApplySpellMod(spellProto, SpellModOp.Effect3, ref value); modOwner.ApplySpellMod(spellProto, SpellModOp.PointsIndex2, ref value);
break; break;
case 3: case 3:
modOwner.ApplySpellMod(spellProto, SpellModOp.Effect4, ref value); modOwner.ApplySpellMod(spellProto, SpellModOp.PointsIndex3, ref value);
break; break;
case 4: case 4:
modOwner.ApplySpellMod(spellProto, SpellModOp.Effect5, ref value); modOwner.ApplySpellMod(spellProto, SpellModOp.PointsIndex4, ref value);
break; break;
} }
} }
@@ -2230,7 +2230,7 @@ namespace Game.Entities
// adds additional damage to critBonus (from talents) // adds additional damage to critBonus (from talents)
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellProto, SpellModOp.CritDamageBonus, ref crit_bonus); modOwner.ApplySpellMod(spellProto, SpellModOp.CritDamageAndHealing, ref crit_bonus);
crit_bonus += (int)damage; crit_bonus += (int)damage;
@@ -2444,7 +2444,7 @@ namespace Game.Entities
// Apply crit_damage bonus for melee spells // Apply crit_damage bonus for melee spells
Player modOwner = GetSpellModOwner(); Player modOwner = GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(spellInfo, SpellModOp.CritDamageBonus, ref crit_bonus); modOwner.ApplySpellMod(spellInfo, SpellModOp.CritDamageAndHealing, ref crit_bonus);
damage += (int)crit_bonus; damage += (int)crit_bonus;
// Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS // Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
+14 -5
View File
@@ -878,7 +878,7 @@ namespace Game.Spells
{ {
Player modOwner = caster.GetSpellModOwner(); Player modOwner = caster.GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.MaxStackAmount, ref maxStackAmount); modOwner.ApplySpellMod(m_spellInfo, SpellModOp.MaxAuraStacks, ref maxStackAmount);
} }
return maxStackAmount; return maxStackAmount;
} }
@@ -1025,7 +1025,7 @@ namespace Game.Spells
{ {
Player modOwner = caster.GetSpellModOwner(); Player modOwner = caster.GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ResistDispelChance, ref resistChance); modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.DispelResistance, ref resistChance);
} }
resistChance = resistChance < 0 ? 0 : 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) // 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); SetLastProcSuccessTime(now);
} }
@@ -1807,7 +1816,7 @@ namespace Game.Spells
// apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell) // apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell)
Player modOwner = caster.GetSpellModOwner(); Player modOwner = caster.GetSpellModOwner();
if (modOwner != null) 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 // proc chance is reduced by an additional 3.333% per level past 60
@@ -2321,7 +2330,7 @@ namespace Game.Spells
{ {
Player modOwner = caster.GetSpellModOwner(); Player modOwner = caster.GetSpellModOwner();
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.Charges, ref maxProcCharges); modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ProcCharges, ref maxProcCharges);
} }
return (byte)maxProcCharges; return (byte)maxProcCharges;
} }
+45 -61
View File
@@ -27,6 +27,7 @@ using Game.Networking.Packets;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Collections;
namespace Game.Spells namespace Game.Spells
{ {
@@ -188,7 +189,7 @@ namespace Game.Spells
{ {
// Apply periodic time mod // Apply periodic time mod
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.ActivationTime, ref _period); modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.Period, ref _period);
if (caster != null) if (caster != null)
{ {
@@ -346,71 +347,54 @@ namespace Game.Spells
return; return;
// reapply some passive spells after add/remove related spellmods // reapply some passive spells after add/remove related spellmods
// Warning: it is a dead loop if 2 auras each other amount-shouldn't happen // Warning: it is a dead loop if 2 auras each other amount-shouldn't happen
BitSet recalculateEffectMask = new(SpellConst.MaxEffects);
switch ((SpellModOp)GetMiscValue()) switch ((SpellModOp)GetMiscValue())
{ {
case SpellModOp.AllEffects: case SpellModOp.Points:
case SpellModOp.Effect1: recalculateEffectMask.SetAll(true);
case SpellModOp.Effect2: break;
case SpellModOp.Effect3: case SpellModOp.PointsIndex0:
case SpellModOp.Effect4: recalculateEffectMask.Set(0, true);
case SpellModOp.Effect5: break;
{ case SpellModOp.PointsIndex1:
ObjectGuid guid = target.GetGUID(); recalculateEffectMask.Set(1, true);
foreach (var iter in target.GetAppliedAuras()) break;
{ case SpellModOp.PointsIndex2:
if (iter.Value == null) recalculateEffectMask.Set(2, true);
continue; break;
Aura aura = iter.Value.GetBase(); case SpellModOp.PointsIndex3:
// only passive and permament auras-active auras should have amount set on spellcast and not be affected recalculateEffectMask.Set(3, true);
// if aura is casted by others, it will not be affected break;
if ((aura.IsPassive() || aura.IsPermanent()) && aura.GetCasterGUID() == guid && aura.GetSpellInfo().IsAffectedBySpellMod(m_spellmod)) case SpellModOp.PointsIndex4:
{ recalculateEffectMask.Set(4, true);
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();
}
}
}
}
break; break;
default: default:
break; 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) public void Update(uint diff, Unit caster)
@@ -4910,7 +4894,7 @@ namespace Game.Spells
uint weaponDamage = MathFunctions.CalculatePct(caster.CalculateDamage(attackType, false, true), GetAmount()); uint weaponDamage = MathFunctions.CalculatePct(caster.CalculateDamage(attackType, false, true), GetAmount());
// Add melee damage bonuses (also check for negative) // 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()); damage = target.MeleeDamageBonusTaken(caster, damageBonusDone, attackType, DamageEffectType.DOT, GetSpellInfo());
break; break;
+8 -8
View File
@@ -68,7 +68,7 @@ namespace Game.Spells
Player modOwner = caster.GetSpellModOwner(); Player modOwner = caster.GetSpellModOwner();
if (modOwner != null) 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()) if (!originalCasterGUID.IsEmpty())
m_originalCasterGUID = originalCasterGUID; m_originalCasterGUID = originalCasterGUID;
@@ -1089,7 +1089,7 @@ namespace Game.Spells
int maxTargets = effect.ChainTargets; int maxTargets = effect.ChainTargets;
Player modOwner = m_caster.GetSpellModOwner(); Player modOwner = m_caster.GetSpellModOwner();
if (modOwner) if (modOwner)
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.JumpTargets, ref maxTargets, this); modOwner.ApplySpellMod(m_spellInfo, SpellModOp.ChainTargets, ref maxTargets, this);
if (maxTargets > 1) if (maxTargets > 1)
{ {
@@ -1411,7 +1411,7 @@ namespace Game.Spells
Player modOwner = m_caster.GetSpellModOwner(); Player modOwner = m_caster.GetSpellModOwner();
if (modOwner) 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 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
bool isBouncingFar = (m_spellInfo.HasAttribute(SpellAttr4.AreaTargetChain) bool isBouncingFar = (m_spellInfo.HasAttribute(SpellAttr4.AreaTargetChain)
@@ -4210,7 +4210,7 @@ namespace Game.Spells
//lower spell cost on fail (by talent aura) //lower spell cost on fail (by talent aura)
Player modOwner = m_caster.ToPlayer().GetSpellModOwner(); Player modOwner = m_caster.ToPlayer().GetSpellModOwner();
if (modOwner) if (modOwner)
modOwner.ApplySpellMod(m_spellInfo, SpellModOp.SpellCostRefundOnFail, ref cost.Amount); modOwner.ApplySpellMod(m_spellInfo, SpellModOp.PowerCostOnMiss, ref cost.Amount);
} }
break; break;
} }
@@ -6434,7 +6434,7 @@ namespace Game.Spells
//check pushback reduce //check pushback reduce
int delaytime = 500; // spellcasting delay is normally 500ms int delaytime = 500; // spellcasting delay is normally 500ms
int delayReduce = 100; // must be initialized to 100 for percent modifiers 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; delayReduce += m_caster.GetTotalAuraModifier(AuraType.ReducePushback) - 100;
if (delayReduce >= 100) if (delayReduce >= 100)
return; return;
@@ -6469,7 +6469,7 @@ namespace Game.Spells
//check pushback reduce //check pushback reduce
int delaytime = MathFunctions.CalculatePct(m_spellInfo.GetDuration(), 25); // channeling delay is normally 25% of its time per hit 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 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; delayReduce += m_caster.GetTotalAuraModifier(AuraType.ReducePushback) - 100;
if (delayReduce >= 100) if (delayReduce >= 100)
return; return;
@@ -7236,7 +7236,7 @@ namespace Game.Spells
// gcd modifier auras are applied only to own spells and only players have such mods // gcd modifier auras are applied only to own spells and only players have such mods
Player modOwner = m_caster.GetSpellModOwner(); Player modOwner = m_caster.GetSpellModOwner();
if (modOwner) 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 || bool isMeleeOrRangedSpell = m_spellInfo.DmgClass == SpellDmgClass.Melee || m_spellInfo.DmgClass == SpellDmgClass.Ranged ||
m_spellInfo.HasAttribute(SpellAttr0.ReqAmmo) || m_spellInfo.HasAttribute(SpellAttr0.Ability); m_spellInfo.HasAttribute(SpellAttr0.ReqAmmo) || m_spellInfo.HasAttribute(SpellAttr0.Ability);
@@ -7724,7 +7724,7 @@ namespace Game.Spells
{ {
public SpellModifier(Aura _ownerAura) public SpellModifier(Aura _ownerAura)
{ {
op = SpellModOp.Damage; op = SpellModOp.HealingAndDamage;
type = SpellModType.Flat; type = SpellModType.Flat;
value = 0; value = 0;
mask = new FlagArray128(); mask = new FlagArray128();
+1 -1
View File
@@ -2635,7 +2635,7 @@ namespace Game.Spells
uint eff_damage = Math.Max(weaponDamage, 0); uint eff_damage = Math.Max(weaponDamage, 0);
// Add melee damage bonuses (also check for negative) // 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); m_damage += (int)unitTarget.MeleeDamageBonusTaken(m_caster, damage, m_attackType, DamageEffectType.SpellDirect, m_spellInfo);
} }
+8 -6
View File
@@ -2839,13 +2839,13 @@ namespace Game.Spells
switch (power.OrderIndex) switch (power.OrderIndex)
{ {
case 0: case 0:
mod = SpellModOp.Cost; mod = SpellModOp.PowerCost0;
break; break;
case 1: case 1:
mod = SpellModOp.SpellCost2; mod = SpellModOp.PowerCost1;
break; break;
case 2: case 2:
mod = SpellModOp.SpellCost3; mod = SpellModOp.PowerCost2;
break; break;
default: default:
break; break;
@@ -3410,7 +3410,9 @@ namespace Game.Spells
// non-positive mods // non-positive mods
switch ((SpellModOp)effect.MiscValue) 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 (effect.CalcValue() > 0)
{ {
if (!deep) if (!deep)
@@ -3963,7 +3965,7 @@ namespace Game.Spells
float multiplier = Amplitude; float multiplier = Amplitude;
Player modOwner = (caster != null ? caster.GetSpellModOwner() : null); Player modOwner = (caster != null ? caster.GetSpellModOwner() : null);
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(_spellInfo, SpellModOp.ValueMultiplier, ref multiplier, spell); modOwner.ApplySpellMod(_spellInfo, SpellModOp.Amplitude, ref multiplier, spell);
return multiplier; return multiplier;
} }
@@ -3972,7 +3974,7 @@ namespace Game.Spells
float multiplierPercent = ChainAmplitude * 100.0f; float multiplierPercent = ChainAmplitude * 100.0f;
Player modOwner = (caster != null ? caster.GetSpellModOwner() : null); Player modOwner = (caster != null ? caster.GetSpellModOwner() : null);
if (modOwner != null) if (modOwner != null)
modOwner.ApplySpellMod(_spellInfo, SpellModOp.DamageMultiplier, ref multiplierPercent, spell); modOwner.ApplySpellMod(_spellInfo, SpellModOp.ChainAmplitude, ref multiplierPercent, spell);
return multiplierPercent / 100.0f; return multiplierPercent / 100.0f;
} }
+1 -1
View File
@@ -415,7 +415,7 @@ namespace Scripts.Spells.Druid
if (spellMod == null) if (spellMod == null)
{ {
spellMod = new SpellModifier(GetAura()); spellMod = new SpellModifier(GetAura());
spellMod.op = SpellModOp.Dot; spellMod.op = SpellModOp.PeriodicHealingAndDamage;
spellMod.type = SpellModType.Flat; spellMod.type = SpellModType.Flat;
spellMod.spellId = GetId(); spellMod.spellId = GetId();
spellMod.mask = aurEff.GetSpellEffectInfo().SpellClassMask; spellMod.mask = aurEff.GetSpellEffectInfo().SpellClassMask;
+1 -1
View File
@@ -279,7 +279,7 @@ namespace Scripts.Spells.Warlock
Player modOwner = caster.GetSpellModOwner(); Player modOwner = caster.GetSpellModOwner();
if (modOwner) if (modOwner)
modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.Cost, ref damage); modOwner.ApplySpellMod(GetSpellInfo(), SpellModOp.PowerCost0, ref damage);
SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, caster, GetSpellInfo(), GetAura().GetSpellVisual(), GetSpellInfo().SchoolMask, GetAura().GetCastGUID()); SpellNonMeleeDamage damageInfo = new SpellNonMeleeDamage(caster, caster, GetSpellInfo(), GetAura().GetSpellVisual(), GetSpellInfo().SchoolMask, GetAura().GetCastGUID());
damageInfo.periodicLog = true; damageInfo.periodicLog = true;