Core/Spells Fixed scroll stacking check when not targeting self
Port From (https://github.com/TrinityCore/TrinityCore/commit/c9443f190abdf2467386c64c0b476e2d6ec545f6)
This commit is contained in:
@@ -3991,41 +3991,47 @@ 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;)
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsHighestExclusiveAuraEffect(SpellInfo spellInfo, AuraType auraType, int effectAmount, uint auraEffectMask, bool removeOtherAuraApplications = false)
|
||||||
|
{
|
||||||
|
var auras = GetAuraEffectsByType(auraType);
|
||||||
|
foreach (AuraEffect existingAurEff in auras)
|
||||||
|
{
|
||||||
|
if (Global.SpellMgr.CheckSpellGroupStackRules(spellInfo, existingAurEff.GetSpellInfo()) == SpellGroupStackRule.ExclusiveHighest)
|
||||||
{
|
{
|
||||||
AuraEffect existingAurEff = auras[i];
|
long diff = Math.Abs(effectAmount) - Math.Abs(existingAurEff.GetAmount());
|
||||||
++i;
|
if (diff == 0)
|
||||||
|
|
||||||
if (Global.SpellMgr.CheckSpellGroupStackRules(aura.GetSpellInfo(), existingAurEff.GetSpellInfo()) == SpellGroupStackRule.ExclusiveHighest)
|
|
||||||
{
|
{
|
||||||
int diff = Math.Abs(aurEff.GetAmount()) - Math.Abs(existingAurEff.GetAmount());
|
for (int i = 0; i < SpellConst.MaxEffects; ++i)
|
||||||
if (diff == 0)
|
diff += (long)((auraEffectMask & (1 << i)) >> i) - (long)((existingAurEff.GetBase().GetEffectMask() & (1 << i)) >> i);
|
||||||
diff = (int)(aura.GetEffectMask() - existingAurEff.GetBase().GetEffectMask());
|
}
|
||||||
|
|
||||||
if (diff > 0)
|
if (diff > 0)
|
||||||
|
{
|
||||||
|
Aura auraBase = existingAurEff.GetBase();
|
||||||
|
// no removing of area auras from the original owner, as that completely cancels them
|
||||||
|
if (removeOtherAuraApplications && (!auraBase.IsArea() || auraBase.GetOwner() != this))
|
||||||
{
|
{
|
||||||
Aura auraBase = existingAurEff.GetBase();
|
AuraApplication aurApp = existingAurEff.GetBase().GetApplicationOfTarget(GetGUID());
|
||||||
// no removing of area auras from the original owner, as that completely cancels them
|
if (aurApp != null)
|
||||||
if (removeOtherAuraApplications && (!auraBase.IsArea() || auraBase.GetOwner() != this))
|
|
||||||
{
|
{
|
||||||
AuraApplication aurApp = existingAurEff.GetBase().GetApplicationOfTarget(GetGUID());
|
//bool hasMoreThanOneEffect = auraBase.HasMoreThanOneEffectForType(auraType);
|
||||||
if (aurApp != null)
|
//uint removedAuras = m_removedAurasCount;
|
||||||
{
|
RemoveAura(aurApp);
|
||||||
bool hasMoreThanOneEffect = auraBase.HasMoreThanOneEffectForType(auraType);
|
//if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1)
|
||||||
uint removedAuras = m_removedAurasCount;
|
//continue;
|
||||||
RemoveAura(aurApp);
|
|
||||||
if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1)
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (diff < 0)
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
else if (diff < 0)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+25
-46
@@ -2605,21 +2605,21 @@ namespace Game.Spells
|
|||||||
|
|
||||||
CallScriptBeforeCastHandlers();
|
CallScriptBeforeCastHandlers();
|
||||||
|
|
||||||
void cleanupSpell(SpellCastResult result, int? param1 = null, int? param2 = null)
|
|
||||||
{
|
|
||||||
SendCastResult(result, param1, param2);
|
|
||||||
SendInterrupted(0);
|
|
||||||
|
|
||||||
if (modOwner)
|
|
||||||
modOwner.SetSpellModTakingSpell(this, false);
|
|
||||||
|
|
||||||
Finish(false);
|
|
||||||
SetExecutedCurrently(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip check if done already (for instant cast spells for example)
|
// skip check if done already (for instant cast spells for example)
|
||||||
if (!skipCheck)
|
if (!skipCheck)
|
||||||
{
|
{
|
||||||
|
void cleanupSpell(SpellCastResult result, int? param1 = null, int? param2 = null)
|
||||||
|
{
|
||||||
|
SendCastResult(result, param1, param2);
|
||||||
|
SendInterrupted(0);
|
||||||
|
|
||||||
|
if (modOwner)
|
||||||
|
modOwner.SetSpellModTakingSpell(this, false);
|
||||||
|
|
||||||
|
Finish(false);
|
||||||
|
SetExecutedCurrently(false);
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user