diff --git a/Source/Framework/Constants/Spells/SpellConst.cs b/Source/Framework/Constants/Spells/SpellConst.cs index 0899ccc66..72773b28c 100644 --- a/Source/Framework/Constants/Spells/SpellConst.cs +++ b/Source/Framework/Constants/Spells/SpellConst.cs @@ -1907,7 +1907,7 @@ namespace Framework.Constants NotAnAttack = 0x04, /*Nyi*/ // Not An Attack CanAssistImmunePc = 0x08, // Can Assist Immune Pc IgnoreForModTimeRate = 0x10, /*Nyi, Time Rate Not Implemented*/ // Ignore For Mod Time Rate - DoNotConsumeResources = 0x20, // Do Not Consume Resources + DoNotConsumeResources = 0x20, // Do Not Consume Resources Requires power/reagents to cast but doesn't consume them FloatingCombatTextOnCast = 0x40, // Floating Combat Text On Cast (Client Only) AuraIsWeaponProc = 0x80, // Aura Is Weapon Proc DoNotChainToCrowdControlledTargets = 0x100, // Do Not Chain To Crowd-Controlled Targets Description Implicit Targeting (Chaining And Area Targeting) Will Not Impact Crowd Controlled Targets diff --git a/Source/Game/Spells/Auras/Aura.cs b/Source/Game/Spells/Auras/Aura.cs index 89f0bceed..51b4b136c 100644 --- a/Source/Game/Spells/Auras/Aura.cs +++ b/Source/Game/Spells/Auras/Aura.cs @@ -350,12 +350,15 @@ namespace Game.Spells m_lastProcAttemptTime = (DateTime.Now - TimeSpan.FromSeconds(10)); m_lastProcSuccessTime = (DateTime.Now - TimeSpan.FromSeconds(120)); - foreach (SpellPowerRecord power in m_spellInfo.PowerCosts) - if (power != null && (power.ManaPerSecond != 0 || power.PowerPctPerSecond > 0.0f)) - m_periodicCosts.Add(power); + if (!m_spellInfo.HasAttribute(SpellAttr6.DoNotConsumeResources)) + { + foreach (SpellPowerRecord power in m_spellInfo.PowerCosts) + if (power != null && (power.ManaPerSecond != 0 || power.PowerPctPerSecond > 0.0f)) + m_periodicCosts.Add(power); - if (!m_periodicCosts.Empty()) - m_timeCla = 1 * Time.InMilliseconds; + if (!m_periodicCosts.Empty()) + m_timeCla = 1 * Time.InMilliseconds; + } m_maxDuration = CalcMaxDuration(createInfo.Caster); m_duration = m_maxDuration; diff --git a/Source/Game/Spells/Auras/AuraEffect.cs b/Source/Game/Spells/Auras/AuraEffect.cs index 9827536f9..f4c658cde 100644 --- a/Source/Game/Spells/Auras/AuraEffect.cs +++ b/Source/Game/Spells/Auras/AuraEffect.cs @@ -5143,7 +5143,7 @@ namespace Game.Spells Unit triggerCaster = triggeredSpellInfo.NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target; if (triggerCaster != null) { - triggerCaster.CastSpell(target, triggerSpellId, new CastSpellExtraArgs(this)); + triggerCaster.CastSpell(target, triggerSpellId, new CastSpellExtraArgs(TriggerCastFlags.FullMask & ~(TriggerCastFlags.IgnorePowerCost | TriggerCastFlags.IgnoreReagentCost)).TriggeringAura = this); Log.outDebug(LogFilter.Spells, "AuraEffect.HandlePeriodicTriggerSpellAuraTick: Spell {0} Trigger {1}", GetId(), triggeredSpellInfo.Id); } } @@ -5167,6 +5167,7 @@ namespace Game.Spells if (triggerCaster != null) { CastSpellExtraArgs args = new(this); + args.SetTriggerFlags(TriggerCastFlags.FullMask & ~(TriggerCastFlags.IgnorePowerCost | TriggerCastFlags.IgnoreReagentCost)); for (int i = 0; i < SpellConst.MaxEffects; ++i) args.AddSpellMod(SpellValueMod.BasePoint0 + i, GetAmount()); @@ -5712,7 +5713,9 @@ namespace Game.Spells if (triggeredSpellInfo != null) { Log.outDebug(LogFilter.Spells, $"AuraEffect.HandleProcTriggerSpellAuraProc: Triggering spell {triggeredSpellInfo.Id} from aura {GetId()} proc"); - triggerCaster.CastSpell(triggerTarget, triggeredSpellInfo.Id, new CastSpellExtraArgs(this).SetTriggeringSpell(eventInfo.GetProcSpell())); + triggerCaster.CastSpell(triggerTarget, triggeredSpellInfo.Id, new CastSpellExtraArgs(this) + .SetTriggeringSpell(eventInfo.GetProcSpell()) + .SetTriggerFlags(TriggerCastFlags.FullMask & ~(TriggerCastFlags.IgnorePowerCost | TriggerCastFlags.IgnoreReagentCost))); } else if (triggerSpellId != 0 && GetAuraType() != AuraType.Dummy) Log.outError(LogFilter.Spells, $"AuraEffect.HandleProcTriggerSpellAuraProc: Spell {GetId()} has non-existent spell {triggerSpellId} in EffectTriggered[{GetEffIndex()}] and is therefore not triggered."); @@ -5736,6 +5739,7 @@ namespace Game.Spells if (triggeredSpellInfo != null) { CastSpellExtraArgs args = new(this); + args.SetTriggerFlags(TriggerCastFlags.FullMask & ~(TriggerCastFlags.IgnorePowerCost | TriggerCastFlags.IgnoreReagentCost)); args.SetTriggeringSpell(eventInfo.GetProcSpell()); args.AddSpellMod(SpellValueMod.BasePoint0, GetAmount()); triggerCaster.CastSpell(triggerTarget, triggerSpellId, args); diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index afb23870d..3f4879661 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -4716,7 +4716,7 @@ namespace Game.Spells if (unitCaster == null) return; - if (m_CastItem != null || m_triggeredByAuraSpell != null) + if (m_CastItem != null || m_spellInfo.HasAttribute(SpellAttr6.DoNotConsumeResources)) return; //Don't take power if the spell is cast while .cheat power is enabled. @@ -4774,7 +4774,7 @@ namespace Game.Spells if (unitCaster == null) return; - if (m_CastItem != null || m_triggeredByAuraSpell != null) + if (m_CastItem != null || m_spellInfo.HasAttribute(SpellAttr6.DoNotConsumeResources)) return; //Don't take power if the spell is cast while .cheat power is enabled. @@ -4868,7 +4868,7 @@ namespace Game.Spells return; // do not take reagents for these item casts - if (m_CastItem != null && m_CastItem.GetTemplate().HasFlag(ItemFlags.NoReagentCost)) + if ((m_CastItem != null && m_CastItem.GetTemplate().HasFlag(ItemFlags.NoReagentCost)) || m_spellInfo.HasAttribute(SpellAttr6.DoNotConsumeResources)) return; Player p_caster = m_caster.ToPlayer(); diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index e4b38dc12..514177a29 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -309,7 +309,7 @@ namespace Game.Spells targets.Update(caster); // refresh pointers stored in targets // original caster guid only for GO cast - CastSpellExtraArgs args = new(TriggerCastFlags.FullMask); + CastSpellExtraArgs args = new(TriggerCastFlags.FullMask & ~(TriggerCastFlags.IgnorePowerCost | TriggerCastFlags.IgnoreReagentCost)); args.SetOriginalCaster(originalCaster); args.OriginalCastId = originalCastId; args.OriginalCastItemLevel = itemLevel; @@ -389,7 +389,7 @@ namespace Game.Spells } } - CastSpellExtraArgs args = new(TriggerCastFlags.FullMask); + CastSpellExtraArgs args = new(TriggerCastFlags.FullMask & ~(TriggerCastFlags.IgnorePowerCost | TriggerCastFlags.IgnoreReagentCost)); args.SetOriginalCaster(m_originalCasterGUID); args.SetTriggeringSpell(this); args.SetCustomArg(m_customArg); @@ -464,7 +464,7 @@ namespace Game.Spells return; } - CastSpellExtraArgs args = new(TriggerCastFlags.FullMask); + CastSpellExtraArgs args = new(TriggerCastFlags.FullMask & ~(TriggerCastFlags.IgnorePowerCost | TriggerCastFlags.IgnoreReagentCost)); args.SetTriggeringSpell(this); // set basepoints for trigger with value effect if (effectInfo.Effect == SpellEffectName.ForceCastWithValue)