Core/Auras: Improve aura interactions with immunities on spell effect level
Port From (https://github.com/TrinityCore/TrinityCore/commit/66b03acc47665cd79646096e13aa8c6b513675aa)
This commit is contained in:
@@ -2075,12 +2075,12 @@ namespace Game.Entities
|
||||
ApplySpellImmune(placeholderSpellId, SpellImmunity.School, 1u << i, true);
|
||||
}
|
||||
|
||||
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster)
|
||||
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster, bool requireImmunityPurgesEffectAttribute = false)
|
||||
{
|
||||
if (GetCreatureTemplate().CreatureType == CreatureType.Mechanical && spellEffectInfo.IsEffect(SpellEffectName.Heal))
|
||||
return true;
|
||||
|
||||
return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster);
|
||||
return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster, requireImmunityPurgesEffectAttribute);
|
||||
}
|
||||
|
||||
public bool IsElite()
|
||||
|
||||
@@ -3116,7 +3116,7 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster)
|
||||
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster, bool requireImmunityPurgesEffectAttribute = false)
|
||||
{
|
||||
// players are immune to taunt (the aura and the spell effect).
|
||||
if (spellEffectInfo.IsAura(AuraType.ModTaunt))
|
||||
@@ -3125,7 +3125,7 @@ namespace Game.Entities
|
||||
if (spellEffectInfo.IsEffect(SpellEffectName.AttackMe))
|
||||
return true;
|
||||
|
||||
return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster);
|
||||
return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster, requireImmunityPurgesEffectAttribute);
|
||||
}
|
||||
|
||||
void RegenerateAll()
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Game.Entities
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster)
|
||||
public override bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster, bool requireImmunityPurgesEffectAttribute = false)
|
||||
{
|
||||
// immune to all positive spells, except of stoneclaw totem absorb and sentry totem bind sight
|
||||
// totems positive spells have unit_caster target
|
||||
@@ -165,7 +165,7 @@ namespace Game.Entities
|
||||
break;
|
||||
}
|
||||
|
||||
return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster);
|
||||
return base.IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster, requireImmunityPurgesEffectAttribute);
|
||||
}
|
||||
|
||||
public uint GetSpell(byte slot = 0) { return m_spells[slot]; }
|
||||
|
||||
@@ -1216,14 +1216,31 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool IsImmunedToSpell(SpellInfo spellInfo, WorldObject caster)
|
||||
|
||||
public bool IsImmunedToSpell(SpellInfo spellInfo, WorldObject caster, bool requireImmunityPurgesEffectAttribute = false)
|
||||
{
|
||||
if (spellInfo == null)
|
||||
return false;
|
||||
|
||||
bool hasImmunity(MultiMap<uint, uint> container, uint key)
|
||||
{
|
||||
var range = container.LookupByKey(key);
|
||||
if (!requireImmunityPurgesEffectAttribute)
|
||||
return !range.Empty();
|
||||
|
||||
return range.Any(entry =>
|
||||
{
|
||||
SpellInfo immunitySourceSpell = Global.SpellMgr.GetSpellInfo(entry, Difficulty.None);
|
||||
if (immunitySourceSpell != null && immunitySourceSpell.HasAttribute(SpellAttr1.ImmunityPurgesEffect))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// Single spell immunity.
|
||||
var idList = m_spellImmune[(int)SpellImmunity.Id];
|
||||
if (idList.ContainsKey(spellInfo.Id))
|
||||
if (hasImmunity(idList, spellInfo.Id))
|
||||
return true;
|
||||
|
||||
if (spellInfo.HasAttribute(SpellAttr0.NoImmunities))
|
||||
@@ -1233,7 +1250,7 @@ namespace Game.Entities
|
||||
if (dispel != 0)
|
||||
{
|
||||
var dispelList = m_spellImmune[(int)SpellImmunity.Dispel];
|
||||
if (dispelList.ContainsKey(dispel))
|
||||
if (hasImmunity(dispelList, dispel))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1242,7 +1259,7 @@ namespace Game.Entities
|
||||
if (mechanic != 0)
|
||||
{
|
||||
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
|
||||
if (mechanicList.ContainsKey(mechanic))
|
||||
if (hasImmunity(mechanicList, mechanic))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1254,7 +1271,7 @@ namespace Game.Entities
|
||||
if (!spellEffectInfo.IsEffect())
|
||||
continue;
|
||||
|
||||
if (!IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster))
|
||||
if (!IsImmunedToSpellEffect(spellInfo, spellEffectInfo, caster, requireImmunityPurgesEffectAttribute))
|
||||
{
|
||||
immuneToAllEffects = false;
|
||||
break;
|
||||
@@ -1280,7 +1297,8 @@ namespace Game.Entities
|
||||
SpellInfo immuneSpellInfo = Global.SpellMgr.GetSpellInfo(pair.Value, GetMap().GetDifficultyID());
|
||||
// Consider the school immune if any of these conditions are not satisfied.
|
||||
// In case of no immuneSpellInfo, ignore that condition and check only the other conditions
|
||||
if ((immuneSpellInfo != null && !immuneSpellInfo.IsPositive()) || !spellInfo.IsPositive() || caster == null || !IsFriendlyTo(caster))
|
||||
if ((immuneSpellInfo != null && !immuneSpellInfo.IsPositive() && (!requireImmunityPurgesEffectAttribute || immuneSpellInfo.HasAttribute(SpellAttr1.ImmunityPurgesEffect)))
|
||||
|| !spellInfo.IsPositive() || caster == null || !IsFriendlyTo(caster))
|
||||
if (!spellInfo.CanPierceImmuneAura(immuneSpellInfo))
|
||||
schoolImmunityMask |= pair.Key;
|
||||
}
|
||||
@@ -1300,6 +1318,7 @@ namespace Game.Entities
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
public uint GetDamageImmunityMask()
|
||||
{
|
||||
uint mask = 0;
|
||||
@@ -1309,6 +1328,7 @@ namespace Game.Entities
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
public uint GetMechanicImmunityMask()
|
||||
{
|
||||
uint mask = 0;
|
||||
@@ -1318,24 +1338,42 @@ namespace Game.Entities
|
||||
|
||||
return mask;
|
||||
}
|
||||
public virtual bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster)
|
||||
|
||||
public virtual bool IsImmunedToSpellEffect(SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, WorldObject caster, bool requireImmunityPurgesEffectAttribute = false)
|
||||
{
|
||||
if (spellInfo == null)
|
||||
return false;
|
||||
|
||||
if (spellEffectInfo == null || !spellEffectInfo.IsEffect())
|
||||
if (spellInfo.HasAttribute(SpellAttr0.NoImmunities))
|
||||
return false;
|
||||
|
||||
bool hasImmunity(MultiMap<uint, uint> container, uint key)
|
||||
{
|
||||
var range = container.LookupByKey(key);
|
||||
if (!requireImmunityPurgesEffectAttribute)
|
||||
return !range.Empty();
|
||||
|
||||
return range.Any(entry =>
|
||||
{
|
||||
var immunitySourceSpell = Global.SpellMgr.GetSpellInfo(entry, Difficulty.None);
|
||||
if (immunitySourceSpell != null)
|
||||
if (immunitySourceSpell.HasAttribute(SpellAttr1.ImmunityPurgesEffect))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// If m_immuneToEffect type contain this effect type, IMMUNE effect.
|
||||
var effectList = m_spellImmune[(int)SpellImmunity.Effect];
|
||||
if (effectList.ContainsKey((uint)spellEffectInfo.Effect))
|
||||
if (hasImmunity(effectList, (uint)spellEffectInfo.Effect))
|
||||
return true;
|
||||
|
||||
uint mechanic = (uint)spellEffectInfo.Mechanic;
|
||||
if (mechanic != 0)
|
||||
{
|
||||
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
|
||||
if (mechanicList.ContainsKey(mechanic))
|
||||
if (hasImmunity(mechanicList, mechanic))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1345,7 +1383,7 @@ namespace Game.Entities
|
||||
if (!spellInfo.HasAttribute(SpellAttr3.AlwaysHit))
|
||||
{
|
||||
var list = m_spellImmune[(int)SpellImmunity.State];
|
||||
if (list.ContainsKey(aura))
|
||||
if (hasImmunity(list, (uint)aura))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1362,6 +1400,7 @@ namespace Game.Entities
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsImmunedToDamage(SpellSchoolMask schoolMask)
|
||||
{
|
||||
if (schoolMask == SpellSchoolMask.None)
|
||||
@@ -1379,6 +1418,7 @@ namespace Game.Entities
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsImmunedToDamage(SpellInfo spellInfo)
|
||||
{
|
||||
if (spellInfo == null)
|
||||
@@ -2216,29 +2256,15 @@ namespace Game.Entities
|
||||
RemoveOwnedAura(pair, AuraRemoveMode.Death);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveMovementImpairingAuras(bool withRoot)
|
||||
{
|
||||
if (withRoot)
|
||||
RemoveAurasWithMechanic(1 << (int)Mechanics.Root);
|
||||
RemoveAurasWithMechanic(1 << (int)Mechanics.Root, AuraRemoveMode.Default, 0, true);
|
||||
|
||||
// Snares
|
||||
foreach (var pair in GetAppliedAuras())
|
||||
{
|
||||
Aura aura = pair.Value.GetBase();
|
||||
if (aura.GetSpellInfo().Mechanic == Mechanics.Snare)
|
||||
{
|
||||
RemoveAura(pair);
|
||||
continue;
|
||||
}
|
||||
|
||||
// turn off snare auras by setting amount to 0
|
||||
foreach (var spellEffectInfo in aura.GetSpellInfo().GetEffects())
|
||||
{
|
||||
if (pair.Value.HasEffect(spellEffectInfo.EffectIndex) && spellEffectInfo.Mechanic == Mechanics.Snare)
|
||||
aura.GetEffect(spellEffectInfo.EffectIndex).ChangeAmount(0);
|
||||
}
|
||||
}
|
||||
RemoveAurasWithMechanic(1 << (int)Mechanics.Snare, AuraRemoveMode.Default, 0, false);
|
||||
}
|
||||
|
||||
public void RemoveAllAurasRequiringDeadTarget()
|
||||
{
|
||||
foreach (var app in GetAppliedAuras())
|
||||
@@ -2930,22 +2956,26 @@ namespace Game.Entities
|
||||
UpdateInterruptMask();
|
||||
}
|
||||
|
||||
public void RemoveAurasWithMechanic(uint mechanic_mask, AuraRemoveMode removemode = AuraRemoveMode.Default, uint except = 0)
|
||||
public void RemoveAurasWithMechanic(uint mechanicMaskToRemove, AuraRemoveMode removeMode = AuraRemoveMode.Default, uint exceptSpellId = 0, bool withEffectMechanics = false)
|
||||
{
|
||||
foreach (var app in GetAppliedAuras())
|
||||
RemoveAppliedAuras(aurApp =>
|
||||
{
|
||||
if (app.Value == null)
|
||||
continue;
|
||||
Aura aura = app.Value.GetBase();
|
||||
if (except == 0 || aura.GetId() != except)
|
||||
{
|
||||
if (Convert.ToBoolean(aura.GetSpellInfo().GetAllEffectsMechanicMask() & mechanic_mask))
|
||||
{
|
||||
RemoveAura(app, removemode);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Aura aura = aurApp.GetBase();
|
||||
if (exceptSpellId != 0 && aura.GetId() == exceptSpellId)
|
||||
return false;
|
||||
|
||||
uint appliedMechanicMask = aura.GetSpellInfo().GetSpellMechanicMaskByEffectMask(aurApp.GetEffectMask());
|
||||
if ((appliedMechanicMask & mechanicMaskToRemove) == 0)
|
||||
return false;
|
||||
|
||||
// spell mechanic matches required mask for removal
|
||||
if (((1 << (int)aura.GetSpellInfo().Mechanic) & mechanicMaskToRemove) != 0 || withEffectMechanics)
|
||||
return true;
|
||||
|
||||
// effect mechanic matches required mask for removal - don't remove, only update targets
|
||||
aura.UpdateTargetMap(aura.GetCaster());
|
||||
return false;
|
||||
}, removeMode);
|
||||
}
|
||||
public void RemoveAurasDueToSpellBySteal(uint spellId, ObjectGuid casterGUID, WorldObject stealer, int stolenCharges = 1)
|
||||
{
|
||||
@@ -3293,45 +3323,45 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAppliedAuras(Func<AuraApplication, bool> check)
|
||||
public void RemoveAppliedAuras(Func<AuraApplication, bool> check, AuraRemoveMode removeMode = AuraRemoveMode.Default)
|
||||
{
|
||||
foreach (var pair in GetAppliedAuras())
|
||||
{
|
||||
if (check(pair.Value))
|
||||
RemoveAura(pair);
|
||||
RemoveAura(pair, removeMode);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveOwnedAuras(Func<Aura, bool> check)
|
||||
public void RemoveOwnedAuras(Func<Aura, bool> check, AuraRemoveMode removeMode = AuraRemoveMode.Default)
|
||||
{
|
||||
foreach (var pair in GetOwnedAuras())
|
||||
{
|
||||
if (check(pair.Value))
|
||||
RemoveOwnedAura(pair);
|
||||
RemoveOwnedAura(pair, removeMode);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveAppliedAuras(uint spellId, Func<AuraApplication, bool> check)
|
||||
void RemoveAppliedAuras(uint spellId, Func<AuraApplication, bool> check, AuraRemoveMode removeMode = AuraRemoveMode.Default)
|
||||
{
|
||||
var list = m_appliedAuras.LookupByKey(spellId);
|
||||
foreach (var app in list)
|
||||
{
|
||||
if (check(app))
|
||||
RemoveAura(app);
|
||||
RemoveAura(app, removeMode);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveOwnedAuras(uint spellId, Func<Aura, bool> check)
|
||||
void RemoveOwnedAuras(uint spellId, Func<Aura, bool> check, AuraRemoveMode removeMode = AuraRemoveMode.Default)
|
||||
{
|
||||
var list = m_ownedAuras.LookupByKey(spellId);
|
||||
foreach (var aura in list)
|
||||
{
|
||||
if (check(aura))
|
||||
RemoveOwnedAura(aura);
|
||||
RemoveOwnedAura(aura, removeMode);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAurasByType(AuraType auraType, Func<AuraApplication, bool> check)
|
||||
public void RemoveAurasByType(AuraType auraType, Func<AuraApplication, bool> check, AuraRemoveMode removeMode = AuraRemoveMode.Default)
|
||||
{
|
||||
var list = m_modAuras[auraType];
|
||||
for (var i = 0; i < list.Count; ++i)
|
||||
@@ -3343,7 +3373,7 @@ namespace Game.Entities
|
||||
if (check(aurApp))
|
||||
{
|
||||
uint removedAuras = m_removedAurasCount;
|
||||
RemoveAura(aurApp);
|
||||
RemoveAura(aurApp, removeMode);
|
||||
if (m_removedAurasCount > removedAuras + 1)
|
||||
i = 0;
|
||||
}
|
||||
@@ -3387,6 +3417,7 @@ namespace Game.Entities
|
||||
RemoveAura(pair);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAllAuras()
|
||||
{
|
||||
// this may be a dead loop if some events on aura remove will continiously apply aura on remove
|
||||
|
||||
@@ -189,7 +189,7 @@ namespace Game.Spells
|
||||
SetNeedClientUpdate();
|
||||
}
|
||||
|
||||
public void UpdateApplyEffectMask(uint newEffMask)
|
||||
public void UpdateApplyEffectMask(uint newEffMask, bool canHandleNewEffects)
|
||||
{
|
||||
if (_effectsToApply == newEffMask)
|
||||
return;
|
||||
@@ -204,20 +204,23 @@ namespace Game.Spells
|
||||
return;
|
||||
}
|
||||
|
||||
// update real effects only if they were applied already
|
||||
for (uint i = 0; i < SpellConst.MaxEffects; ++i)
|
||||
{
|
||||
// update real effects only if they were applied already
|
||||
if ((_effectMask & (1 << (int)i)) == 0)
|
||||
continue;
|
||||
|
||||
if ((removeEffMask & (1 << (int)i)) != 0)
|
||||
if (HasEffect(i) && (removeEffMask & (1 << (int)i)) != 0)
|
||||
_HandleEffect(i, false);
|
||||
|
||||
if ((addEffMask & (1 << (int)i)) != 0)
|
||||
_HandleEffect(i, true);
|
||||
}
|
||||
|
||||
_effectsToApply = newEffMask;
|
||||
|
||||
if (canHandleNewEffects)
|
||||
{
|
||||
for (uint i = 0; i < SpellConst.MaxEffects; ++i)
|
||||
{
|
||||
if ((addEffMask & (1 << (int)i)) != 0)
|
||||
_HandleEffect(i, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetNeedClientUpdate()
|
||||
@@ -499,7 +502,7 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateTargetMap(Unit caster, bool apply = true)
|
||||
public void UpdateTargetMap(Unit caster, bool apply = true)
|
||||
{
|
||||
if (IsRemoved())
|
||||
return;
|
||||
@@ -524,12 +527,19 @@ namespace Game.Spells
|
||||
{
|
||||
// needs readding - remove now, will be applied in next update cycle
|
||||
// (dbcs do not have auras which apply on same type of targets but have different radius, so this is not really needed)
|
||||
if (!CanBeAppliedOn(app.Value.GetTarget()))
|
||||
if (app.Value.GetTarget().IsImmunedToSpell(GetSpellInfo(), caster, true) || !CanBeAppliedOn(app.Value.GetTarget()))
|
||||
{
|
||||
targetsToRemove.Add(app.Value.GetTarget());
|
||||
continue;
|
||||
}
|
||||
|
||||
// check target immunities (for existing targets)
|
||||
foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
|
||||
if (app.Value.GetTarget().IsImmunedToSpellEffect(GetSpellInfo(), spellEffectInfo, caster, true))
|
||||
existing &= ~(uint)(1 << (int)spellEffectInfo.EffectIndex);
|
||||
|
||||
targets[app.Value.GetTarget()] = existing;
|
||||
|
||||
// needs to add/remove effects from application, don't remove from map so it gets updated
|
||||
if (app.Value.GetEffectMask() != existing)
|
||||
continue;
|
||||
@@ -542,18 +552,19 @@ namespace Game.Spells
|
||||
// register auras for units
|
||||
foreach (var unit in targets.Keys.ToList())
|
||||
{
|
||||
var value = targets[unit];
|
||||
|
||||
bool addUnit = true;
|
||||
// check target immunities
|
||||
foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
|
||||
AuraApplication aurApp = GetApplicationOfTarget(unit.GetGUID());
|
||||
if (aurApp == null)
|
||||
{
|
||||
if (unit.IsImmunedToSpellEffect(GetSpellInfo(), spellEffectInfo, caster))
|
||||
value &= ~(1u << (int)spellEffectInfo.EffectIndex);
|
||||
// check target immunities (for new targets)
|
||||
foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
|
||||
if (unit.IsImmunedToSpellEffect(GetSpellInfo(), spellEffectInfo, caster))
|
||||
targets[unit] &= ~(uint)(1 << (int)spellEffectInfo.EffectIndex);
|
||||
|
||||
if (targets[unit] == 0 || unit.IsImmunedToSpell(GetSpellInfo(), caster) || !CanBeAppliedOn(unit))
|
||||
addUnit = false;
|
||||
}
|
||||
|
||||
if (value == 0 || unit.IsImmunedToSpell(GetSpellInfo(), caster) || !CanBeAppliedOn(unit))
|
||||
addUnit = false;
|
||||
|
||||
if (addUnit && !unit.IsHighestExclusiveAura(this, true))
|
||||
addUnit = false;
|
||||
@@ -596,14 +607,13 @@ namespace Game.Spells
|
||||
unit.GetName(), unit.IsInWorld ? (int)unit.GetMap().GetId() : -1);
|
||||
}
|
||||
|
||||
AuraApplication aurApp = GetApplicationOfTarget(unit.GetGUID());
|
||||
if (aurApp != null)
|
||||
{
|
||||
// aura is already applied, this means we need to update effects of current application
|
||||
unit._UnapplyAura(aurApp, AuraRemoveMode.Default);
|
||||
aurApp.UpdateApplyEffectMask(targets[unit], true); // aura is already applied, this means we need to update effects of current application
|
||||
targets.Remove(unit);
|
||||
}
|
||||
|
||||
unit._CreateAuraApplication(this, value);
|
||||
else
|
||||
unit._CreateAuraApplication(this, targets[unit]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2550,7 +2560,7 @@ namespace Game.Spells
|
||||
{
|
||||
AuraApplication aurApp = foundAura.GetApplicationOfTarget(unit.GetGUID());
|
||||
if (aurApp != null)
|
||||
aurApp.UpdateApplyEffectMask(effMask);
|
||||
aurApp.UpdateApplyEffectMask(effMask, false);
|
||||
}
|
||||
|
||||
return foundAura;
|
||||
|
||||
@@ -658,7 +658,7 @@ namespace Game.Spells
|
||||
if (aurApp == null)
|
||||
aurApp = unitTarget._CreateAuraApplication(spellAura, 1u << (int)effectInfo.EffectIndex);
|
||||
else
|
||||
aurApp.UpdateApplyEffectMask(aurApp.GetEffectsToApply() | 1u << (int)effectInfo.EffectIndex);
|
||||
aurApp.UpdateApplyEffectMask(aurApp.GetEffectsToApply() | 1u << (int)effectInfo.EffectIndex, false);
|
||||
}
|
||||
|
||||
[SpellEffectHandler(SpellEffectName.UnlearnSpecialization)]
|
||||
|
||||
@@ -2439,13 +2439,23 @@ namespace Game.Spells
|
||||
if (Convert.ToBoolean(mechanicImmunity & (1 << (int)i)))
|
||||
target.ApplySpellImmune(Id, SpellImmunity.Mechanic, i, apply);
|
||||
|
||||
if (apply && HasAttribute(SpellAttr1.ImmunityPurgesEffect))
|
||||
if (HasAttribute(SpellAttr1.ImmunityPurgesEffect))
|
||||
{
|
||||
// exception for purely snare mechanic (eg. hands of freedom)!
|
||||
if (mechanicImmunity == (1 << (int)Mechanics.Snare))
|
||||
target.RemoveMovementImpairingAuras(false);
|
||||
else
|
||||
if (apply)
|
||||
target.RemoveAurasWithMechanic(mechanicImmunity, AuraRemoveMode.Default, Id);
|
||||
else
|
||||
{
|
||||
target.RemoveAppliedAuras(aurApp =>
|
||||
{
|
||||
Aura aura = aurApp.GetBase();
|
||||
if ((aura.GetSpellInfo().GetAllEffectsMechanicMask() & mechanicImmunity) != 0)
|
||||
aura.UpdateTargetMap(aura.GetCaster());
|
||||
|
||||
// only update targets, don't remove anything
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user