Core/Spells Fixed scroll stacking check when not targeting self

Port From (https://github.com/TrinityCore/TrinityCore/commit/c9443f190abdf2467386c64c0b476e2d6ec545f6)
This commit is contained in:
hondacrx
2022-02-18 16:34:20 -05:00
parent ce5b592d8b
commit e7eba5907d
2 changed files with 57 additions and 72 deletions
+21 -15
View File
@@ -3991,18 +3991,26 @@ namespace Game.Entities
if (aurEff == null) if (aurEff == null)
continue; continue;
AuraType auraType = aurEff.GetSpellEffectInfo().ApplyAuraName; if (!IsHighestExclusiveAuraEffect(aura.GetSpellInfo(), aurEff.GetAuraType(), aurEff.GetAmount(), aura.GetEffectMask(), removeOtherAuraApplications))
var auras = GetAuraEffectsByType(auraType); return false;
for (var i = 0; i < auras.Count;) }
{
AuraEffect existingAurEff = auras[i];
++i;
if (Global.SpellMgr.CheckSpellGroupStackRules(aura.GetSpellInfo(), existingAurEff.GetSpellInfo()) == SpellGroupStackRule.ExclusiveHighest) return true;
}
public bool IsHighestExclusiveAuraEffect(SpellInfo spellInfo, AuraType auraType, int effectAmount, uint auraEffectMask, bool removeOtherAuraApplications = false)
{ {
int diff = Math.Abs(aurEff.GetAmount()) - Math.Abs(existingAurEff.GetAmount()); var auras = GetAuraEffectsByType(auraType);
foreach (AuraEffect existingAurEff in auras)
{
if (Global.SpellMgr.CheckSpellGroupStackRules(spellInfo, existingAurEff.GetSpellInfo()) == SpellGroupStackRule.ExclusiveHighest)
{
long diff = Math.Abs(effectAmount) - Math.Abs(existingAurEff.GetAmount());
if (diff == 0) if (diff == 0)
diff = (int)(aura.GetEffectMask() - existingAurEff.GetBase().GetEffectMask()); {
for (int i = 0; i < SpellConst.MaxEffects; ++i)
diff += (long)((auraEffectMask & (1 << i)) >> i) - (long)((existingAurEff.GetBase().GetEffectMask() & (1 << i)) >> i);
}
if (diff > 0) if (diff > 0)
{ {
@@ -4013,11 +4021,11 @@ namespace Game.Entities
AuraApplication aurApp = existingAurEff.GetBase().GetApplicationOfTarget(GetGUID()); AuraApplication aurApp = existingAurEff.GetBase().GetApplicationOfTarget(GetGUID());
if (aurApp != null) if (aurApp != null)
{ {
bool hasMoreThanOneEffect = auraBase.HasMoreThanOneEffectForType(auraType); //bool hasMoreThanOneEffect = auraBase.HasMoreThanOneEffectForType(auraType);
uint removedAuras = m_removedAurasCount; //uint removedAuras = m_removedAurasCount;
RemoveAura(aurApp); RemoveAura(aurApp);
if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1) //if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1)
i = 0; //continue;
} }
} }
} }
@@ -4026,8 +4034,6 @@ namespace Game.Entities
} }
} }
}
return true; return true;
} }
+16 -37
View File
@@ -2605,6 +2605,9 @@ namespace Game.Spells
CallScriptBeforeCastHandlers(); CallScriptBeforeCastHandlers();
// skip check if done already (for instant cast spells for example)
if (!skipCheck)
{
void cleanupSpell(SpellCastResult result, int? param1 = null, int? param2 = null) void cleanupSpell(SpellCastResult result, int? param1 = null, int? param2 = null)
{ {
SendCastResult(result, param1, param2); SendCastResult(result, param1, param2);
@@ -2617,9 +2620,6 @@ namespace Game.Spells
SetExecutedCurrently(false); SetExecutedCurrently(false);
} }
// skip check if done already (for instant cast spells for example)
if (!skipCheck)
{
int param1 = 0, param2 = 0; int param1 = 0, param2 = 0;
SpellCastResult castResult = CheckCast(false, ref param1, ref param2); SpellCastResult castResult = CheckCast(false, ref param1, ref param2);
if (castResult != SpellCastResult.SpellCastOk) if (castResult != SpellCastResult.SpellCastOk)
@@ -2679,40 +2679,6 @@ namespace Game.Spells
} }
} }
// check if target already has the same type, but more powerful aura
if (modOwner)
{
foreach (SpellEffectInfo spellEffectInfo in GetSpellInfo().GetEffects())
{
if (!spellEffectInfo.IsAura())
continue;
var auras = modOwner.GetAuraEffectsByType(AuraType.ModStat);
foreach (var auraIt in auras)
{
// check if both spells are in same SpellGroups
if (Global.SpellMgr.CheckSpellGroupStackRules(GetSpellInfo(), auraIt.GetSpellInfo()) == SpellGroupStackRule.ExclusiveHighest)
{
// compare new aura vs existing aura
if (Math.Abs(spellEffectInfo.CalcBaseValue(m_caster, null, m_castItemEntry, m_castItemLevel)) < Math.Abs(auraIt.GetSpellEffectInfo().CalcBaseValue(m_caster, null, m_castItemEntry, m_castItemLevel)))
{
cleanupSpell(SpellCastResult.AuraBounced);
return;
}
else if (Math.Abs(spellEffectInfo.BasePoints) == Math.Abs(auraIt.GetSpellEffectInfo().BasePoints))
{
// in case when baseboints match and to avoid false positive, example, spell 8097 vs 8116
if (Math.Abs(spellEffectInfo.MiscValue) == Math.Abs(auraIt.GetSpellEffectInfo().MiscValue))
{
cleanupSpell(SpellCastResult.AuraBounced);
return;
}
}
}
}
}
}
// if the spell allows the creature to turn while casting, then adjust server-side orientation to face the target now // if the spell allows the creature to turn while casting, then adjust server-side orientation to face the target now
// client-side orientation is handled by the client itself, as the cast target is targeted due to Creature::FocusTarget // client-side orientation is handled by the client itself, as the cast target is targeted due to Creature::FocusTarget
if (m_caster.IsTypeId(TypeId.Unit) && !m_caster.ToUnit().HasUnitFlag(UnitFlags.Possessed)) if (m_caster.IsTypeId(TypeId.Unit) && !m_caster.ToUnit().HasUnitFlag(UnitFlags.Possessed))
@@ -4845,6 +4811,7 @@ namespace Game.Spells
if (castResult != SpellCastResult.SpellCastOk) if (castResult != SpellCastResult.SpellCastOk)
return castResult; return castResult;
uint approximateAuraEffectMask = 0;
foreach (var spellEffectInfo in m_spellInfo.GetEffects()) foreach (var spellEffectInfo in m_spellInfo.GetEffects())
{ {
// for effects of spells that have only one target // for effects of spells that have only one target
@@ -5423,6 +5390,9 @@ namespace Game.Spells
default: default:
break; break;
} }
if (spellEffectInfo.IsAura())
approximateAuraEffectMask |= 1u << (int)spellEffectInfo.EffectIndex;
} }
foreach (var spellEffectInfo in m_spellInfo.GetEffects()) foreach (var spellEffectInfo in m_spellInfo.GetEffects())
@@ -5545,6 +5515,15 @@ namespace Game.Spells
default: default:
break; break;
} }
// check if target already has the same type, but more powerful aura
if (!m_spellInfo.IsTargetingArea())
{
Unit target = m_targets.GetUnitTarget();
if (target != null)
if (!target.IsHighestExclusiveAuraEffect(m_spellInfo, spellEffectInfo.ApplyAuraName, spellEffectInfo.CalcBaseValue(m_caster, null, m_castItemEntry, m_castItemLevel), approximateAuraEffectMask, false))
return SpellCastResult.AuraBounced;
}
} }
// check trade slot case (last, for allow catch any another cast problems) // check trade slot case (last, for allow catch any another cast problems)