Core/Auras: Prevent recursive infinite loops with spell mod auras affecting each other

Port From (https://github.com/TrinityCore/TrinityCore/commit/cfb32584b0bd91a091e9861a51533ee157792d8e)
This commit is contained in:
hondacrx
2021-03-29 16:11:20 -04:00
parent c1fb79b086
commit 369e36819d
+19 -13
View File
@@ -244,7 +244,7 @@ namespace Game.Spells
} }
GetBase().CallScriptEffectCalcSpellModHandlers(this, ref m_spellmod); GetBase().CallScriptEffectCalcSpellModHandlers(this, ref m_spellmod);
} }
public void ChangeAmount(int newAmount, bool mark = true, bool onStackOrReapply = false) public void ChangeAmount(int newAmount, bool mark = true, bool onStackOrReapply = false, AuraEffect triggeredBy = null)
{ {
// Reapply if amount change // Reapply if amount change
AuraEffectHandleModes handleMask = 0; AuraEffectHandleModes handleMask = 0;
@@ -261,7 +261,7 @@ namespace Game.Spells
foreach (var aurApp in effectApplications) foreach (var aurApp in effectApplications)
{ {
aurApp.GetTarget()._RegisterAuraEffect(this, false); aurApp.GetTarget()._RegisterAuraEffect(this, false);
HandleEffect(aurApp, handleMask, false); HandleEffect(aurApp, handleMask, false, triggeredBy);
} }
if (Convert.ToBoolean(handleMask & AuraEffectHandleModes.ChangeAmount)) if (Convert.ToBoolean(handleMask & AuraEffectHandleModes.ChangeAmount))
@@ -279,14 +279,14 @@ namespace Game.Spells
continue; continue;
aurApp.GetTarget()._RegisterAuraEffect(this, true); aurApp.GetTarget()._RegisterAuraEffect(this, true);
HandleEffect(aurApp, handleMask, true); HandleEffect(aurApp, handleMask, true, triggeredBy);
} }
if (GetSpellInfo().HasAttribute(SpellAttr8.AuraSendAmount) || Aura.EffectTypeNeedsSendingAmount(GetAuraType())) if (GetSpellInfo().HasAttribute(SpellAttr8.AuraSendAmount) || Aura.EffectTypeNeedsSendingAmount(GetAuraType()))
GetBase().SetNeedClientUpdateForTargets(); GetBase().SetNeedClientUpdateForTargets();
} }
public void HandleEffect(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply) public void HandleEffect(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply, AuraEffect triggeredBy = null)
{ {
// check if call is correct, we really don't want using bitmasks here (with 1 exception) // check if call is correct, we really don't want using bitmasks here (with 1 exception)
Cypher.Assert(mode == AuraEffectHandleModes.Real || mode == AuraEffectHandleModes.SendForClient Cypher.Assert(mode == AuraEffectHandleModes.Real || mode == AuraEffectHandleModes.SendForClient
@@ -301,7 +301,7 @@ namespace Game.Spells
// real aura apply/remove, handle modifier // real aura apply/remove, handle modifier
if (mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask)) if (mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask))
ApplySpellMod(aurApp.GetTarget(), apply); ApplySpellMod(aurApp.GetTarget(), apply, triggeredBy);
// call scripts helping/replacing effect handlers // call scripts helping/replacing effect handlers
bool prevented; bool prevented;
@@ -328,14 +328,14 @@ namespace Game.Spells
else else
GetBase().CallScriptAfterEffectRemoveHandlers(this, aurApp, mode); GetBase().CallScriptAfterEffectRemoveHandlers(this, aurApp, mode);
} }
public void HandleEffect(Unit target, AuraEffectHandleModes mode, bool apply) public void HandleEffect(Unit target, AuraEffectHandleModes mode, bool apply, AuraEffect triggeredBy = null)
{ {
AuraApplication aurApp = GetBase().GetApplicationOfTarget(target.GetGUID()); AuraApplication aurApp = GetBase().GetApplicationOfTarget(target.GetGUID());
Cypher.Assert(aurApp != null); Cypher.Assert(aurApp != null);
HandleEffect(aurApp, mode, apply); HandleEffect(aurApp, mode, apply, triggeredBy);
} }
void ApplySpellMod(Unit target, bool apply) void ApplySpellMod(Unit target, bool apply, AuraEffect triggeredBy = null)
{ {
if (m_spellmod == null || !target.IsTypeId(TypeId.Player)) if (m_spellmod == null || !target.IsTypeId(TypeId.Player))
return; return;
@@ -374,6 +374,9 @@ namespace Game.Spells
if (recalculateEffectMask.Any()) if (recalculateEffectMask.Any())
{ {
if (triggeredBy == null)
triggeredBy = this;
ObjectGuid guid = target.GetGUID(); ObjectGuid guid = target.GetGUID();
var auras = target.GetAppliedAuras(); var auras = target.GetAppliedAuras();
foreach (var iter in auras) foreach (var iter in auras)
@@ -389,7 +392,8 @@ namespace Game.Spells
{ {
AuraEffect aurEff = aura.GetEffect(i); AuraEffect aurEff = aura.GetEffect(i);
if (aurEff != null) if (aurEff != null)
aurEff.RecalculateAmount(); if (aurEff != triggeredBy)
aurEff.RecalculateAmount(triggeredBy);
} }
} }
} }
@@ -769,17 +773,19 @@ namespace Game.Spells
public int GetPeriodicTimer() { return _periodicTimer; } public int GetPeriodicTimer() { return _periodicTimer; }
public void SetPeriodicTimer(int periodicTimer) { _periodicTimer = periodicTimer; } public void SetPeriodicTimer(int periodicTimer) { _periodicTimer = periodicTimer; }
void RecalculateAmount() void RecalculateAmount(AuraEffect triggeredBy = null)
{ {
if (!CanBeRecalculated()) if (!CanBeRecalculated())
return; return;
ChangeAmount(CalculateAmount(GetCaster()), false);
ChangeAmount(CalculateAmount(GetCaster()), false, false, triggeredBy);
} }
public void RecalculateAmount(Unit caster) public void RecalculateAmount(Unit caster, AuraEffect triggeredBy = null)
{ {
if (!CanBeRecalculated()) if (!CanBeRecalculated())
return; return;
ChangeAmount(CalculateAmount(caster), false);
ChangeAmount(CalculateAmount(caster), false, false, triggeredBy);
} }
public bool CanBeRecalculated() { return m_canBeRecalculated; } public bool CanBeRecalculated() { return m_canBeRecalculated; }