diff --git a/Source/Framework/Constants/Spells/SpellConst.cs b/Source/Framework/Constants/Spells/SpellConst.cs index 2946ce2e7..51e3ebe4a 100644 --- a/Source/Framework/Constants/Spells/SpellConst.cs +++ b/Source/Framework/Constants/Spells/SpellConst.cs @@ -1986,7 +1986,7 @@ namespace Framework.Constants AutocastOffByDefault = 0x20000, // AutoCast Off By Default IgnoreSchoolLockout = 0x40000, // Ignore School Lockout AllowDarkSimulacrum = 0x80000, // Allow Dark Simulacrum - Unk20 = 0x100000, // 20 + AllowCastWhileChanneling = 0x100000, // Allow Cast While Channeling Unk21 = 0x200000, // 21 Unk22 = 0x400000, // 22 Unk23 = 0x800000, // 23 diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index 4479796c8..10373b937 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -1814,7 +1814,8 @@ namespace Game.Entities InterruptSpell(CurrentSpellTypes.Generic, false); // generic spells always break channeled not delayed spells - if (GetCurrentSpell(CurrentSpellTypes.Channeled) != null && !GetCurrentSpell(CurrentSpellTypes.Channeled).GetSpellInfo().HasAttribute(SpellAttr5.AllowActionsDuringChannel)) + if (GetCurrentSpell(CurrentSpellTypes.Channeled) != null && !GetCurrentSpell(CurrentSpellTypes.Channeled).GetSpellInfo().HasAttribute(SpellAttr5.AllowActionsDuringChannel) + && !pSpell.GetSpellInfo().HasAttribute(SpellAttr9.AllowCastWhileChanneling)) InterruptSpell(CurrentSpellTypes.Channeled, false); // autorepeat breaking @@ -2979,7 +2980,7 @@ namespace Game.Entities return dispelList; } - bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags flag, Unit unit, SpellInfo auraSpellInfo, SpellInfo interruptSource) + bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags flag, Unit unit, SpellInfo auraSpellInfo, bool isChannel, SpellInfo interruptSource) { switch (flag) { @@ -2994,6 +2995,9 @@ namespace Game.Entities if (interruptSource.HasAttribute(SpellAttr2.AllowWhileInvisible) && auraSpellInfo.Dispel == DispelType.Invisibility) return true; + + if (interruptSource.HasAttribute(SpellAttr9.AllowCastWhileChanneling) && isChannel) + return true; } break; default: @@ -3003,7 +3007,7 @@ namespace Game.Entities return false; } - bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags2 flag, Unit unit, SpellInfo auraSpellInfo, SpellInfo interruptSource) + bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags2 flag, Unit unit, SpellInfo auraSpellInfo, bool isChannel, SpellInfo interruptSource) { return false; } @@ -3018,7 +3022,7 @@ namespace Game.Entities { Aura aura = m_interruptableAuras[i].GetBase(); - if (aura.GetSpellInfo().HasAuraInterruptFlag(flag) && (source == null || aura.GetId() != source.Id) && !IsInterruptFlagIgnoredForSpell(flag, this, aura.GetSpellInfo(), source)) + if (aura.GetSpellInfo().HasAuraInterruptFlag(flag) && (source == null || aura.GetId() != source.Id) && !IsInterruptFlagIgnoredForSpell(flag, this, aura.GetSpellInfo(), false, source)) { uint removedAuras = m_removedAurasCount; RemoveAura(aura, AuraRemoveMode.Interrupt); @@ -3034,7 +3038,7 @@ namespace Game.Entities if (spell.GetState() == SpellState.Casting && spell.GetSpellInfo().HasChannelInterruptFlag(flag) && (source == null || spell.GetSpellInfo().Id != source.Id) - && !IsInterruptFlagIgnoredForSpell(flag, this, spell.GetSpellInfo(), source)) + && !IsInterruptFlagIgnoredForSpell(flag, this, spell.GetSpellInfo(), true, source)) InterruptNonMeleeSpells(false); } @@ -3051,7 +3055,7 @@ namespace Game.Entities { Aura aura = m_interruptableAuras[i].GetBase(); - if (aura.GetSpellInfo().HasAuraInterruptFlag(flag) && (source == null || aura.GetId() != source.Id) && !IsInterruptFlagIgnoredForSpell(flag, this, aura.GetSpellInfo(), source)) + if (aura.GetSpellInfo().HasAuraInterruptFlag(flag) && (source == null || aura.GetId() != source.Id) && !IsInterruptFlagIgnoredForSpell(flag, this, aura.GetSpellInfo(), false, source)) { uint removedAuras = m_removedAurasCount; RemoveAura(aura, AuraRemoveMode.Interrupt); @@ -3067,7 +3071,7 @@ namespace Game.Entities if (spell.GetState() == SpellState.Casting && spell.GetSpellInfo().HasChannelInterruptFlag(flag) && (source == null || spell.GetSpellInfo().Id != source.Id) - && !IsInterruptFlagIgnoredForSpell(flag, this, spell.GetSpellInfo(), source)) + && !IsInterruptFlagIgnoredForSpell(flag, this, spell.GetSpellInfo(), true, source)) InterruptNonMeleeSpells(false); } diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index 391964654..b14f3d13f 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -2583,7 +2583,7 @@ namespace Game.Spells } // Prevent casting at cast another spell (ServerSide check) - if (!_triggeredCastFlags.HasFlag(TriggerCastFlags.IgnoreCastInProgress) && m_caster.ToUnit() != null && m_caster.ToUnit().IsNonMeleeSpellCast(false, true, true, m_spellInfo.Id == 75) && !m_castId.IsEmpty()) + if (!_triggeredCastFlags.HasFlag(TriggerCastFlags.IgnoreCastInProgress) && m_caster.ToUnit() != null && m_caster.ToUnit().IsNonMeleeSpellCast(false, true, true, m_spellInfo.Id == 75)) { SendCastResult(SpellCastResult.SpellInProgress); Finish(SpellCastResult.SpellInProgress);