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:
@@ -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; }
|
||||||
|
|||||||
Reference in New Issue
Block a user