From 3971aea8f98e989098ceafcf3bf9b350ff093b98 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Fri, 8 Oct 2021 10:30:35 -0400 Subject: [PATCH] Core/Spells: Implemented SpellValueMod duration Port From (https://github.com/TrinityCore/TrinityCore/commit/a048475cb037a3a3672723c1f2ab32a343142927) --- Source/Framework/Constants/UnitConst.cs | 3 +- Source/Game/Spells/Spell.cs | 85 +++++++++++++++---------- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/Source/Framework/Constants/UnitConst.cs b/Source/Framework/Constants/UnitConst.cs index 6758722e8..510011620 100644 --- a/Source/Framework/Constants/UnitConst.cs +++ b/Source/Framework/Constants/UnitConst.cs @@ -396,7 +396,8 @@ namespace Framework.Constants MaxTargets, AuraStack, CritChance, - DurationPct + DurationPct, + Duration } public enum CombatRating diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index ca2908ee8..b0484ce2c 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -2048,34 +2048,39 @@ namespace Game.Spells spellAura.SetDiminishGroup(hitInfo.DRGroup); - hitInfo.AuraDuration = caster.ModSpellDuration(m_spellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, spellAura.GetEffectMask()); - - if (hitInfo.AuraDuration > 0) + if (!m_spellValue.Duration.HasValue) { - hitInfo.AuraDuration *= (int)m_spellValue.DurationMul; + hitInfo.AuraDuration *= caster.ModSpellDuration(m_spellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, spellAura.GetEffectMask()); - // Haste modifies duration of channeled spells - if (m_spellInfo.IsChanneled()) - caster.ModSpellDurationTime(m_spellInfo, ref hitInfo.AuraDuration, this); - else if (m_spellInfo.HasAttribute(SpellAttr5.HasteAffectDuration)) + if (hitInfo.AuraDuration > 0) { - int origDuration = hitInfo.AuraDuration; - hitInfo.AuraDuration = 0; - foreach (AuraEffect auraEff in spellAura.GetAuraEffects()) - { - if (auraEff != null) - { - int period = auraEff.GetPeriod(); - if (period != 0) // period is hastened by UNIT_MOD_CAST_SPEED - hitInfo.AuraDuration = Math.Max(Math.Max(origDuration / period, 1) * period, hitInfo.AuraDuration); - } - } + hitInfo.AuraDuration *= (int)m_spellValue.DurationMul; - // if there is no periodic effect - if (hitInfo.AuraDuration == 0) - hitInfo.AuraDuration = (int)(origDuration * m_originalCaster.m_unitData.ModCastingSpeed); + // Haste modifies duration of channeled spells + if (m_spellInfo.IsChanneled()) + caster.ModSpellDurationTime(m_spellInfo, ref hitInfo.AuraDuration, this); + else if (m_spellInfo.HasAttribute(SpellAttr5.HasteAffectDuration)) + { + int origDuration = hitInfo.AuraDuration; + hitInfo.AuraDuration = 0; + foreach (AuraEffect auraEff in spellAura.GetAuraEffects()) + { + if (auraEff != null) + { + int period = auraEff.GetPeriod(); + if (period != 0) // period is hastened by UNIT_MOD_CAST_SPEED + hitInfo.AuraDuration = Math.Max(Math.Max(origDuration / period, 1) * period, hitInfo.AuraDuration); + } + } + + // if there is no periodic effect + if (hitInfo.AuraDuration == 0) + hitInfo.AuraDuration = (int)(origDuration * m_originalCaster.m_unitData.ModCastingSpeed); + } } } + else + hitInfo.AuraDuration = m_spellValue.Duration.Value; if (hitInfo.AuraDuration != spellAura.GetMaxDuration()) { @@ -2799,23 +2804,29 @@ namespace Game.Spells if (m_spellInfo.IsChanneled()) { int duration = m_spellInfo.GetDuration(); - if (duration > 0) + if (duration > 0 || m_spellValue.Duration.HasValue) { - // First mod_duration then haste - see Missile Barrage - // Apply duration mod - Player modOwner = m_caster.GetSpellModOwner(); - if (modOwner != null) - modOwner.ApplySpellMod(m_spellInfo, SpellModOp.Duration, ref duration); + if (!m_spellValue.Duration.HasValue) + { + // First mod_duration then haste - see Missile Barrage + // Apply duration mod + Player modOwner = m_caster.GetSpellModOwner(); + if (modOwner != null) + modOwner.ApplySpellMod(m_spellInfo, SpellModOp.Duration, ref duration); - duration = (int)(duration * m_spellValue.DurationMul); + duration = (int)(duration * m_spellValue.DurationMul); - // Apply haste mods - m_caster.ModSpellDurationTime(m_spellInfo, ref duration, this); + // Apply haste mods + m_caster.ModSpellDurationTime(m_spellInfo, ref duration, this); + } + else + duration = m_spellValue.Duration.Value; + m_channeledDuration = duration; SendChannelStart((uint)duration); } else if (duration == -1) - SendChannelStart((uint)duration); + SendChannelStart(unchecked((uint)duration)); if (duration != 0) { @@ -6424,7 +6435,10 @@ namespace Game.Spells return; //check pushback reduce - int delaytime = MathFunctions.CalculatePct(m_spellInfo.GetDuration(), 25); // channeling delay is normally 25% of its time per hit + // should be affected by modifiers, not take the dbc duration. + int duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo.GetDuration()); + + int delaytime = MathFunctions.CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit int delayReduce = 100; // must be initialized to 100 for percent modifiers Player player = unitCaster.GetSpellModOwner(); @@ -6879,6 +6893,9 @@ namespace Game.Spells case SpellValueMod.DurationPct: m_spellValue.DurationMul = (float)value / 100.0f; break; + case SpellValueMod.Duration: + m_spellValue.Duration.Set(value); + break; } } @@ -7415,6 +7432,7 @@ namespace Game.Spells List m_powerCost = new(); int m_casttime; // Calculated spell cast time initialized only in Spell.prepare + int m_channeledDuration; // Calculated channeled spell duration in order to calculate correct pushback. bool m_canReflect; // can reflect this spell? bool m_autoRepeat; byte m_runesState; @@ -8073,6 +8091,7 @@ namespace Game.Spells public int AuraStackAmount; public float DurationMul; public float CriticalChance; + public Optional Duration; } // Spell modifier (used for modify other spells)