diff --git a/Source/Game/Entities/Player/Player.Spells.cs b/Source/Game/Entities/Player/Player.Spells.cs index e556186f7..0bef138fe 100644 --- a/Source/Game/Entities/Player/Player.Spells.cs +++ b/Source/Game/Entities/Player/Player.Spells.cs @@ -274,20 +274,23 @@ namespace Game.Entities return false; } - public override SpellInfo GetCastSpellInfo(SpellInfo spellInfo, TriggerCastFlags triggerFlag) + public override SpellInfo GetCastSpellInfo(SpellInfo spellInfo, TriggerCastFlags triggerFlag, GetCastSpellInfoContext context) { var overrides = m_overrideSpells.LookupByKey(spellInfo.Id); if (!overrides.Empty()) { foreach (uint spellId in overrides) { - SpellInfo newInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID()); - if (newInfo != null) - return GetCastSpellInfo(newInfo, triggerFlag); + if (context.AddSpell(spellId)) + { + SpellInfo newInfo = Global.SpellMgr.GetSpellInfo(spellId, GetMap().GetDifficultyID()); + if (newInfo != null) + return GetCastSpellInfo(newInfo, triggerFlag, context); + } } } - return base.GetCastSpellInfo(spellInfo, triggerFlag); + return base.GetCastSpellInfo(spellInfo, triggerFlag, context); } public void SetOverrideSpellsId(uint overrideSpellsId) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OverrideSpellsID), overrideSpellsId); } @@ -3879,7 +3882,8 @@ namespace Game.Entities } // Check possible spell cast overrides - spellInfo = castingUnit.GetCastSpellInfo(spellInfo, triggerFlag); + GetCastSpellInfoContext overrideContext = new(); + spellInfo = castingUnit.GetCastSpellInfo(spellInfo, triggerFlag, overrideContext); if (spellInfo.IsPassive()) { CancelPendingCastRequest(); diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index 8f5128b6f..caaf0db66 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -944,14 +944,14 @@ namespace Game.Entities spell.Finish(result); } - public virtual SpellInfo GetCastSpellInfo(SpellInfo spellInfo, TriggerCastFlags triggerFlag) + public virtual SpellInfo GetCastSpellInfo(SpellInfo spellInfo, TriggerCastFlags triggerFlag, GetCastSpellInfoContext context) { SpellInfo findMatchingAuraEffectIn(AuraType type) { foreach (AuraEffect auraEffect in GetAuraEffectsByType(type)) { bool matches = auraEffect.GetMiscValue() != 0 ? auraEffect.GetMiscValue() == spellInfo.Id : auraEffect.IsAffectingSpell(spellInfo); - if (matches) + if (matches && context.AddSpell((uint)auraEffect.GetAmount())) { SpellInfo info = Global.SpellMgr.GetSpellInfo((uint)auraEffect.GetAmount(), GetMap().GetDifficultyID()); if (info != null) @@ -979,14 +979,14 @@ namespace Game.Entities if (newInfo != null) { triggerFlag &= ~TriggerCastFlags.IgnoreCastTime; - return GetCastSpellInfo(newInfo, triggerFlag); + return GetCastSpellInfo(newInfo, triggerFlag, context); } newInfo = findMatchingAuraEffectIn(AuraType.OverrideActionbarSpellsTriggered); if (newInfo != null) { triggerFlag |= TriggerCastFlags.IgnoreCastTime; - return GetCastSpellInfo(newInfo, triggerFlag); + return GetCastSpellInfo(newInfo, triggerFlag, context); } return spellInfo; @@ -4602,4 +4602,26 @@ namespace Game.Entities public void SetVisibleAuraUpdate(AuraApplication aurApp) { m_visibleAurasToUpdate.Add(aurApp); } public void RemoveVisibleAuraUpdate(AuraApplication aurApp) { m_visibleAurasToUpdate.Remove(aurApp); } } + + public class GetCastSpellInfoContext + { + uint[] VisitedSpells = new uint[5]; + + public bool AddSpell(uint spellId) + { + if (VisitedSpells.Contains(spellId)) + return false; // already exists + + for (int i = 0; i < VisitedSpells.Length; ++i) + { + if (VisitedSpells[i] != 0u) + continue; + + VisitedSpells[i] = spellId; + return true; + } + + return false; + } + } }