Core/Spell: revamp of immunities system
This commit is contained in:
@@ -302,6 +302,7 @@ namespace Framework.Constants
|
|||||||
Sapped = 30,
|
Sapped = 30,
|
||||||
Enraged = 31,
|
Enraged = 31,
|
||||||
Wounded = 32,
|
Wounded = 32,
|
||||||
|
Max = 33,
|
||||||
|
|
||||||
ImmuneToMovementImpairmentAndLossControlMask = ((1 << Charm) | (1 << Disoriented) |
|
ImmuneToMovementImpairmentAndLossControlMask = ((1 << Charm) | (1 << Disoriented) |
|
||||||
(1 << Fear) | (1 << Root) | (1 << Sleep) | (1 << Snare) | (1 << Stun) |
|
(1 << Fear) | (1 << Root) | (1 << Sleep) | (1 << Snare) | (1 << Stun) |
|
||||||
@@ -1370,9 +1371,9 @@ namespace Framework.Constants
|
|||||||
IsArcaneConcentration = 0x800000, // 23 Only Mage Arcane Concentration Have This Flag
|
IsArcaneConcentration = 0x800000, // 23 Only Mage Arcane Concentration Have This Flag
|
||||||
Unk24 = 0x1000000, // 24
|
Unk24 = 0x1000000, // 24
|
||||||
Unk25 = 0x2000000, // 25
|
Unk25 = 0x2000000, // 25
|
||||||
Unk26 = 0x4000000, // 26 Unaffected By School Immunity
|
UnaffectedByAuraSchoolImmune = 0x4000000, // 26 Unaffected By School Immunity
|
||||||
Unk27 = 0x8000000, // 27
|
Unk27 = 0x8000000, // 27
|
||||||
Unk28 = 0x10000000, // 28
|
IgnoreItemCheck = 0x10000000, // 28 Spell is cast without checking item requirements (charges/reagents/totem)
|
||||||
CantCrit = 0x20000000, // 29 Spell Can'T Crit
|
CantCrit = 0x20000000, // 29 Spell Can'T Crit
|
||||||
TriggeredCanTriggerProc = 0x40000000, // 30 Spell Can Trigger Even If Triggered
|
TriggeredCanTriggerProc = 0x40000000, // 30 Spell Can Trigger Even If Triggered
|
||||||
FoodBuff = 0x80000000 // 31 Food Or Drink Buff (Like Well Fed)
|
FoodBuff = 0x80000000 // 31 Food Or Drink Buff (Like Well Fed)
|
||||||
@@ -1539,7 +1540,7 @@ namespace Framework.Constants
|
|||||||
Unk17 = 0x20000, // 17 Only 27965 (Suicide) Spell.
|
Unk17 = 0x20000, // 17 Only 27965 (Suicide) Spell.
|
||||||
HasChargeEffect = 0x40000, // 18 Only Spells That Have Charge Among Effects.
|
HasChargeEffect = 0x40000, // 18 Only Spells That Have Charge Among Effects.
|
||||||
ZoneTeleport = 0x80000, // 19 Teleports To Specific Zones.
|
ZoneTeleport = 0x80000, // 19 Teleports To Specific Zones.
|
||||||
Unk20 = 0x100000, // 20 Blink, Divine Shield, Ice Block
|
UsableInStunFearConfusion = 0x100000, // 20 Blink, Divine Shield, Ice Block
|
||||||
Unk21 = 0x200000, // 21 Not Set
|
Unk21 = 0x200000, // 21 Not Set
|
||||||
Unk22 = 0x400000, // 22
|
Unk22 = 0x400000, // 22
|
||||||
Unk23 = 0x800000, // 23 Motivate, Mutilate, Shattering Throw
|
Unk23 = 0x800000, // 23 Motivate, Mutilate, Shattering Throw
|
||||||
|
|||||||
@@ -858,6 +858,12 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
public uint DealDamage(Unit victim, uint damage, CleanDamage cleanDamage = null, DamageEffectType damagetype = DamageEffectType.Direct, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal, SpellInfo spellProto = null, bool durabilityLoss = true)
|
public uint DealDamage(Unit victim, uint damage, CleanDamage cleanDamage = null, DamageEffectType damagetype = DamageEffectType.Direct, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal, SpellInfo spellProto = null, bool durabilityLoss = true)
|
||||||
{
|
{
|
||||||
|
if (victim.IsImmunedToDamage(spellProto))
|
||||||
|
{
|
||||||
|
SendSpellDamageImmune(victim, spellProto.Id, false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (victim.IsAIEnabled)
|
if (victim.IsAIEnabled)
|
||||||
victim.GetAI().DamageTaken(this, ref damage);
|
victim.GetAI().DamageTaken(this, ref damage);
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ namespace Game.Entities
|
|||||||
//Spells
|
//Spells
|
||||||
protected Dictionary<CurrentSpellTypes, Spell> m_currentSpells = new Dictionary<CurrentSpellTypes, Spell>((int)CurrentSpellTypes.Max);
|
protected Dictionary<CurrentSpellTypes, Spell> m_currentSpells = new Dictionary<CurrentSpellTypes, Spell>((int)CurrentSpellTypes.Max);
|
||||||
Dictionary<SpellValueMod, int> CustomSpellValueMod = new Dictionary<SpellValueMod, int>();
|
Dictionary<SpellValueMod, int> CustomSpellValueMod = new Dictionary<SpellValueMod, int>();
|
||||||
MultiMap<SpellImmunity, SpellImmune> m_spellImmune = new MultiMap<SpellImmunity, SpellImmune>();
|
MultiMap<uint, uint>[] m_spellImmune = new MultiMap<uint, uint>[(int)SpellImmunity.Max];
|
||||||
uint[] m_interruptMask = new uint[2];
|
uint[] m_interruptMask = new uint[2];
|
||||||
protected int m_procDeep;
|
protected int m_procDeep;
|
||||||
bool m_AutoRepeatFirstCast;
|
bool m_AutoRepeatFirstCast;
|
||||||
@@ -132,12 +132,6 @@ namespace Game.Entities
|
|||||||
ushort _meleeAnimKitId;
|
ushort _meleeAnimKitId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct SpellImmune
|
|
||||||
{
|
|
||||||
public uint spellType;
|
|
||||||
public uint spellId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DiminishingReturn
|
public class DiminishingReturn
|
||||||
{
|
{
|
||||||
public DiminishingReturn() { }
|
public DiminishingReturn() { }
|
||||||
|
|||||||
@@ -1403,7 +1403,7 @@ namespace Game.Entities
|
|||||||
return GetPositionZ() - offset;
|
return GetPositionZ() - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit GetUnitBeingMoved()
|
public Unit GetUnitBeingMoved()
|
||||||
{
|
{
|
||||||
Player player = ToPlayer();
|
Player player = ToPlayer();
|
||||||
if (player)
|
if (player)
|
||||||
|
|||||||
@@ -794,20 +794,20 @@ namespace Game.Entities
|
|||||||
// Parry
|
// Parry
|
||||||
// For spells
|
// For spells
|
||||||
// Resist
|
// Resist
|
||||||
public SpellMissInfo SpellHitResult(Unit victim, SpellInfo spell, bool CanReflect)
|
public SpellMissInfo SpellHitResult(Unit victim, SpellInfo spellInfo, bool CanReflect)
|
||||||
{
|
{
|
||||||
|
if (spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
||||||
|
return SpellMissInfo.None;
|
||||||
|
|
||||||
// Check for immune
|
// Check for immune
|
||||||
if (victim.IsImmunedToSpell(spell))
|
if (victim.IsImmunedToSpell(spellInfo))
|
||||||
return SpellMissInfo.Immune;
|
return SpellMissInfo.Immune;
|
||||||
|
|
||||||
// All positive spells can`t miss
|
// All positive spells can`t miss
|
||||||
// @todo client not show miss log for this spells - so need find info for this in dbc and use it!
|
// @todo client not show miss log for this spells - so need find info for this in dbc and use it!
|
||||||
if (spell.IsPositive()
|
if (spellInfo.IsPositive()
|
||||||
&& (!IsHostileTo(victim))) // prevent from affecting enemy by "positive" spell
|
&& (!IsHostileTo(victim))) // prevent from affecting enemy by "positive" spell
|
||||||
return SpellMissInfo.None;
|
return SpellMissInfo.None;
|
||||||
// Check for immune
|
|
||||||
if (victim.IsImmunedToDamage(spell))
|
|
||||||
return SpellMissInfo.Immune;
|
|
||||||
|
|
||||||
if (this == victim)
|
if (this == victim)
|
||||||
return SpellMissInfo.None;
|
return SpellMissInfo.None;
|
||||||
@@ -822,22 +822,22 @@ namespace Game.Entities
|
|||||||
int reflectchance = victim.GetTotalAuraModifier(AuraType.ReflectSpells);
|
int reflectchance = victim.GetTotalAuraModifier(AuraType.ReflectSpells);
|
||||||
var mReflectSpellsSchool = victim.GetAuraEffectsByType(AuraType.ReflectSpellsSchool);
|
var mReflectSpellsSchool = victim.GetAuraEffectsByType(AuraType.ReflectSpellsSchool);
|
||||||
foreach (var eff in mReflectSpellsSchool)
|
foreach (var eff in mReflectSpellsSchool)
|
||||||
if (Convert.ToBoolean(eff.GetMiscValue() & (int)spell.GetSchoolMask()))
|
if (Convert.ToBoolean(eff.GetMiscValue() & (int)spellInfo.GetSchoolMask()))
|
||||||
reflectchance += eff.GetAmount();
|
reflectchance += eff.GetAmount();
|
||||||
|
|
||||||
if (reflectchance > 0 && RandomHelper.randChance(reflectchance))
|
if (reflectchance > 0 && RandomHelper.randChance(reflectchance))
|
||||||
return SpellMissInfo.Reflect;
|
return SpellMissInfo.Reflect;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (spell.DmgClass)
|
switch (spellInfo.DmgClass)
|
||||||
{
|
{
|
||||||
case SpellDmgClass.Ranged:
|
case SpellDmgClass.Ranged:
|
||||||
case SpellDmgClass.Melee:
|
case SpellDmgClass.Melee:
|
||||||
return MeleeSpellHitResult(victim, spell);
|
return MeleeSpellHitResult(victim, spellInfo);
|
||||||
case SpellDmgClass.None:
|
case SpellDmgClass.None:
|
||||||
return SpellMissInfo.None;
|
return SpellMissInfo.None;
|
||||||
case SpellDmgClass.Magic:
|
case SpellDmgClass.Magic:
|
||||||
return MagicSpellHitResult(victim, spell);
|
return MagicSpellHitResult(victim, spellInfo);
|
||||||
}
|
}
|
||||||
return SpellMissInfo.None;
|
return SpellMissInfo.None;
|
||||||
}
|
}
|
||||||
@@ -845,11 +845,6 @@ namespace Game.Entities
|
|||||||
// Melee based spells hit result calculations
|
// Melee based spells hit result calculations
|
||||||
SpellMissInfo MeleeSpellHitResult(Unit victim, SpellInfo spellInfo)
|
SpellMissInfo MeleeSpellHitResult(Unit victim, SpellInfo spellInfo)
|
||||||
{
|
{
|
||||||
// Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will additionally fully ignore
|
|
||||||
// resist and deflect chances
|
|
||||||
if (spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
|
||||||
return SpellMissInfo.None;
|
|
||||||
|
|
||||||
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
||||||
|
|
||||||
// Check damage class instead of attack type to correctly handle judgements
|
// Check damage class instead of attack type to correctly handle judgements
|
||||||
@@ -1433,10 +1428,11 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
Spell spell = m_currentSpells.LookupByKey(CurrentSpellTypes.Channeled);
|
Spell spell = m_currentSpells.LookupByKey(CurrentSpellTypes.Channeled);
|
||||||
if (spell)
|
if (spell)
|
||||||
if (spell.getState() != SpellState.Finished)
|
if (spell.getState() != SpellState.Finished && spell.IsChannelActive())
|
||||||
return spell.GetSpellInfo().HasAttribute(SpellAttr5.CanChannelWhenMoving) && spell.IsChannelActive();
|
if (!spell.GetSpellInfo().IsMoveAllowedChannel())
|
||||||
|
return false;
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HasBreakableByDamageAuraType(AuraType type, uint excludeAura)
|
bool HasBreakableByDamageAuraType(AuraType type, uint excludeAura)
|
||||||
@@ -1552,24 +1548,35 @@ namespace Game.Entities
|
|||||||
SendEnergizeSpellLog(victim, spellId, damage, overEnergize, powerType);
|
SendEnergizeSpellLog(victim, spellId, damage, overEnergize, powerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplySpellImmune(uint spellId, SpellImmunity op, object type, bool apply)
|
public void ApplySpellImmune(uint spellId, SpellImmunity op, SpellSchoolMask type, bool apply)
|
||||||
|
{
|
||||||
|
ApplySpellImmune(spellId, op, (uint)type, apply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplySpellImmune(uint spellId, SpellImmunity op, AuraType type, bool apply)
|
||||||
|
{
|
||||||
|
ApplySpellImmune(spellId, op, (uint)type, apply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplySpellImmune(uint spellId, SpellImmunity op, SpellEffectName type, bool apply)
|
||||||
|
{
|
||||||
|
ApplySpellImmune(spellId, op, (uint)type, apply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplySpellImmune(uint spellId, SpellImmunity op, uint type, bool apply)
|
||||||
{
|
{
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
m_spellImmune[op].RemoveAll(p => p.spellType == Convert.ToUInt32(type));
|
m_spellImmune[(int)op].Add(type, spellId);
|
||||||
|
|
||||||
SpellImmune Immune = new SpellImmune();
|
|
||||||
Immune.spellId = spellId;
|
|
||||||
Immune.spellType = Convert.ToUInt32(type);
|
|
||||||
m_spellImmune.Add(op, Immune);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var spell in m_spellImmune[op].ToList())
|
var bounds = m_spellImmune[(int)op].LookupByKey(type);
|
||||||
|
foreach (var spell in bounds)
|
||||||
{
|
{
|
||||||
if (spell.spellId == spellId && spell.spellType == Convert.ToUInt32(type))
|
if (spell == spellId)
|
||||||
{
|
{
|
||||||
m_spellImmune.Remove(op, spell);
|
m_spellImmune[(int)op].Remove(type, spell);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1581,28 +1588,27 @@ namespace Game.Entities
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Single spell immunity.
|
// Single spell immunity.
|
||||||
var idList = m_spellImmune.LookupByKey(SpellImmunity.Id);
|
var idList = m_spellImmune[(int)SpellImmunity.Id];
|
||||||
foreach (var immune in idList)
|
if (idList.ContainsKey(spellInfo.Id))
|
||||||
if (immune.spellType == spellInfo.Id)
|
return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
if (spellInfo.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
if (spellInfo.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (spellInfo.Dispel != 0)
|
uint dispel = (uint)spellInfo.Dispel;
|
||||||
|
if (dispel != 0)
|
||||||
{
|
{
|
||||||
var dispelList = m_spellImmune.LookupByKey(SpellImmunity.Dispel);
|
var dispelList = m_spellImmune[(int)SpellImmunity.Dispel];
|
||||||
foreach (var immune in dispelList)
|
if (dispelList.ContainsKey(dispel))
|
||||||
if (immune.spellType == (int)spellInfo.Dispel)
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spells that don't have effectMechanics.
|
// Spells that don't have effectMechanics.
|
||||||
if (spellInfo.Mechanic != 0)
|
uint mechanic = (uint)spellInfo.Mechanic;
|
||||||
|
if (mechanic != 0)
|
||||||
{
|
{
|
||||||
var mechanicList = m_spellImmune.LookupByKey(SpellImmunity.Mechanic);
|
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
|
||||||
foreach (var immune in mechanicList)
|
if (mechanicList.ContainsKey(mechanic))
|
||||||
if (immune.spellType == (int)spellInfo.Mechanic)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1611,7 +1617,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
// State/effect immunities applied by aura expect full spell immunity
|
// State/effect immunities applied by aura expect full spell immunity
|
||||||
// Ignore effects with mechanic, they are supposed to be checked separately
|
// Ignore effects with mechanic, they are supposed to be checked separately
|
||||||
if (effect == null || !effect.IsEffect())
|
if (effect == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!IsImmunedToSpellEffect(spellInfo, effect.EffectIndex))
|
if (!IsImmunedToSpellEffect(spellInfo, effect.EffectIndex))
|
||||||
@@ -1624,13 +1630,13 @@ namespace Game.Entities
|
|||||||
if (immuneToAllEffects) //Return immune only if the target is immune to all spell effects.
|
if (immuneToAllEffects) //Return immune only if the target is immune to all spell effects.
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (spellInfo.Id != 42292 && spellInfo.Id != 59752)
|
if (!spellInfo.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune) && !spellInfo.HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune))
|
||||||
{
|
{
|
||||||
var schoolList = m_spellImmune.LookupByKey(SpellImmunity.School);
|
var schoolList = m_spellImmune[(int)SpellImmunity.School];
|
||||||
foreach (var immune in schoolList)
|
foreach (var pair in schoolList)
|
||||||
{
|
{
|
||||||
SpellInfo immuneSpellInfo = Global.SpellMgr.GetSpellInfo(immune.spellId);
|
SpellInfo immuneSpellInfo = Global.SpellMgr.GetSpellInfo(pair.Value);
|
||||||
if (Convert.ToBoolean(immune.spellType & (uint)spellInfo.GetSchoolMask())
|
if (Convert.ToBoolean(pair.Key & (uint)spellInfo.GetSchoolMask())
|
||||||
&& !(immuneSpellInfo != null && immuneSpellInfo.IsPositive() && spellInfo.IsPositive())
|
&& !(immuneSpellInfo != null && immuneSpellInfo.IsPositive() && spellInfo.IsPositive())
|
||||||
&& !spellInfo.CanPierceImmuneAura(immuneSpellInfo))
|
&& !spellInfo.CanPierceImmuneAura(immuneSpellInfo))
|
||||||
return true;
|
return true;
|
||||||
@@ -1642,18 +1648,18 @@ namespace Game.Entities
|
|||||||
public uint GetSchoolImmunityMask()
|
public uint GetSchoolImmunityMask()
|
||||||
{
|
{
|
||||||
uint mask = 0;
|
uint mask = 0;
|
||||||
var mechanicList = m_spellImmune.LookupByKey(SpellImmunity.School);
|
var mechanicList = m_spellImmune[(int)SpellImmunity.School];
|
||||||
foreach (var spell in mechanicList)
|
foreach (var pair in mechanicList)
|
||||||
mask |= spell.spellType;
|
mask |= pair.Key;
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
public uint GetMechanicImmunityMask()
|
public uint GetMechanicImmunityMask()
|
||||||
{
|
{
|
||||||
uint mask = 0;
|
uint mask = 0;
|
||||||
var mechanicList = m_spellImmune.LookupByKey(SpellImmunity.Mechanic);
|
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
|
||||||
foreach (var spell in mechanicList)
|
foreach (var pair in mechanicList)
|
||||||
mask |= (uint)(1 << (int)spell.spellType);
|
mask |= (1u << (int)pair.Value);
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
@@ -1668,75 +1674,76 @@ namespace Game.Entities
|
|||||||
|
|
||||||
// If m_immuneToEffect type contain this effect type, IMMUNE effect.
|
// If m_immuneToEffect type contain this effect type, IMMUNE effect.
|
||||||
uint eff = (uint)effect.Effect;
|
uint eff = (uint)effect.Effect;
|
||||||
var effectList = m_spellImmune.LookupByKey(SpellImmunity.Effect);
|
var effectList = m_spellImmune[(int)SpellImmunity.Effect];
|
||||||
foreach (var immune in effectList)
|
if (effectList.ContainsKey(eff))
|
||||||
if (immune.spellType == eff)
|
return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
uint mechanic = (uint)effect.Mechanic;
|
uint mechanic = (uint)effect.Mechanic;
|
||||||
if (mechanic != 0)
|
if (mechanic != 0)
|
||||||
{
|
{
|
||||||
var mechanicList = m_spellImmune.LookupByKey(SpellImmunity.Mechanic);
|
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
|
||||||
foreach (var immune in mechanicList)
|
if (mechanicList.ContainsKey(mechanic))
|
||||||
if (immune.spellType == mechanic)
|
return true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint aura = (uint)effect.ApplyAuraName;
|
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
||||||
if (aura != 0)
|
|
||||||
{
|
{
|
||||||
var list = m_spellImmune.LookupByKey(SpellImmunity.State);
|
uint aura = (uint)effect.ApplyAuraName;
|
||||||
foreach (var immune in list)
|
if (aura != 0)
|
||||||
if (immune.spellType == aura)
|
{
|
||||||
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
var list = m_spellImmune[(int)SpellImmunity.State];
|
||||||
return true;
|
if (list.ContainsKey(aura))
|
||||||
|
|
||||||
// Check for immune to application of harmful magical effects
|
|
||||||
var immuneAuraApply = GetAuraEffectsByType(AuraType.ModImmuneAuraApplySchool);
|
|
||||||
foreach (var immune in immuneAuraApply)
|
|
||||||
if (spellInfo.Dispel == DispelType.Magic && // Magic debuff
|
|
||||||
Convert.ToBoolean(immune.GetMiscValue() & (uint)spellInfo.GetSchoolMask()) && // Check school
|
|
||||||
!spellInfo.IsPositiveEffect(index)) // Harmful
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (!spellInfo.HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune))
|
||||||
|
{
|
||||||
|
// Check for immune to application of harmful magical effects
|
||||||
|
var immuneAuraApply = GetAuraEffectsByType(AuraType.ModImmuneAuraApplySchool);
|
||||||
|
foreach (var auraEffect in immuneAuraApply)
|
||||||
|
if (Convert.ToBoolean(auraEffect.GetMiscValue() & (int)spellInfo.GetSchoolMask()) && // Check school
|
||||||
|
!spellInfo.IsPositiveEffect(index)) // Harmful
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public bool IsImmunedToDamage(SpellSchoolMask shoolMask)
|
public bool IsImmunedToDamage(SpellSchoolMask schoolMask)
|
||||||
{
|
{
|
||||||
// If m_immuneToSchool type contain this school type, IMMUNE damage.
|
// If m_immuneToSchool type contain this school type, IMMUNE damage.
|
||||||
var schoolList = m_spellImmune.LookupByKey(SpellImmunity.School);
|
var schoolList = m_spellImmune[(int)SpellImmunity.School];
|
||||||
foreach (var immune in schoolList)
|
foreach (var immune in schoolList)
|
||||||
if (Convert.ToBoolean(immune.spellType & (uint)shoolMask))
|
if (Convert.ToBoolean(immune.Key & (uint)schoolMask))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If m_immuneToDamage type contain magic, IMMUNE damage.
|
// If m_immuneToDamage type contain magic, IMMUNE damage.
|
||||||
var damageList = m_spellImmune.LookupByKey(SpellImmunity.Damage);
|
var damageList = m_spellImmune[(int)SpellImmunity.Damage];
|
||||||
foreach (var immune in damageList)
|
foreach (var immune in damageList)
|
||||||
if (Convert.ToBoolean(immune.spellType & (uint)shoolMask))
|
if (Convert.ToBoolean(immune.Key & (uint)schoolMask))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public bool IsImmunedToDamage(SpellInfo spellInfo)
|
public bool IsImmunedToDamage(SpellInfo spellInfo)
|
||||||
{
|
{
|
||||||
if (spellInfo.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
if (spellInfo == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint shoolMask = (uint)spellInfo.GetSchoolMask();
|
if (spellInfo.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune) || spellInfo.HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune))
|
||||||
if (spellInfo.Id != 42292 && spellInfo.Id != 59752)
|
return false;
|
||||||
{
|
|
||||||
// If m_immuneToSchool type contain this school type, IMMUNE damage.
|
uint schoolMask = (uint)spellInfo.GetSchoolMask();
|
||||||
var schoolList = m_spellImmune.LookupByKey(SpellImmunity.School);
|
// If m_immuneToSchool type contain this school type, IMMUNE damage.
|
||||||
foreach (var immune in schoolList)
|
var schoolList = m_spellImmune[(int)SpellImmunity.School];
|
||||||
if (Convert.ToBoolean(immune.spellType & shoolMask) && !spellInfo.CanPierceImmuneAura(Global.SpellMgr.GetSpellInfo(immune.spellId)))
|
foreach (var pair in schoolList)
|
||||||
return true;
|
if (Convert.ToBoolean(pair.Key & schoolMask) && !spellInfo.CanPierceImmuneAura(Global.SpellMgr.GetSpellInfo(pair.Value)))
|
||||||
}
|
return true;
|
||||||
|
|
||||||
// If m_immuneToDamage type contain magic, IMMUNE damage.
|
// If m_immuneToDamage type contain magic, IMMUNE damage.
|
||||||
var damageList = m_spellImmune.LookupByKey(SpellImmunity.Damage);
|
var damageList = m_spellImmune[(int)SpellImmunity.Damage];
|
||||||
foreach (var immune in damageList)
|
foreach (var immune in damageList)
|
||||||
if (Convert.ToBoolean(immune.spellType & shoolMask))
|
if (Convert.ToBoolean(immune.Key & schoolMask))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -2173,7 +2180,7 @@ namespace Game.Entities
|
|||||||
bool isSpellBlocked(Unit victim, SpellInfo spellProto, WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
bool isSpellBlocked(Unit victim, SpellInfo spellProto, WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
||||||
{
|
{
|
||||||
// These spells can't be blocked
|
// These spells can't be blocked
|
||||||
if (spellProto != null && spellProto.HasAttribute(SpellAttr0.ImpossibleDodgeParryBlock))
|
if (spellProto != null && (spellProto.HasAttribute(SpellAttr0.ImpossibleDodgeParryBlock) || spellProto.HasAttribute(SpellAttr3.IgnoreHitResult)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Can't block when casting/controlled
|
// Can't block when casting/controlled
|
||||||
@@ -2657,28 +2664,6 @@ namespace Game.Entities
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplySpellDispelImmunity(SpellInfo spellProto, DispelType type, bool apply)
|
|
||||||
{
|
|
||||||
ApplySpellImmune(spellProto.Id, SpellImmunity.Dispel, type, apply);
|
|
||||||
|
|
||||||
if (apply && spellProto.HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
|
||||||
{
|
|
||||||
// Create dispel mask by dispel type
|
|
||||||
uint dispelMask = SpellInfo.GetDispelMask(type);
|
|
||||||
// Dispel all existing auras vs current dispel type
|
|
||||||
var auras = GetAppliedAuras();
|
|
||||||
foreach (var pair in auras)
|
|
||||||
{
|
|
||||||
SpellInfo spell = pair.Value.GetBase().GetSpellInfo();
|
|
||||||
if ((spell.GetDispelMask() & dispelMask) != 0)
|
|
||||||
{
|
|
||||||
// Dispel aura
|
|
||||||
RemoveAura(pair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DiminishingLevels GetDiminishing(DiminishingGroup group)
|
public DiminishingLevels GetDiminishing(DiminishingGroup group)
|
||||||
{
|
{
|
||||||
DiminishingReturn diminish = m_Diminishing[(int)group];
|
DiminishingReturn diminish = m_Diminishing[(int)group];
|
||||||
|
|||||||
@@ -54,6 +54,9 @@ namespace Game.Entities
|
|||||||
m_modAttackSpeedPct = new float[] { 1.0f, 1.0f, 1.0f };
|
m_modAttackSpeedPct = new float[] { 1.0f, 1.0f, 1.0f };
|
||||||
m_deathState = DeathState.Alive;
|
m_deathState = DeathState.Alive;
|
||||||
|
|
||||||
|
for (byte i = 0; i < (int)SpellImmunity.Max; ++i)
|
||||||
|
m_spellImmune[i] = new MultiMap<uint, uint>();
|
||||||
|
|
||||||
for (byte i = 0; i < (int)UnitMods.End; ++i)
|
for (byte i = 0; i < (int)UnitMods.End; ++i)
|
||||||
m_auraModifiersGroup[i] = new float[] { 0.0f, 100.0f, 1.0f, 0.0f, 1.0f };
|
m_auraModifiersGroup[i] = new float[] { 0.0f, 100.0f, 1.0f, 0.0f, 1.0f };
|
||||||
|
|
||||||
|
|||||||
@@ -151,8 +151,8 @@ namespace Game.Entities
|
|||||||
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.SchoolImmunity, true);
|
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.SchoolImmunity, true);
|
||||||
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.ModUnattackable, true);
|
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.ModUnattackable, true);
|
||||||
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.SchoolAbsorb, true);
|
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.SchoolAbsorb, true);
|
||||||
_me.ApplySpellImmune(0, SpellImmunity.Mechanic, Mechanics.Shield, true);
|
_me.ApplySpellImmune(0, SpellImmunity.Mechanic, (uint)Mechanics.Shield, true);
|
||||||
_me.ApplySpellImmune(0, SpellImmunity.Mechanic, Mechanics.Immune_Shield, true);
|
_me.ApplySpellImmune(0, SpellImmunity.Mechanic, (uint)Mechanics.Immune_Shield, true);
|
||||||
|
|
||||||
// ... Resistance, Split damage, Change stats ...
|
// ... Resistance, Split damage, Change stats ...
|
||||||
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.DamageShield, true);
|
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.DamageShield, true);
|
||||||
|
|||||||
@@ -377,6 +377,9 @@ namespace Game
|
|||||||
Log.outInfo(LogFilter.ServerLoading, "Loading SpellInfo diminishing infos...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading SpellInfo diminishing infos...");
|
||||||
Global.SpellMgr.LoadSpellInfoDiminishing();
|
Global.SpellMgr.LoadSpellInfoDiminishing();
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loading SpellInfo immunity infos...");
|
||||||
|
Global.SpellMgr.LoadSpellInfoImmunities();
|
||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loading PetFamilySpellsStore Data...");
|
Log.outInfo(LogFilter.ServerLoading, "Loading PetFamilySpellsStore Data...");
|
||||||
Global.SpellMgr.LoadPetFamilySpellsStore();
|
Global.SpellMgr.LoadPetFamilySpellsStore();
|
||||||
|
|
||||||
|
|||||||
@@ -2703,7 +2703,7 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
//Players on flying mounts must be immune to polymorph
|
//Players on flying mounts must be immune to polymorph
|
||||||
if (target.IsTypeId(TypeId.Player))
|
if (target.IsTypeId(TypeId.Player))
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Polymorph, apply);
|
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, (uint)Mechanics.Polymorph, apply);
|
||||||
|
|
||||||
// Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
|
// Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
|
||||||
if (apply && target.HasAuraEffect(42016, 0) && target.GetMountID() != 0)
|
if (apply && target.HasAuraEffect(42016, 0) && target.GetMountID() != 0)
|
||||||
@@ -2767,228 +2767,13 @@ namespace Game.Spells
|
|||||||
/*** IMMUNITY ***/
|
/*** IMMUNITY ***/
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
[AuraEffectHandler(AuraType.MechanicImmunityMask)]
|
[AuraEffectHandler(AuraType.MechanicImmunityMask)]
|
||||||
void HandleModStateImmunityMask(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
void HandleModMechanicImmunityMask(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||||
{
|
{
|
||||||
if (!mode.HasAnyFlag(AuraEffectHandleModes.Real))
|
if (!mode.HasAnyFlag(AuraEffectHandleModes.Real))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
List<AuraType> aura_immunity_list = new List<AuraType>();
|
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||||
|
|
||||||
uint mechanic_immunity_list = (1 << (int)Mechanics.Snare) | (1 << (int)Mechanics.Root)
|
|
||||||
| (1 << (int)Mechanics.Fear) | (1 << (int)Mechanics.Stun)
|
|
||||||
| (1 << (int)Mechanics.Sleep) | (1 << (int)Mechanics.Charm)
|
|
||||||
| (1 << (int)Mechanics.Sapped) | (1 << (int)Mechanics.Horror)
|
|
||||||
| (1 << (int)Mechanics.Polymorph) | (1 << (int)Mechanics.Disoriented)
|
|
||||||
| (1 << (int)Mechanics.Freeze) | (1 << (int)Mechanics.Turn);
|
|
||||||
|
|
||||||
int miscVal = GetMiscValue();
|
|
||||||
switch (miscVal)
|
|
||||||
{
|
|
||||||
case 27:
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Silence, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModSilence);
|
|
||||||
break;
|
|
||||||
case 96:
|
|
||||||
case 1615:
|
|
||||||
{
|
|
||||||
if (HasAmount())
|
|
||||||
{
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Snare, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Root, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Fear, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sleep, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Charm, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sapped, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Horror, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Polymorph, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Disoriented, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Freeze, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Turn, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModStun);
|
|
||||||
aura_immunity_list.Add(AuraType.ModDecreaseSpeed);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot);
|
|
||||||
aura_immunity_list.Add(AuraType.ModConfuse);
|
|
||||||
aura_immunity_list.Add(AuraType.ModFear);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 679:
|
|
||||||
{
|
|
||||||
if (GetId() == 57742)
|
|
||||||
{
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Snare, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Root, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Fear, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sleep, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Charm, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sapped, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Horror, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Polymorph, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Disoriented, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Freeze, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Turn, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModStun);
|
|
||||||
aura_immunity_list.Add(AuraType.ModDecreaseSpeed);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot);
|
|
||||||
aura_immunity_list.Add(AuraType.ModConfuse);
|
|
||||||
aura_immunity_list.Add(AuraType.ModFear);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1557:
|
|
||||||
{
|
|
||||||
if (GetId() == 64187)
|
|
||||||
{
|
|
||||||
mechanic_immunity_list = (1 << (int)Mechanics.Stun);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModStun);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Snare, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Root, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Fear, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sleep, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Charm, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sapped, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Horror, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Polymorph, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Disoriented, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Freeze, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Turn, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModStun);
|
|
||||||
aura_immunity_list.Add(AuraType.ModDecreaseSpeed);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot);
|
|
||||||
aura_immunity_list.Add(AuraType.ModConfuse);
|
|
||||||
aura_immunity_list.Add(AuraType.ModFear);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1614:
|
|
||||||
case 1694:
|
|
||||||
{
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Effect, SpellEffectName.AttackMe, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModTaunt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1630:
|
|
||||||
{
|
|
||||||
if (!HasAmount())
|
|
||||||
{
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Effect, SpellEffectName.AttackMe, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModTaunt);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Snare, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Root, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Fear, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sleep, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Charm, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sapped, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Horror, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Polymorph, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Disoriented, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Freeze, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Turn, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModStun);
|
|
||||||
aura_immunity_list.Add(AuraType.ModDecreaseSpeed);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot);
|
|
||||||
aura_immunity_list.Add(AuraType.ModConfuse);
|
|
||||||
aura_immunity_list.Add(AuraType.ModFear);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 477:
|
|
||||||
case 1733:
|
|
||||||
{
|
|
||||||
if (!HasAmount())
|
|
||||||
{
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Snare, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Root, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Fear, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sleep, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Charm, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sapped, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Horror, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Polymorph, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Disoriented, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Freeze, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Turn, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Effect, SpellEffectName.KnockBack, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Effect, SpellEffectName.KnockBackDest, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModStun);
|
|
||||||
aura_immunity_list.Add(AuraType.ModDecreaseSpeed);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot);
|
|
||||||
aura_immunity_list.Add(AuraType.ModConfuse);
|
|
||||||
aura_immunity_list.Add(AuraType.ModFear);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 878:
|
|
||||||
{
|
|
||||||
if (GetAmount() == 1)
|
|
||||||
{
|
|
||||||
mechanic_immunity_list = (1 << (int)Mechanics.Snare) | (1 << (int)Mechanics.Stun)
|
|
||||||
| (1 << (int)Mechanics.Disoriented) | (1 << (int)Mechanics.Freeze);
|
|
||||||
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Snare, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Disoriented, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Freeze, apply);
|
|
||||||
aura_immunity_list.Add(AuraType.ModStun);
|
|
||||||
aura_immunity_list.Add(AuraType.ModDecreaseSpeed);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aura_immunity_list.Empty())
|
|
||||||
{
|
|
||||||
if (Convert.ToBoolean(miscVal & (1 << 10)))
|
|
||||||
aura_immunity_list.Add(AuraType.ModStun);
|
|
||||||
if (Convert.ToBoolean(miscVal & (1 << 1)))
|
|
||||||
aura_immunity_list.Add(AuraType.Transform);
|
|
||||||
|
|
||||||
// These flag can be recognized wrong:
|
|
||||||
if (Convert.ToBoolean(miscVal & (1 << 6)))
|
|
||||||
aura_immunity_list.Add(AuraType.ModDecreaseSpeed);
|
|
||||||
if (Convert.ToBoolean(miscVal & (1 << 0)))
|
|
||||||
{
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot);
|
|
||||||
aura_immunity_list.Add(AuraType.ModRoot2);
|
|
||||||
}
|
|
||||||
if (Convert.ToBoolean(miscVal & (1 << 2)))
|
|
||||||
aura_immunity_list.Add(AuraType.ModConfuse);
|
|
||||||
if (Convert.ToBoolean(miscVal & (1 << 9)))
|
|
||||||
aura_immunity_list.Add(AuraType.ModFear);
|
|
||||||
if (Convert.ToBoolean(miscVal & (1 << 7)))
|
|
||||||
aura_immunity_list.Add(AuraType.ModDisarm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// apply immunities
|
|
||||||
foreach (var iter in aura_immunity_list)
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.State, iter, apply);
|
|
||||||
|
|
||||||
if (apply && GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
|
||||||
{
|
|
||||||
target.RemoveAurasWithMechanic(mechanic_immunity_list, AuraRemoveMode.Default, GetId());
|
|
||||||
foreach (var iter in aura_immunity_list)
|
|
||||||
target.RemoveAurasByType(iter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.MechanicImmunity)]
|
[AuraEffectHandler(AuraType.MechanicImmunity)]
|
||||||
@@ -2998,52 +2783,7 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
uint mechanic;
|
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||||
|
|
||||||
switch (GetId())
|
|
||||||
{
|
|
||||||
case 34471: // The Beast Within
|
|
||||||
case 19574: // Bestial Wrath
|
|
||||||
mechanic = (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Charm, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Disoriented, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Fear, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Root, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sleep, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Snare, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Freeze, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Knockout, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Polymorph, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Banish, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Shackle, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Turn, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Horror, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Daze, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Sapped, apply);
|
|
||||||
break;
|
|
||||||
case 42292: // PvP trinket
|
|
||||||
case 59752: // Every Man for Himself
|
|
||||||
case 53490: // Bullheaded
|
|
||||||
mechanic = (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
|
||||||
// Actually we should apply immunities here, too, but the aura has only 100 ms duration, so there is practically no point
|
|
||||||
break;
|
|
||||||
case 54508: // Demonic Empowerment
|
|
||||||
mechanic = (1 << (int)Mechanics.Snare) | (1 << (int)Mechanics.Root);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Snare, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Root, apply);
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, Mechanics.Stun, apply);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (GetMiscValue() < 1)
|
|
||||||
return;
|
|
||||||
mechanic = (uint)(1 << GetMiscValue());
|
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, GetMiscValue(), apply);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (apply && GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
|
||||||
target.RemoveAurasWithMechanic(mechanic, AuraRemoveMode.Default, GetId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.EffectImmunity)]
|
[AuraEffectHandler(AuraType.EffectImmunity)]
|
||||||
@@ -3053,8 +2793,7 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Effect, GetMiscValue(), apply);
|
|
||||||
|
|
||||||
// when removing flag aura, handle flag drop
|
// when removing flag aura, handle flag drop
|
||||||
Player player = target.ToPlayer();
|
Player player = target.ToPlayer();
|
||||||
@@ -3078,11 +2817,7 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.State, GetMiscValue(), apply);
|
|
||||||
|
|
||||||
if (apply && GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
|
||||||
target.RemoveAurasByType((AuraType)GetMiscValue(), ObjectGuid.Empty, GetBase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.SchoolImmunity)]
|
[AuraEffectHandler(AuraType.SchoolImmunity)]
|
||||||
@@ -3092,8 +2827,7 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.School, (uint)GetMiscValue(), (apply));
|
|
||||||
|
|
||||||
if (GetSpellInfo().Mechanic == Mechanics.Banish)
|
if (GetSpellInfo().Mechanic == Mechanics.Banish)
|
||||||
{
|
{
|
||||||
@@ -3103,9 +2837,9 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
bool banishFound = false;
|
bool banishFound = false;
|
||||||
var banishAuras = target.GetAuraEffectsByType(GetAuraType());
|
var banishAuras = target.GetAuraEffectsByType(GetAuraType());
|
||||||
foreach (var eff in banishAuras)
|
foreach (var aurEff in banishAuras)
|
||||||
{
|
{
|
||||||
if (eff.GetSpellInfo().Mechanic == Mechanics.Banish)
|
if (aurEff.GetSpellInfo().Mechanic == Mechanics.Banish)
|
||||||
{
|
{
|
||||||
banishFound = true;
|
banishFound = true;
|
||||||
break;
|
break;
|
||||||
@@ -3124,21 +2858,6 @@ namespace Game.Spells
|
|||||||
if (GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity)
|
if (GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity)
|
||||||
&& GetSpellInfo().HasAttribute(SpellAttr2.DamageReducedShield))
|
&& GetSpellInfo().HasAttribute(SpellAttr2.DamageReducedShield))
|
||||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||||
|
|
||||||
/// @todo optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else
|
|
||||||
if ((apply) && GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity) && GetSpellInfo().IsPositive()) //Only positive immunity removes auras
|
|
||||||
{
|
|
||||||
int schoolMask = GetMiscValue();
|
|
||||||
target.RemoveAppliedAuras(aurApp1 =>
|
|
||||||
{
|
|
||||||
SpellInfo spell = aurApp1.GetBase().GetSpellInfo();
|
|
||||||
return Convert.ToBoolean((int)spell.GetSchoolMask() & schoolMask)//Check for school mask
|
|
||||||
&& GetSpellInfo().CanDispelAura(spell)
|
|
||||||
&& !aurApp1.IsPositive() //Don't remove positive spells
|
|
||||||
&& !spell.IsPassive() // Don't remove passive auras
|
|
||||||
&& spell.Id != GetId(); //Don't remove self
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.DamageImmunity)]
|
[AuraEffectHandler(AuraType.DamageImmunity)]
|
||||||
@@ -3148,8 +2867,7 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Damage, (uint)GetMiscValue(), apply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.DispelImmunity)]
|
[AuraEffectHandler(AuraType.DispelImmunity)]
|
||||||
@@ -3159,8 +2877,7 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||||
target.ApplySpellDispelImmunity(m_spellInfo, (DispelType)GetMiscValue(), (apply));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************/
|
/*********************************************************/
|
||||||
@@ -4608,7 +4325,7 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
// Recently Bandaged
|
// Recently Bandaged
|
||||||
case 11196:
|
case 11196:
|
||||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, GetMiscValue(), apply);
|
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, (uint)GetMiscValue(), apply);
|
||||||
break;
|
break;
|
||||||
// Unstable Power
|
// Unstable Power
|
||||||
case 24658:
|
case 24658:
|
||||||
|
|||||||
+284
-221
@@ -2091,7 +2091,7 @@ namespace Game.Spells
|
|||||||
return SpellMissInfo.Evade;
|
return SpellMissInfo.Evade;
|
||||||
|
|
||||||
// For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
|
// For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
|
||||||
if (m_spellInfo.Speed != 0.0f && (unit.IsImmunedToDamage(m_spellInfo) || unit.IsImmunedToSpell(m_spellInfo)))
|
if (m_spellInfo.Speed != 0.0f && unit.IsImmunedToSpell(m_spellInfo))
|
||||||
return SpellMissInfo.Immune;
|
return SpellMissInfo.Immune;
|
||||||
|
|
||||||
// disable effects to which unit is immune
|
// disable effects to which unit is immune
|
||||||
@@ -2523,7 +2523,8 @@ namespace Game.Spells
|
|||||||
if (Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreComboPoints) || m_CastItem != null || m_caster.m_playerMovingMe == null)
|
if (Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreComboPoints) || m_CastItem != null || m_caster.m_playerMovingMe == null)
|
||||||
m_needComboPoints = false;
|
m_needComboPoints = false;
|
||||||
|
|
||||||
SpellCastResult result = CheckCast(true);
|
uint param1 = 0, param2 = 0;
|
||||||
|
SpellCastResult result = CheckCast(true, ref param1, ref param2);
|
||||||
// target is checked in too many locations and with different results to handle each of them
|
// target is checked in too many locations and with different results to handle each of them
|
||||||
// handle just the general SPELL_FAILED_BAD_TARGETS result which is the default result for most DBC target checks
|
// handle just the general SPELL_FAILED_BAD_TARGETS result which is the default result for most DBC target checks
|
||||||
if (Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreTargetCheck) && result == SpellCastResult.BadTargets)
|
if (Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreTargetCheck) && result == SpellCastResult.BadTargets)
|
||||||
@@ -2548,7 +2549,10 @@ namespace Game.Spells
|
|||||||
m_caster.ToPlayer().SetSpellModTakingSpell(this, false);
|
m_caster.ToPlayer().SetSpellModTakingSpell(this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendCastResult(result);
|
if (param1 != 0 || param2 != 0)
|
||||||
|
SendCastResult(result, param1, param2);
|
||||||
|
else
|
||||||
|
SendCastResult(result);
|
||||||
|
|
||||||
finish(false);
|
finish(false);
|
||||||
return;
|
return;
|
||||||
@@ -2749,10 +2753,11 @@ namespace Game.Spells
|
|||||||
// 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)
|
||||||
{
|
{
|
||||||
SpellCastResult castResult = CheckCast(false);
|
uint param1 = 0, param2 = 0;
|
||||||
|
SpellCastResult castResult = CheckCast(false, ref param1, ref param2);
|
||||||
if (castResult != SpellCastResult.SpellCastOk)
|
if (castResult != SpellCastResult.SpellCastOk)
|
||||||
{
|
{
|
||||||
SendCastResult(castResult);
|
SendCastResult(castResult, param1, param2);
|
||||||
SendInterrupted(0);
|
SendInterrupted(0);
|
||||||
//restore spell mods
|
//restore spell mods
|
||||||
if (m_caster.IsTypeId(TypeId.Player))
|
if (m_caster.IsTypeId(TypeId.Player))
|
||||||
@@ -3316,7 +3321,7 @@ namespace Game.Spells
|
|||||||
m_caster.AttackStop();
|
m_caster.AttackStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FillSpellCastFailedArgs<T>(T packet, ObjectGuid castId, SpellInfo spellInfo, SpellCastResult result, SpellCustomErrors customError, uint[] misc, Player caster) where T : CastFailedBase
|
static void FillSpellCastFailedArgs<T>(T packet, ObjectGuid castId, SpellInfo spellInfo, SpellCastResult result, SpellCustomErrors customError, uint? param1, uint? param2, Player caster) where T : CastFailedBase
|
||||||
{
|
{
|
||||||
packet.CastID = castId;
|
packet.CastID = castId;
|
||||||
packet.SpellID = (int)spellInfo.Id;
|
packet.SpellID = (int)spellInfo.Id;
|
||||||
@@ -3325,112 +3330,183 @@ namespace Game.Spells
|
|||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case SpellCastResult.NotReady:
|
case SpellCastResult.NotReady:
|
||||||
packet.FailedArg1 = 0; // unknown (value 1 update cooldowns on client flag)
|
if (param1.HasValue)
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
else
|
||||||
|
packet.FailedArg1 = 0;// unknown (value 1 update cooldowns on client flag)
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.RequiresSpellFocus:
|
case SpellCastResult.RequiresSpellFocus:
|
||||||
packet.FailedArg1 = (int)spellInfo.RequiresSpellFocus; // SpellFocusObject.dbc id
|
if (param1.HasValue)
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
else
|
||||||
|
packet.FailedArg1 = (int)spellInfo.RequiresSpellFocus; // SpellFocusObject.dbc id
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.RequiresArea: // AreaTable.dbc id
|
case SpellCastResult.RequiresArea: // AreaTable.dbc id
|
||||||
// hardcode areas limitation case
|
if (param1.HasValue)
|
||||||
switch (spellInfo.Id)
|
packet.FailedArg1 = (int)param1;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
case 41617: // Cenarion Mana Salve
|
// hardcode areas limitation case
|
||||||
case 41619: // Cenarion Healing Salve
|
switch (spellInfo.Id)
|
||||||
packet.FailedArg1 = 3905;
|
{
|
||||||
break;
|
case 41617: // Cenarion Mana Salve
|
||||||
case 41618: // Bottled Nethergon Energy
|
case 41619: // Cenarion Healing Salve
|
||||||
case 41620: // Bottled Nethergon Vapor
|
packet.FailedArg1 = 3905;
|
||||||
packet.FailedArg1 = 3842;
|
break;
|
||||||
break;
|
case 41618: // Bottled Nethergon Energy
|
||||||
case 45373: // Bloodberry Elixir
|
case 41620: // Bottled Nethergon Vapor
|
||||||
packet.FailedArg1 = 4075;
|
packet.FailedArg1 = 3842;
|
||||||
break;
|
break;
|
||||||
default: // default case (don't must be)
|
case 45373: // Bloodberry Elixir
|
||||||
packet.FailedArg1 = 0;
|
packet.FailedArg1 = 4075;
|
||||||
break;
|
break;
|
||||||
|
default: // default case (don't must be)
|
||||||
|
packet.FailedArg1 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.Totems:
|
case SpellCastResult.Totems:
|
||||||
if (spellInfo.Totem[0] != 0)
|
if (param1.HasValue)
|
||||||
packet.FailedArg1 = (int)spellInfo.Totem[0];
|
{
|
||||||
if (spellInfo.Totem[1] != 0)
|
packet.FailedArg1 = (int)param1;
|
||||||
packet.FailedArg2 = (int)spellInfo.Totem[1];
|
if (param2.HasValue)
|
||||||
|
packet.FailedArg2 = (int)param2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (spellInfo.Totem[0] != 0)
|
||||||
|
packet.FailedArg1 = (int)spellInfo.Totem[0];
|
||||||
|
if (spellInfo.Totem[1] != 0)
|
||||||
|
packet.FailedArg2 = (int)spellInfo.Totem[1];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.TotemCategory:
|
case SpellCastResult.TotemCategory:
|
||||||
if (spellInfo.TotemCategory[0] != 0)
|
if (param1.HasValue)
|
||||||
packet.FailedArg1 = (int)spellInfo.TotemCategory[0];
|
{
|
||||||
if (spellInfo.TotemCategory[1] != 0)
|
packet.FailedArg1 = (int)param1;
|
||||||
packet.FailedArg2 = (int)spellInfo.TotemCategory[1];
|
if (param2.HasValue)
|
||||||
|
packet.FailedArg2 = (int)param2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (spellInfo.TotemCategory[0] != 0)
|
||||||
|
packet.FailedArg1 = (int)spellInfo.TotemCategory[0];
|
||||||
|
if (spellInfo.TotemCategory[1] != 0)
|
||||||
|
packet.FailedArg2 = (int)spellInfo.TotemCategory[1];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.EquippedItemClass:
|
case SpellCastResult.EquippedItemClass:
|
||||||
case SpellCastResult.EquippedItemClassMainhand:
|
case SpellCastResult.EquippedItemClassMainhand:
|
||||||
case SpellCastResult.EquippedItemClassOffhand:
|
case SpellCastResult.EquippedItemClassOffhand:
|
||||||
packet.FailedArg1 = (int)spellInfo.EquippedItemClass;
|
if (param1.HasValue && param2.HasValue)
|
||||||
packet.FailedArg2 = spellInfo.EquippedItemSubClassMask;
|
{
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
packet.FailedArg2 = (int)param2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet.FailedArg1 = (int)spellInfo.EquippedItemClass;
|
||||||
|
packet.FailedArg2 = spellInfo.EquippedItemSubClassMask;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.TooManyOfItem:
|
case SpellCastResult.TooManyOfItem:
|
||||||
{
|
{
|
||||||
uint item = 0;
|
if (param1.HasValue)
|
||||||
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(caster.GetMap().GetDifficultyID()))
|
packet.FailedArg1 = (int)param1;
|
||||||
if (effect.ItemType != 0)
|
else
|
||||||
item = effect.ItemType;
|
{
|
||||||
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item);
|
uint item = 0;
|
||||||
if (proto != null && proto.GetItemLimitCategory() != 0)
|
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(caster.GetMap().GetDifficultyID()))
|
||||||
packet.FailedArg1 = (int)proto.GetItemLimitCategory();
|
if (effect.ItemType != 0)
|
||||||
|
item = effect.ItemType;
|
||||||
|
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item);
|
||||||
|
if (proto != null && proto.GetItemLimitCategory() != 0)
|
||||||
|
packet.FailedArg1 = (int)proto.GetItemLimitCategory();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SpellCastResult.PreventedByMechanic:
|
case SpellCastResult.PreventedByMechanic:
|
||||||
packet.FailedArg1 = (int)spellInfo.GetAllEffectsMechanicMask(); // SpellMechanic.dbc id
|
if (param1.HasValue)
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
else
|
||||||
|
packet.FailedArg1 = (int)spellInfo.GetAllEffectsMechanicMask(); // SpellMechanic.dbc id
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.NeedExoticAmmo:
|
case SpellCastResult.NeedExoticAmmo:
|
||||||
packet.FailedArg1 = spellInfo.EquippedItemSubClassMask; // seems correct...
|
if (param1.HasValue)
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
else
|
||||||
|
packet.FailedArg1 = spellInfo.EquippedItemSubClassMask; // seems correct...
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.NeedMoreItems:
|
case SpellCastResult.NeedMoreItems:
|
||||||
packet.FailedArg1 = 0; // Item id
|
if (param1.HasValue && param2.HasValue)
|
||||||
packet.FailedArg2 = 0; // Item count?
|
{
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
packet.FailedArg2 = (int)param2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet.FailedArg1 = 0; // Item id
|
||||||
|
packet.FailedArg2 = 0; // Item count?
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.MinSkill:
|
case SpellCastResult.MinSkill:
|
||||||
packet.FailedArg1 = 0; // SkillLine.dbc id
|
if (param1.HasValue && param2.HasValue)
|
||||||
packet.FailedArg2 = 0; // required skill value
|
{
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
packet.FailedArg2 = (int)param2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet.FailedArg1 = 0; // SkillLine.dbc id
|
||||||
|
packet.FailedArg2 = 0; // required skill value
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.FishingTooLow:
|
case SpellCastResult.FishingTooLow:
|
||||||
packet.FailedArg1 = 0; // required fishing skill
|
if (param1.HasValue)
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
else
|
||||||
|
packet.FailedArg1 = 0; // required fishing skill
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.CustomError:
|
case SpellCastResult.CustomError:
|
||||||
packet.FailedArg1 = (int)customError;
|
packet.FailedArg1 = (int)customError;
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.Silenced:
|
case SpellCastResult.Silenced:
|
||||||
packet.FailedArg1 = 0; // Unknown
|
if (param1.HasValue)
|
||||||
|
packet.FailedArg1 = (int)param1;
|
||||||
|
else
|
||||||
|
packet.FailedArg1 = 0; // Unknown
|
||||||
break;
|
break;
|
||||||
case SpellCastResult.Reagents:
|
case SpellCastResult.Reagents:
|
||||||
{
|
{
|
||||||
uint missingItem = 0;
|
if (param1.HasValue)
|
||||||
for (uint i = 0; i < SpellConst.MaxReagents; i++)
|
packet.FailedArg1 = (int)param1;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (spellInfo.Reagent[i] <= 0)
|
uint missingItem = 0;
|
||||||
continue;
|
for (uint i = 0; i < SpellConst.MaxReagents; i++)
|
||||||
|
|
||||||
uint itemid = (uint)spellInfo.Reagent[i];
|
|
||||||
uint itemcount = spellInfo.ReagentCount[i];
|
|
||||||
|
|
||||||
if (!caster.HasItemCount(itemid, itemcount))
|
|
||||||
{
|
{
|
||||||
missingItem = itemid;
|
if (spellInfo.Reagent[i] <= 0)
|
||||||
break;
|
continue;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
packet.FailedArg1 = (int)missingItem; // first missing item
|
uint itemid = (uint)spellInfo.Reagent[i];
|
||||||
|
uint itemcount = spellInfo.ReagentCount[i];
|
||||||
|
|
||||||
|
if (!caster.HasItemCount(itemid, itemcount))
|
||||||
|
{
|
||||||
|
missingItem = itemid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
packet.FailedArg1 = (int)missingItem; // first missing item
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SpellCastResult.CantUntalent:
|
case SpellCastResult.CantUntalent:
|
||||||
{
|
{
|
||||||
if (misc != null)
|
Contract.Assert(param1.HasValue);
|
||||||
{
|
packet.FailedArg1 = (int)param1;
|
||||||
TalentRecord talent = CliDB.TalentStorage.LookupByKey(misc[0]);
|
|
||||||
if (talent != null)
|
|
||||||
packet.FailedArg1 = (int)talent.SpellID;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO: SPELL_FAILED_NOT_STANDING
|
// TODO: SPELL_FAILED_NOT_STANDING
|
||||||
@@ -3439,7 +3515,7 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendCastResult(SpellCastResult result)
|
public void SendCastResult(SpellCastResult result, uint? param1 = null, uint? param2 = null)
|
||||||
{
|
{
|
||||||
if (result == SpellCastResult.SpellCastOk)
|
if (result == SpellCastResult.SpellCastOk)
|
||||||
return;
|
return;
|
||||||
@@ -3447,7 +3523,7 @@ namespace Game.Spells
|
|||||||
if (!m_caster.IsTypeId(TypeId.Player))
|
if (!m_caster.IsTypeId(TypeId.Player))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_caster.ToPlayer().GetSession().PlayerLoading()) // don't send cast results at loading time
|
if (m_caster.ToPlayer().IsLoading()) // don't send cast results at loading time
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.DontReportCastError))
|
if (_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.DontReportCastError))
|
||||||
@@ -3455,11 +3531,11 @@ namespace Game.Spells
|
|||||||
|
|
||||||
CastFailed castFailed = new CastFailed();
|
CastFailed castFailed = new CastFailed();
|
||||||
castFailed.SpellXSpellVisualID = (int)m_SpellVisual;
|
castFailed.SpellXSpellVisualID = (int)m_SpellVisual;
|
||||||
FillSpellCastFailedArgs(castFailed, m_castId, m_spellInfo, result, m_customError, m_misc.GetRawData(), m_caster.ToPlayer());
|
FillSpellCastFailedArgs(castFailed, m_castId, m_spellInfo, result, m_customError, param1, param2, m_caster.ToPlayer());
|
||||||
m_caster.ToPlayer().SendPacket(castFailed);
|
m_caster.ToPlayer().SendPacket(castFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPetCastResult(SpellCastResult result)
|
public void SendPetCastResult(SpellCastResult result, uint? param1 = null, uint? param2 = null)
|
||||||
{
|
{
|
||||||
if (result == SpellCastResult.SpellCastOk)
|
if (result == SpellCastResult.SpellCastOk)
|
||||||
return;
|
return;
|
||||||
@@ -3472,18 +3548,18 @@ namespace Game.Spells
|
|||||||
result = SpellCastResult.DontReport;
|
result = SpellCastResult.DontReport;
|
||||||
|
|
||||||
PetCastFailed petCastFailed = new PetCastFailed();
|
PetCastFailed petCastFailed = new PetCastFailed();
|
||||||
FillSpellCastFailedArgs(petCastFailed, m_castId, m_spellInfo, result, SpellCustomErrors.None, m_misc.GetRawData(), owner.ToPlayer());
|
FillSpellCastFailedArgs(petCastFailed, m_castId, m_spellInfo, result, SpellCustomErrors.None, param1, param2, owner.ToPlayer());
|
||||||
owner.ToPlayer().SendPacket(petCastFailed);
|
owner.ToPlayer().SendPacket(petCastFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendCastResult(Player caster, SpellInfo spellInfo, uint spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError = SpellCustomErrors.None, uint[] misc = null)
|
public static void SendCastResult(Player caster, SpellInfo spellInfo, uint spellVisual, ObjectGuid cast_count, SpellCastResult result, SpellCustomErrors customError = SpellCustomErrors.None, uint? param1 = null, uint? param2 = null)
|
||||||
{
|
{
|
||||||
if (result == SpellCastResult.SpellCastOk)
|
if (result == SpellCastResult.SpellCastOk)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CastFailed packet = new CastFailed();
|
CastFailed packet = new CastFailed();
|
||||||
packet.SpellXSpellVisualID = (int)spellVisual;
|
packet.SpellXSpellVisualID = (int)spellVisual;
|
||||||
FillSpellCastFailedArgs(packet, cast_count, spellInfo, result, customError, misc, caster);
|
FillSpellCastFailedArgs(packet, cast_count, spellInfo, result, customError, param1, param2, caster);
|
||||||
caster.SendPacket(packet);
|
caster.SendPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4329,6 +4405,12 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SpellCastResult CheckCast(bool strict)
|
public SpellCastResult CheckCast(bool strict)
|
||||||
|
{
|
||||||
|
uint param1 = 0, param2 = 0;
|
||||||
|
return CheckCast(strict, ref param1, ref param2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpellCastResult CheckCast(bool strict, ref uint param1, ref uint param2)
|
||||||
{
|
{
|
||||||
SpellCastResult castResult = SpellCastResult.SpellCastOk;
|
SpellCastResult castResult = SpellCastResult.SpellCastOk;
|
||||||
// check death state
|
// check death state
|
||||||
@@ -4395,13 +4477,15 @@ namespace Game.Spells
|
|||||||
bool checkForm = true;
|
bool checkForm = true;
|
||||||
// Ignore form req aura
|
// Ignore form req aura
|
||||||
var ignore = m_caster.GetAuraEffectsByType(AuraType.ModIgnoreShapeshift);
|
var ignore = m_caster.GetAuraEffectsByType(AuraType.ModIgnoreShapeshift);
|
||||||
foreach (var aura in ignore)
|
foreach (var aurEff in ignore)
|
||||||
{
|
{
|
||||||
if (!aura.IsAffectingSpell(m_spellInfo))
|
if (!aurEff.IsAffectingSpell(m_spellInfo))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
checkForm = false;
|
checkForm = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkForm)
|
if (checkForm)
|
||||||
{
|
{
|
||||||
// Cannot be used in this stance/form
|
// Cannot be used in this stance/form
|
||||||
@@ -4630,7 +4714,7 @@ namespace Game.Spells
|
|||||||
// always (except passive spells) check items (focus object can be required for any type casts)
|
// always (except passive spells) check items (focus object can be required for any type casts)
|
||||||
if (!m_spellInfo.IsPassive())
|
if (!m_spellInfo.IsPassive())
|
||||||
{
|
{
|
||||||
castResult = CheckItems();
|
castResult = CheckItems(ref param1, ref param2);
|
||||||
if (castResult != SpellCastResult.SpellCastOk)
|
if (castResult != SpellCastResult.SpellCastOk)
|
||||||
return castResult;
|
return castResult;
|
||||||
}
|
}
|
||||||
@@ -4650,7 +4734,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreCasterAuras))
|
if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreCasterAuras))
|
||||||
{
|
{
|
||||||
castResult = CheckCasterAuras();
|
castResult = CheckCasterAuras(ref param1);
|
||||||
if (castResult != SpellCastResult.SpellCastOk)
|
if (castResult != SpellCastResult.SpellCastOk)
|
||||||
return castResult;
|
return castResult;
|
||||||
}
|
}
|
||||||
@@ -4909,7 +4993,7 @@ namespace Game.Spells
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (!m_caster.IsTypeId(TypeId.Player) // only players can open locks, gather etc.
|
if (!m_caster.IsTypeId(TypeId.Player) // only players can open locks, gather etc.
|
||||||
// we need a go target in case of TARGET_GAMEOBJECT_TARGET
|
// we need a go target in case of TARGET_GAMEOBJECT_TARGET
|
||||||
|| (effect.TargetA.GetTarget() == Targets.GameobjectTarget && m_targets.GetGOTarget() == null))
|
|| (effect.TargetA.GetTarget() == Targets.GameobjectTarget && m_targets.GetGOTarget() == null))
|
||||||
return SpellCastResult.BadTargets;
|
return SpellCastResult.BadTargets;
|
||||||
|
|
||||||
@@ -5139,7 +5223,10 @@ namespace Game.Spells
|
|||||||
if (talent == null)
|
if (talent == null)
|
||||||
return SpellCastResult.DontReport;
|
return SpellCastResult.DontReport;
|
||||||
if (m_caster.GetSpellHistory().HasCooldown(talent.SpellID))
|
if (m_caster.GetSpellHistory().HasCooldown(talent.SpellID))
|
||||||
|
{
|
||||||
|
param1 = talent.SpellID;
|
||||||
return SpellCastResult.CantUntalent;
|
return SpellCastResult.CantUntalent;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SpellEffectName.GiveArtifactPower:
|
case SpellEffectName.GiveArtifactPower:
|
||||||
@@ -5362,146 +5449,109 @@ namespace Game.Spells
|
|||||||
return CheckCast(true);
|
return CheckCast(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellCastResult CheckCasterAuras()
|
SpellCastResult CheckCasterAuras(ref uint param1)
|
||||||
{
|
{
|
||||||
// spells totally immuned to caster auras (wsg flag drop, give marks etc)
|
// spells totally immuned to caster auras (wsg flag drop, give marks etc)
|
||||||
if (m_spellInfo.HasAttribute(SpellAttr6.IgnoreCasterAuras))
|
if (m_spellInfo.HasAttribute(SpellAttr6.IgnoreCasterAuras))
|
||||||
return SpellCastResult.SpellCastOk;
|
return SpellCastResult.SpellCastOk;
|
||||||
|
|
||||||
int school_immune = 0;
|
bool usableWhileStunned = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileStunned);
|
||||||
uint mechanic_immune = 0;
|
bool usableWhileFeared = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileFeared);
|
||||||
uint dispel_immune = 0;
|
bool usableWhileConfused = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileConfused);
|
||||||
|
if (m_spellInfo.HasAttribute(SpellAttr7.UsableInStunFearConfusion))
|
||||||
// Check if the spell grants school or mechanic immunity.
|
|
||||||
// We use bitmasks so the loop is done only once and not on every aura check below.
|
|
||||||
if (m_spellInfo.HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
|
||||||
{
|
{
|
||||||
foreach (SpellEffectInfo effect in GetEffects())
|
usableWhileStunned = true;
|
||||||
{
|
usableWhileFeared = true;
|
||||||
if (effect == null)
|
usableWhileConfused = true;
|
||||||
continue;
|
|
||||||
|
|
||||||
if (effect.ApplyAuraName == AuraType.SchoolImmunity)
|
|
||||||
school_immune |= effect.MiscValue;
|
|
||||||
else if (effect.ApplyAuraName == AuraType.MechanicImmunity)
|
|
||||||
mechanic_immune |= (uint)(1 << effect.MiscValue);
|
|
||||||
else if (effect.ApplyAuraName == AuraType.DispelImmunity)
|
|
||||||
dispel_immune |= SpellInfo.GetDispelMask((DispelType)effect.MiscValue);
|
|
||||||
}
|
|
||||||
// immune movement impairment and loss of control
|
|
||||||
if (m_spellInfo.Id == 42292 || m_spellInfo.Id == 59752 || m_spellInfo.Id == 19574 || m_spellInfo.Id == 53490)
|
|
||||||
mechanic_immune = (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool usableInStun = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileStunned);
|
|
||||||
|
|
||||||
// Check whether the cast should be prevented by any state you might have.
|
// Check whether the cast should be prevented by any state you might have.
|
||||||
SpellCastResult prevented_reason = SpellCastResult.SpellCastOk;
|
SpellCastResult result = SpellCastResult.SpellCastOk;
|
||||||
// Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
|
// Get unit state
|
||||||
UnitFlags unitflag = (UnitFlags)m_caster.GetUInt32Value(UnitFields.Flags); // Get unit state
|
UnitFlags unitflag = (UnitFlags)m_caster.GetUInt32Value(UnitFields.Flags);
|
||||||
if (Convert.ToBoolean(unitflag & UnitFlags.Stunned))
|
if (!m_caster.GetCharmerGUID().IsEmpty())
|
||||||
{
|
{
|
||||||
// spell is usable while stunned, check if caster has allowed stun auras, another stun types must prevent cast spell
|
Unit charmer = m_caster.GetCharmer();
|
||||||
if (usableInStun)
|
if (charmer)
|
||||||
{
|
if (charmer.GetUnitBeingMoved() != m_caster && CheckCasterNotImmunedCharmAuras(ref param1))
|
||||||
uint allowedStunMask =
|
result = SpellCastResult.Charmed;
|
||||||
1 << (int)Mechanics.Stun
|
|
||||||
| 1 << (int)Mechanics.Freeze
|
|
||||||
| 1 << (int)Mechanics.Sapped
|
|
||||||
| 1 << (int)Mechanics.Sleep;
|
|
||||||
|
|
||||||
bool foundNotStun = false;
|
|
||||||
var stunAuras = m_caster.GetAuraEffectsByType(AuraType.ModStun);
|
|
||||||
foreach (var auraEffect in stunAuras)
|
|
||||||
{
|
|
||||||
uint mechanicMask = auraEffect.GetSpellInfo().GetAllEffectsMechanicMask();
|
|
||||||
if (mechanicMask != 0 && !Convert.ToBoolean(mechanicMask & allowedStunMask))
|
|
||||||
{
|
|
||||||
foundNotStun = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (foundNotStun)
|
|
||||||
prevented_reason = SpellCastResult.Stunned;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
prevented_reason = SpellCastResult.Stunned;
|
|
||||||
}
|
}
|
||||||
else if (unitflag.HasAnyFlag(UnitFlags.Confused) && !m_spellInfo.HasAttribute(SpellAttr5.UsableWhileConfused))
|
else if (unitflag.HasAnyFlag(UnitFlags.Stunned) && !usableWhileStunned && CheckCasterNotImmunedStunAuras(ref param1))
|
||||||
prevented_reason = SpellCastResult.Confused;
|
result = SpellCastResult.Stunned;
|
||||||
else if (unitflag.HasAnyFlag(UnitFlags.Fleeing) && !m_spellInfo.HasAttribute(SpellAttr5.UsableWhileFeared))
|
else if (unitflag.HasAnyFlag(UnitFlags.Silenced) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence) && CheckCasterNotImmunedSilenceAuras(ref param1))
|
||||||
prevented_reason = SpellCastResult.Fleeing;
|
result = SpellCastResult.Silenced;
|
||||||
else if (unitflag.HasAnyFlag(UnitFlags.Silenced) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence))
|
else if (unitflag.HasAnyFlag(UnitFlags.Pacified) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify) && CheckCasterNotImmunedPacifyAuras(ref param1))
|
||||||
prevented_reason = SpellCastResult.Silenced;
|
result = SpellCastResult.Pacified;
|
||||||
else if (unitflag.HasAnyFlag(UnitFlags.Pacified) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify))
|
else if (unitflag.HasAnyFlag(UnitFlags.Fleeing) && !usableWhileFeared && CheckCasterNotImmunedFearAuras(ref param1))
|
||||||
prevented_reason = SpellCastResult.Pacified;
|
result = SpellCastResult.Fleeing;
|
||||||
|
else if (unitflag.HasAnyFlag(UnitFlags.Confused) && !usableWhileConfused && CheckCasterNotImmunedDisorientAuras(ref param1))
|
||||||
|
result = SpellCastResult.Confused;
|
||||||
else if (m_caster.HasFlag(UnitFields.Flags2, UnitFlags2.NoActions) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.NoActions))
|
else if (m_caster.HasFlag(UnitFields.Flags2, UnitFlags2.NoActions) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.NoActions))
|
||||||
prevented_reason = SpellCastResult.NoActions;
|
result = SpellCastResult.NoActions;
|
||||||
|
|
||||||
// Attr must make flag drop spell totally immune from all effects
|
// Attr must make flag drop spell totally immune from all effects
|
||||||
if (prevented_reason != SpellCastResult.SpellCastOk)
|
if (result != SpellCastResult.SpellCastOk)
|
||||||
{
|
return (param1 != 0) ? SpellCastResult.PreventedByMechanic : result;
|
||||||
if (school_immune != 0 || mechanic_immune != 0 || dispel_immune != 0)
|
|
||||||
{
|
|
||||||
//Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
|
|
||||||
foreach (var pair in m_caster.GetAppliedAuras())
|
|
||||||
{
|
|
||||||
Aura aura = pair.Value.GetBase();
|
|
||||||
SpellInfo auraInfo = aura.GetSpellInfo();
|
|
||||||
if (Convert.ToBoolean(auraInfo.GetAllEffectsMechanicMask() & mechanic_immune))
|
|
||||||
continue;
|
|
||||||
if (Convert.ToBoolean((int)auraInfo.GetSchoolMask() & school_immune) && !auraInfo.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune))
|
|
||||||
continue;
|
|
||||||
if (Convert.ToBoolean((int)auraInfo.GetDispelMask() & dispel_immune))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//Make a second check for spell failed so the right SPELL_FAILED message is returned.
|
|
||||||
//That is needed when your casting is prevented by multiple states and you are only immune to some of them.
|
|
||||||
foreach (SpellEffectInfo effect in GetEffects())
|
|
||||||
{
|
|
||||||
if (effect == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
AuraEffect part = aura.GetEffect(effect.EffectIndex);
|
|
||||||
if (part != null)
|
|
||||||
{
|
|
||||||
switch (part.GetAuraType())
|
|
||||||
{
|
|
||||||
case AuraType.ModStun:
|
|
||||||
if (!usableInStun || !Convert.ToBoolean(auraInfo.GetAllEffectsMechanicMask() & (1 << (int)Mechanics.Stun)))
|
|
||||||
return SpellCastResult.Stunned;
|
|
||||||
break;
|
|
||||||
case AuraType.ModConfuse:
|
|
||||||
if (!m_spellInfo.HasAttribute(SpellAttr5.UsableWhileConfused))
|
|
||||||
return SpellCastResult.Confused;
|
|
||||||
break;
|
|
||||||
case AuraType.ModFear:
|
|
||||||
if (!m_spellInfo.HasAttribute(SpellAttr5.UsableWhileFeared))
|
|
||||||
return SpellCastResult.Fleeing;
|
|
||||||
break;
|
|
||||||
case AuraType.ModSilence:
|
|
||||||
case AuraType.ModPacify:
|
|
||||||
case AuraType.ModPacifySilence:
|
|
||||||
if (m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify))
|
|
||||||
return SpellCastResult.Pacified;
|
|
||||||
else if (m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence))
|
|
||||||
return SpellCastResult.Silenced;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
|
|
||||||
else
|
|
||||||
return prevented_reason;
|
|
||||||
}
|
|
||||||
return SpellCastResult.SpellCastOk;
|
return SpellCastResult.SpellCastOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// based on sub_00804430 from 12340 client
|
||||||
|
bool CheckCasterHasNotImmunedAuraType(AuraType auraType, ref uint param1)
|
||||||
|
{
|
||||||
|
// Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
|
||||||
|
var auraEffects = m_caster.GetAuraEffectsByType(auraType);
|
||||||
|
if (auraEffects.Empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (AuraEffect aurEff in auraEffects)
|
||||||
|
{
|
||||||
|
if (m_spellInfo.CanSpellCastOverrideAuraEffect(aurEff))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
param1 = (uint)aurEff.GetSpellEffectInfo().Mechanic;
|
||||||
|
if (param1 == 0)
|
||||||
|
param1 = (uint)aurEff.GetSpellInfo().Mechanic;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckCasterNotImmunedCharmAuras(ref uint param1)
|
||||||
|
{
|
||||||
|
return CheckCasterHasNotImmunedAuraType(AuraType.ModCharm, ref param1) ||
|
||||||
|
CheckCasterHasNotImmunedAuraType(AuraType.AoeCharm, ref param1) ||
|
||||||
|
CheckCasterHasNotImmunedAuraType(AuraType.ModPossess, ref param1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckCasterNotImmunedStunAuras(ref uint param1)
|
||||||
|
{
|
||||||
|
return CheckCasterHasNotImmunedAuraType(AuraType.ModStun, ref param1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckCasterNotImmunedSilenceAuras(ref uint param1)
|
||||||
|
{
|
||||||
|
return CheckCasterHasNotImmunedAuraType(AuraType.ModSilence, ref param1) ||
|
||||||
|
CheckCasterHasNotImmunedAuraType(AuraType.ModPacifySilence, ref param1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckCasterNotImmunedPacifyAuras(ref uint param1)
|
||||||
|
{
|
||||||
|
return CheckCasterHasNotImmunedAuraType(AuraType.ModPacify, ref param1) ||
|
||||||
|
CheckCasterHasNotImmunedAuraType(AuraType.ModPacifySilence, ref param1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckCasterNotImmunedFearAuras(ref uint param1)
|
||||||
|
{
|
||||||
|
return CheckCasterHasNotImmunedAuraType(AuraType.ModFear, ref param1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckCasterNotImmunedDisorientAuras(ref uint param1)
|
||||||
|
{
|
||||||
|
return CheckCasterHasNotImmunedAuraType(AuraType.ModConfuse, ref param1);
|
||||||
|
}
|
||||||
|
|
||||||
SpellCastResult CheckArenaAndRatedBattlegroundCastRules()
|
SpellCastResult CheckArenaAndRatedBattlegroundCastRules()
|
||||||
{
|
{
|
||||||
bool isRatedBattleground = false; // NYI
|
bool isRatedBattleground = false; // NYI
|
||||||
@@ -5727,13 +5777,15 @@ namespace Game.Spells
|
|||||||
return SpellCastResult.SpellCastOk;
|
return SpellCastResult.SpellCastOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpellCastResult CheckItems()
|
SpellCastResult CheckItems(ref uint param1, ref uint param2)
|
||||||
{
|
{
|
||||||
Player player = m_caster.ToPlayer();
|
Player player = m_caster.ToPlayer();
|
||||||
|
|
||||||
if (!player)
|
if (!player)
|
||||||
return SpellCastResult.SpellCastOk;
|
return SpellCastResult.SpellCastOk;
|
||||||
|
|
||||||
|
if (m_spellInfo.HasAttribute(SpellAttr2.IgnoreItemCheck))
|
||||||
|
return SpellCastResult.SpellCastOk;
|
||||||
|
|
||||||
if (m_CastItem == null)
|
if (m_CastItem == null)
|
||||||
{
|
{
|
||||||
if (!m_castItemGUID.IsEmpty())
|
if (!m_castItemGUID.IsEmpty())
|
||||||
@@ -5809,13 +5861,11 @@ namespace Game.Spells
|
|||||||
// check target item
|
// check target item
|
||||||
if (!m_targets.GetItemTargetGUID().IsEmpty())
|
if (!m_targets.GetItemTargetGUID().IsEmpty())
|
||||||
{
|
{
|
||||||
if (!m_caster.IsTypeId(TypeId.Player))
|
Item item = m_targets.GetItemTarget();
|
||||||
return SpellCastResult.BadTargets;
|
if (item == null)
|
||||||
|
|
||||||
if (m_targets.GetItemTarget() == null)
|
|
||||||
return SpellCastResult.ItemGone;
|
return SpellCastResult.ItemGone;
|
||||||
|
|
||||||
if (!m_targets.GetItemTarget().IsFitToSpellRequirements(m_spellInfo))
|
if (!item.IsFitToSpellRequirements(m_spellInfo))
|
||||||
return SpellCastResult.EquippedItemClass;
|
return SpellCastResult.EquippedItemClass;
|
||||||
}
|
}
|
||||||
// if not item target then required item must be equipped
|
// if not item target then required item must be equipped
|
||||||
@@ -5868,7 +5918,10 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!player.HasItemCount(itemid, itemcount))
|
if (!player.HasItemCount(itemid, itemcount))
|
||||||
|
{
|
||||||
|
param1 = itemid;
|
||||||
return SpellCastResult.Reagents;
|
return SpellCastResult.Reagents;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6073,21 +6126,26 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
case SpellEffectName.Prospecting:
|
case SpellEffectName.Prospecting:
|
||||||
{
|
{
|
||||||
if (m_targets.GetItemTarget() == null)
|
Item item = m_targets.GetItemTarget();
|
||||||
|
if (!item)
|
||||||
return SpellCastResult.CantBeProspected;
|
return SpellCastResult.CantBeProspected;
|
||||||
//ensure item is a prospectable ore
|
//ensure item is a prospectable ore
|
||||||
if (!Convert.ToBoolean(m_targets.GetItemTarget().GetTemplate().GetFlags() & ItemFlags.IsProspectable))
|
if (!Convert.ToBoolean(item.GetTemplate().GetFlags() & ItemFlags.IsProspectable))
|
||||||
return SpellCastResult.CantBeProspected;
|
return SpellCastResult.CantBeProspected;
|
||||||
//prevent prospecting in trade slot
|
//prevent prospecting in trade slot
|
||||||
if (m_targets.GetItemTarget().GetOwnerGUID() != m_caster.GetGUID())
|
if (item.GetOwnerGUID() != m_caster.GetGUID())
|
||||||
return SpellCastResult.CantBeProspected;
|
return SpellCastResult.CantBeProspected;
|
||||||
//Check for enough skill in jewelcrafting
|
//Check for enough skill in jewelcrafting
|
||||||
uint item_prospectingskilllevel = m_targets.GetItemTarget().GetTemplate().GetRequiredSkillRank();
|
uint item_prospectingskilllevel = item.GetTemplate().GetRequiredSkillRank();
|
||||||
if (item_prospectingskilllevel > player.GetSkillValue(SkillType.Jewelcrafting))
|
if (item_prospectingskilllevel > player.GetSkillValue(SkillType.Jewelcrafting))
|
||||||
return SpellCastResult.LowCastlevel;
|
return SpellCastResult.LowCastlevel;
|
||||||
//make sure the player has the required ores in inventory
|
//make sure the player has the required ores in inventory
|
||||||
if (m_targets.GetItemTarget().GetCount() < 5)
|
if (item.GetCount() < 5)
|
||||||
|
{
|
||||||
|
param1 = item.GetEntry();
|
||||||
|
param2 = 5;
|
||||||
return SpellCastResult.NeedMoreItems;
|
return SpellCastResult.NeedMoreItems;
|
||||||
|
}
|
||||||
|
|
||||||
if (!LootStorage.Prospecting.HaveLootFor(m_targets.GetItemTargetEntry()))
|
if (!LootStorage.Prospecting.HaveLootFor(m_targets.GetItemTargetEntry()))
|
||||||
return SpellCastResult.CantBeProspected;
|
return SpellCastResult.CantBeProspected;
|
||||||
@@ -6096,21 +6154,26 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
case SpellEffectName.Milling:
|
case SpellEffectName.Milling:
|
||||||
{
|
{
|
||||||
if (m_targets.GetItemTarget() == null)
|
Item item = m_targets.GetItemTarget();
|
||||||
|
if (!item)
|
||||||
return SpellCastResult.CantBeMilled;
|
return SpellCastResult.CantBeMilled;
|
||||||
//ensure item is a millable herb
|
//ensure item is a millable herb
|
||||||
if (!(m_targets.GetItemTarget().GetTemplate().GetFlags().HasAnyFlag(ItemFlags.IsMillable)))
|
if (!(item.GetTemplate().GetFlags().HasAnyFlag(ItemFlags.IsMillable)))
|
||||||
return SpellCastResult.CantBeMilled;
|
return SpellCastResult.CantBeMilled;
|
||||||
//prevent milling in trade slot
|
//prevent milling in trade slot
|
||||||
if (m_targets.GetItemTarget().GetOwnerGUID() != m_caster.GetGUID())
|
if (item.GetOwnerGUID() != m_caster.GetGUID())
|
||||||
return SpellCastResult.CantBeMilled;
|
return SpellCastResult.CantBeMilled;
|
||||||
//Check for enough skill in inscription
|
//Check for enough skill in inscription
|
||||||
uint item_millingskilllevel = m_targets.GetItemTarget().GetTemplate().GetRequiredSkillRank();
|
uint item_millingskilllevel = item.GetTemplate().GetRequiredSkillRank();
|
||||||
if (item_millingskilllevel > player.GetSkillValue(SkillType.Inscription))
|
if (item_millingskilllevel > player.GetSkillValue(SkillType.Inscription))
|
||||||
return SpellCastResult.LowCastlevel;
|
return SpellCastResult.LowCastlevel;
|
||||||
//make sure the player has the required herbs in inventory
|
//make sure the player has the required herbs in inventory
|
||||||
if (m_targets.GetItemTarget().GetCount() < 5)
|
if (item.GetCount() < 5)
|
||||||
|
{
|
||||||
|
param1 = item.GetEntry();
|
||||||
|
param2 = 5;
|
||||||
return SpellCastResult.NeedMoreItems;
|
return SpellCastResult.NeedMoreItems;
|
||||||
|
}
|
||||||
|
|
||||||
if (!LootStorage.Milling.HaveLootFor(m_targets.GetItemTargetEntry()))
|
if (!LootStorage.Milling.HaveLootFor(m_targets.GetItemTargetEntry()))
|
||||||
return SpellCastResult.CantBeMilled;
|
return SpellCastResult.CantBeMilled;
|
||||||
@@ -7145,7 +7208,7 @@ namespace Game.Spells
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator bool (Spell spell)
|
public static implicit operator bool(Spell spell)
|
||||||
{
|
{
|
||||||
return spell != null;
|
return spell != null;
|
||||||
}
|
}
|
||||||
|
|||||||
+507
-14
@@ -638,32 +638,35 @@ namespace Game.Spells
|
|||||||
return IsAffected(affectSpell.SpellFamilyName, mod.mask);
|
return IsAffected(affectSpell.SpellFamilyName, mod.mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanPierceImmuneAura(SpellInfo aura)
|
public bool CanPierceImmuneAura(SpellInfo auraSpellInfo)
|
||||||
{
|
{
|
||||||
|
// aura can't be pierced
|
||||||
|
if (auraSpellInfo == null || auraSpellInfo.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||||
|
return false;
|
||||||
|
|
||||||
// these spells pierce all avalible spells (Resurrection Sickness for example)
|
// these spells pierce all avalible spells (Resurrection Sickness for example)
|
||||||
if (HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
if (HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// these spells (Cyclone for example) can pierce all... | ...but not these (Divine shield, Ice block, Cyclone and Banish for example)
|
// Dispels other auras on immunity, check if this spell makes the unit immune to aura
|
||||||
if (HasAttribute(SpellAttr1.UnaffectedBySchoolImmune)
|
if (HasAttribute(SpellAttr1.DispelAurasOnImmunity) && CanSpellProvideImmunityAgainstAura(auraSpellInfo))
|
||||||
&& !(aura != null && (aura.Mechanic == Mechanics.Immune_Shield || aura.Mechanic == Mechanics.Invulnerability || aura.Mechanic == Mechanics.Banish)))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanDispelAura(SpellInfo aura)
|
public bool CanDispelAura(SpellInfo auraSpellInfo)
|
||||||
{
|
{
|
||||||
// These spells (like Mass Dispel) can dispell all auras
|
|
||||||
if (HasAttribute(SpellAttr0.UnaffectedByInvulnerability) && !aura.IsDeathPersistent())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// These auras (like Divine Shield) can't be dispelled
|
// These auras (like Divine Shield) can't be dispelled
|
||||||
if (aura.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
if (auraSpellInfo.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// These spells (like Mass Dispel) can dispel all auras
|
||||||
|
if (HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||||
|
return true;
|
||||||
|
|
||||||
// These auras (Cyclone for example) are not dispelable
|
// These auras (Cyclone for example) are not dispelable
|
||||||
if (aura.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune))
|
if (auraSpellInfo.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune) || auraSpellInfo.HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1204,7 +1207,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
// if target is magnet (i.e Grounding Totem) the check is skipped
|
// if target is magnet (i.e Grounding Totem) the check is skipped
|
||||||
//if (target.IsMagnet())
|
//if (target.IsMagnet())
|
||||||
//return true;
|
//return true;
|
||||||
|
|
||||||
uint creatureType = target.GetCreatureTypeMask();
|
uint creatureType = target.GetCreatureTypeMask();
|
||||||
return TargetCreatureType == 0 || creatureType == 0 || Convert.ToBoolean(creatureType & TargetCreatureType);
|
return TargetCreatureType == 0 || creatureType == 0 || Convert.ToBoolean(creatureType & TargetCreatureType);
|
||||||
@@ -2017,6 +2020,478 @@ namespace Game.Spells
|
|||||||
return 8 * Time.InMilliseconds;
|
return 8 * Time.InMilliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void _LoadImmunityInfo()
|
||||||
|
{
|
||||||
|
var loadImmunityInfoFn = new Action<SpellEffectInfo>(effectInfo =>
|
||||||
|
{
|
||||||
|
uint schoolImmunityMask = 0;
|
||||||
|
uint applyHarmfulAuraImmunityMask = 0;
|
||||||
|
uint mechanicImmunityMask = 0;
|
||||||
|
uint dispelImmunity = 0;
|
||||||
|
uint damageImmunityMask = 0;
|
||||||
|
|
||||||
|
int miscVal = effectInfo.MiscValue;
|
||||||
|
int amount = effectInfo.CalcValue();
|
||||||
|
|
||||||
|
ImmunityInfo immuneInfo = effectInfo.GetImmunityInfo();
|
||||||
|
|
||||||
|
switch (effectInfo.ApplyAuraName)
|
||||||
|
{
|
||||||
|
case AuraType.MechanicImmunityMask:
|
||||||
|
{
|
||||||
|
switch (miscVal)
|
||||||
|
{
|
||||||
|
case 96: // Free Friend, Uncontrollable Frenzy, Warlord's Presence
|
||||||
|
{
|
||||||
|
mechanicImmunityMask |= (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
||||||
|
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDecreaseSpeed);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModConfuse);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModFear);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1615: // Incite Rage, Wolf Spirit, Overload, Lightning Tendrils
|
||||||
|
{
|
||||||
|
switch (Id)
|
||||||
|
{
|
||||||
|
case 43292: // Incite Rage
|
||||||
|
case 49172: // Wolf Spirit
|
||||||
|
mechanicImmunityMask |= (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
||||||
|
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDecreaseSpeed);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModConfuse);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModFear);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot2);
|
||||||
|
goto case 61869;
|
||||||
|
// no break intended
|
||||||
|
case 61869: // Overload
|
||||||
|
case 63481:
|
||||||
|
case 61887: // Lightning Tendrils
|
||||||
|
case 63486:
|
||||||
|
mechanicImmunityMask |= (1 << (int)Mechanics.Interrupt) | (1 << (int)Mechanics.Silence);
|
||||||
|
|
||||||
|
immuneInfo.SpellEffectImmune.Add(SpellEffectName.KnockBack);
|
||||||
|
immuneInfo.SpellEffectImmune.Add(SpellEffectName.KnockBackDest);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 679: // Mind Control, Avenging Fury
|
||||||
|
{
|
||||||
|
if (Id == 57742) // Avenging Fury
|
||||||
|
{
|
||||||
|
mechanicImmunityMask |= (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
||||||
|
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDecreaseSpeed);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModConfuse);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModFear);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1557: // Startling Roar, Warlord Roar, Break Bonds, Stormshield
|
||||||
|
{
|
||||||
|
if (Id == 64187) // Stormshield
|
||||||
|
{
|
||||||
|
mechanicImmunityMask |= (1 << (int)Mechanics.Stun);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mechanicImmunityMask |= (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
||||||
|
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDecreaseSpeed);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModConfuse);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModFear);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1614: // Fixate
|
||||||
|
case 1694: // Fixated, Lightning Tendrils
|
||||||
|
{
|
||||||
|
immuneInfo.SpellEffectImmune.Add(SpellEffectName.AttackMe);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModTaunt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1630: // Fervor, Berserk
|
||||||
|
{
|
||||||
|
if (Id == 64112) // Berserk
|
||||||
|
{
|
||||||
|
immuneInfo.SpellEffectImmune.Add(SpellEffectName.AttackMe);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModTaunt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mechanicImmunityMask |= (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
||||||
|
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDecreaseSpeed);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModConfuse);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModFear);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 477: // Bladestorm
|
||||||
|
case 1733: // Bladestorm, Killing Spree
|
||||||
|
{
|
||||||
|
if (amount == 0)
|
||||||
|
{
|
||||||
|
mechanicImmunityMask |= (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
||||||
|
|
||||||
|
immuneInfo.SpellEffectImmune.Add(SpellEffectName.KnockBack);
|
||||||
|
immuneInfo.SpellEffectImmune.Add(SpellEffectName.KnockBackDest);
|
||||||
|
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDecreaseSpeed);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModConfuse);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModFear);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 878: // Whirlwind, Fog of Corruption, Determination
|
||||||
|
{
|
||||||
|
if (Id == 66092) // Determination
|
||||||
|
{
|
||||||
|
mechanicImmunityMask |= (1 << (int)Mechanics.Snare) | (1 << (int)Mechanics.Stun)
|
||||||
|
| (1 << (int)Mechanics.Disoriented) | (1 << (int)Mechanics.Freeze);
|
||||||
|
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDecreaseSpeed);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (immuneInfo.AuraTypeImmune.Empty())
|
||||||
|
{
|
||||||
|
if (miscVal.HasAnyFlag(1 << 10))
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModStun);
|
||||||
|
if (miscVal.HasAnyFlag(1 << 1))
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.Transform);
|
||||||
|
|
||||||
|
// These flag can be recognized wrong:
|
||||||
|
if (miscVal.HasAnyFlag(1 << 6))
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDecreaseSpeed);
|
||||||
|
if (miscVal.HasAnyFlag(1 << 0))
|
||||||
|
{
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot);
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModRoot2);
|
||||||
|
}
|
||||||
|
if (miscVal.HasAnyFlag(1 << 2))
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModConfuse);
|
||||||
|
if (miscVal.HasAnyFlag(1 << 9))
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModFear);
|
||||||
|
if (miscVal.HasAnyFlag(1 << 7))
|
||||||
|
immuneInfo.AuraTypeImmune.Add(AuraType.ModDisarm);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuraType.MechanicImmunity:
|
||||||
|
{
|
||||||
|
switch (Id)
|
||||||
|
{
|
||||||
|
case 34471: // The Beast Within
|
||||||
|
case 19574: // Bestial Wrath
|
||||||
|
case 42292: // PvP trinket
|
||||||
|
case 46227: // Medallion of Immunity
|
||||||
|
case 59752: // Every Man for Himself
|
||||||
|
case 53490: // Bullheaded
|
||||||
|
case 65547: // PvP Trinket
|
||||||
|
case 134946: // Supremacy of the Alliance
|
||||||
|
case 134956: // Supremacy of the Horde
|
||||||
|
case 195710: // Honorable Medallion
|
||||||
|
case 208683: // Gladiator's Medallion
|
||||||
|
mechanicImmunityMask |= (uint)Mechanics.ImmuneToMovementImpairmentAndLossControlMask;
|
||||||
|
break;
|
||||||
|
case 54508: // Demonic Empowerment
|
||||||
|
mechanicImmunityMask |= (1 << (int)Mechanics.Snare) | (1 << (int)Mechanics.Root) | (1 << (int)Mechanics.Stun);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (miscVal < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mechanicImmunityMask |= 1u << miscVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuraType.EffectImmunity:
|
||||||
|
{
|
||||||
|
immuneInfo.SpellEffectImmune.Add((SpellEffectName)miscVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuraType.StateImmunity:
|
||||||
|
{
|
||||||
|
immuneInfo.AuraTypeImmune.Add((AuraType)miscVal);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuraType.SchoolImmunity:
|
||||||
|
{
|
||||||
|
schoolImmunityMask |= (uint)miscVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuraType.ModImmuneAuraApplySchool:
|
||||||
|
{
|
||||||
|
applyHarmfulAuraImmunityMask |= (uint)miscVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuraType.DamageImmunity:
|
||||||
|
{
|
||||||
|
damageImmunityMask |= (uint)miscVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuraType.DispelImmunity:
|
||||||
|
{
|
||||||
|
dispelImmunity = (uint)miscVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
immuneInfo.SchoolImmuneMask = schoolImmunityMask;
|
||||||
|
immuneInfo.ApplyHarmfulAuraImmuneMask = applyHarmfulAuraImmunityMask;
|
||||||
|
immuneInfo.MechanicImmuneMask = mechanicImmunityMask;
|
||||||
|
immuneInfo.DispelImmune = dispelImmunity;
|
||||||
|
immuneInfo.DamageSchoolMask = damageImmunityMask;
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var effects in _effects)
|
||||||
|
{
|
||||||
|
foreach (SpellEffectInfo effect in effects.Value)
|
||||||
|
{
|
||||||
|
if (effect == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
loadImmunityInfoFn(effect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyAllSpellImmunitiesTo(Unit target, SpellEffectInfo effect, bool apply)
|
||||||
|
{
|
||||||
|
ImmunityInfo immuneInfo = effect.GetImmunityInfo();
|
||||||
|
|
||||||
|
uint schoolImmunity = immuneInfo.SchoolImmuneMask;
|
||||||
|
if (schoolImmunity != 0)
|
||||||
|
{
|
||||||
|
target.ApplySpellImmune(Id, SpellImmunity.School, schoolImmunity, apply);
|
||||||
|
|
||||||
|
if (apply && HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
||||||
|
{
|
||||||
|
target.RemoveAppliedAuras(aurApp =>
|
||||||
|
{
|
||||||
|
SpellInfo auraSpellInfo = aurApp.GetBase().GetSpellInfo();
|
||||||
|
return (((uint)auraSpellInfo.GetSchoolMask() & schoolImmunity) != 0 && // Check for school mask
|
||||||
|
CanDispelAura(auraSpellInfo) &&
|
||||||
|
(IsPositive() != aurApp.IsPositive()) && // Check spell vs aura possitivity
|
||||||
|
!auraSpellInfo.IsPassive() && // Don't remove passive auras
|
||||||
|
auraSpellInfo.Id != Id); // Don't remove self
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint mechanicImmunity = immuneInfo.MechanicImmuneMask;
|
||||||
|
if (mechanicImmunity != 0)
|
||||||
|
{
|
||||||
|
for (uint i = 0; i < (int)Mechanics.Max; ++i)
|
||||||
|
if (Convert.ToBoolean(mechanicImmunity & (1 << (int)i)))
|
||||||
|
target.ApplySpellImmune(Id, SpellImmunity.Mechanic, i, apply);
|
||||||
|
|
||||||
|
if (apply && HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
||||||
|
target.RemoveAurasWithMechanic(mechanicImmunity, AuraRemoveMode.Default, Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint dispelImmunity = immuneInfo.DispelImmune;
|
||||||
|
if (dispelImmunity != 0)
|
||||||
|
{
|
||||||
|
target.ApplySpellImmune(Id, SpellImmunity.Dispel, dispelImmunity, apply);
|
||||||
|
|
||||||
|
if (apply && HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
||||||
|
{
|
||||||
|
target.RemoveAppliedAuras(aurApp =>
|
||||||
|
{
|
||||||
|
SpellInfo spellInfo = aurApp.GetBase().GetSpellInfo();
|
||||||
|
if ((uint)spellInfo.Dispel == dispelImmunity)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint damageImmunity = immuneInfo.DamageSchoolMask;
|
||||||
|
if (damageImmunity != 0)
|
||||||
|
target.ApplySpellImmune(Id, SpellImmunity.Damage, damageImmunity, apply);
|
||||||
|
|
||||||
|
foreach (AuraType auraType in immuneInfo.AuraTypeImmune)
|
||||||
|
{
|
||||||
|
target.ApplySpellImmune(Id, SpellImmunity.State, auraType, apply);
|
||||||
|
if (apply && HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
||||||
|
target.RemoveAurasByType(auraType);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (SpellEffectName effectType in immuneInfo.SpellEffectImmune)
|
||||||
|
target.ApplySpellImmune(Id, SpellImmunity.Effect, effectType, apply);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanSpellProvideImmunityAgainstAura(SpellInfo auraSpellInfo)
|
||||||
|
{
|
||||||
|
if (auraSpellInfo == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (SpellEffectInfo effectInfo in GetEffectsForDifficulty(Difficulty.None))
|
||||||
|
{
|
||||||
|
if (effectInfo == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ImmunityInfo immuneInfo = effectInfo.GetImmunityInfo();
|
||||||
|
|
||||||
|
if (!auraSpellInfo.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune) && !auraSpellInfo.HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune))
|
||||||
|
{
|
||||||
|
uint schoolImmunity = immuneInfo.SchoolImmuneMask;
|
||||||
|
if (schoolImmunity != 0)
|
||||||
|
if (((uint)auraSpellInfo.SchoolMask & schoolImmunity) != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint mechanicImmunity = immuneInfo.MechanicImmuneMask;
|
||||||
|
if (mechanicImmunity != 0)
|
||||||
|
if ((mechanicImmunity & (1 << (int)auraSpellInfo.Mechanic)) != 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
uint dispelImmunity = immuneInfo.DispelImmune;
|
||||||
|
if (dispelImmunity != 0)
|
||||||
|
if ((uint)auraSpellInfo.Dispel == dispelImmunity)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
bool immuneToAllEffects = true;
|
||||||
|
foreach (SpellEffectInfo auraSpellEffectInfo in auraSpellInfo.GetEffectsForDifficulty(Difficulty.None))
|
||||||
|
{
|
||||||
|
if (auraSpellEffectInfo == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SpellEffectName effectName = auraSpellEffectInfo.Effect;
|
||||||
|
if (effectName == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!immuneInfo.SpellEffectImmune.Contains(effectName))
|
||||||
|
{
|
||||||
|
immuneToAllEffects = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint mechanic = (uint)auraSpellEffectInfo.Mechanic;
|
||||||
|
if (mechanic != 0)
|
||||||
|
{
|
||||||
|
if (!Convert.ToBoolean(immuneInfo.MechanicImmuneMask & (1 << (int)mechanic)))
|
||||||
|
{
|
||||||
|
immuneToAllEffects = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!auraSpellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
||||||
|
{
|
||||||
|
AuraType auraName = auraSpellEffectInfo.ApplyAuraName;
|
||||||
|
if (auraName != 0)
|
||||||
|
{
|
||||||
|
bool isImmuneToAuraEffectApply = false;
|
||||||
|
if (!immuneInfo.AuraTypeImmune.Contains(auraName))
|
||||||
|
isImmuneToAuraEffectApply = true;
|
||||||
|
|
||||||
|
if (!isImmuneToAuraEffectApply && !auraSpellInfo.IsPositiveEffect(auraSpellEffectInfo.EffectIndex) && !auraSpellInfo.HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune))
|
||||||
|
{
|
||||||
|
uint applyHarmfulAuraImmunityMask = immuneInfo.ApplyHarmfulAuraImmuneMask;
|
||||||
|
if (applyHarmfulAuraImmunityMask != 0)
|
||||||
|
if (((uint)auraSpellInfo.GetSchoolMask() & applyHarmfulAuraImmunityMask) != 0)
|
||||||
|
isImmuneToAuraEffectApply = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isImmuneToAuraEffectApply)
|
||||||
|
{
|
||||||
|
immuneToAllEffects = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (immuneToAllEffects)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// based on client sub_007FDFA0
|
||||||
|
public bool CanSpellCastOverrideAuraEffect(AuraEffect aurEff)
|
||||||
|
{
|
||||||
|
if (!HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (aurEff.GetSpellInfo().HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (SpellEffectInfo effectInfo in GetEffectsForDifficulty(Difficulty.None))
|
||||||
|
{
|
||||||
|
if (effectInfo == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (effectInfo.Effect != SpellEffectName.ApplyAura)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint miscValue = (uint)effectInfo.MiscValue;
|
||||||
|
switch (effectInfo.ApplyAuraName)
|
||||||
|
{
|
||||||
|
case AuraType.StateImmunity:
|
||||||
|
if (miscValue != (uint)aurEff.GetSpellEffectInfo().ApplyAuraName)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case AuraType.SchoolImmunity:
|
||||||
|
case AuraType.ModImmuneAuraApplySchool:
|
||||||
|
if (aurEff.GetSpellInfo().HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune) || !Convert.ToBoolean((uint)aurEff.GetSpellInfo().SchoolMask & miscValue))
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case AuraType.DispelImmunity:
|
||||||
|
if (miscValue != (uint)aurEff.GetSpellInfo().Dispel)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case AuraType.MechanicImmunity:
|
||||||
|
if (miscValue != (uint)aurEff.GetSpellInfo().Mechanic)
|
||||||
|
{
|
||||||
|
if (miscValue != (uint)aurEff.GetSpellEffectInfo().Mechanic)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public float GetMinRange(bool positive = false)
|
public float GetMinRange(bool positive = false)
|
||||||
{
|
{
|
||||||
if (RangeEntry == null)
|
if (RangeEntry == null)
|
||||||
@@ -2594,8 +3069,8 @@ namespace Game.Spells
|
|||||||
var visual = CliDB.SpellXSpellVisualStorage.LookupByKey(GetSpellXSpellVisualId(caster));
|
var visual = CliDB.SpellXSpellVisualStorage.LookupByKey(GetSpellXSpellVisualId(caster));
|
||||||
if (visual != null)
|
if (visual != null)
|
||||||
{
|
{
|
||||||
//if (visual->LowViolenceSpellVisualID && forPlayer->GetViolenceLevel() operator 2)
|
//if (visual.LowViolenceSpellVisualID && forPlayer.GetViolenceLevel() operator 2)
|
||||||
// return visual->LowViolenceSpellVisualID;
|
// return visual.LowViolenceSpellVisualID;
|
||||||
|
|
||||||
return visual.SpellVisualID;
|
return visual.SpellVisualID;
|
||||||
}
|
}
|
||||||
@@ -3213,6 +3688,8 @@ namespace Game.Spells
|
|||||||
Scaling.Coefficient = spellEffectScaling != null ? spellEffectScaling.Coefficient : 0.0f;
|
Scaling.Coefficient = spellEffectScaling != null ? spellEffectScaling.Coefficient : 0.0f;
|
||||||
Scaling.Variance = spellEffectScaling != null ? spellEffectScaling.Variance : 0.0f;
|
Scaling.Variance = spellEffectScaling != null ? spellEffectScaling.Variance : 0.0f;
|
||||||
Scaling.ResourceCoefficient = spellEffectScaling != null ? spellEffectScaling.ResourceCoefficient : 0.0f;
|
Scaling.ResourceCoefficient = spellEffectScaling != null ? spellEffectScaling.ResourceCoefficient : 0.0f;
|
||||||
|
|
||||||
|
_immunityInfo = new ImmunityInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsEffect()
|
public bool IsEffect()
|
||||||
@@ -3551,6 +4028,8 @@ namespace Game.Spells
|
|||||||
return _data[(int)Effect].UsedTargetObjectType;
|
return _data[(int)Effect].UsedTargetObjectType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImmunityInfo GetImmunityInfo() { return _immunityInfo; }
|
||||||
|
|
||||||
public class StaticData
|
public class StaticData
|
||||||
{
|
{
|
||||||
public StaticData(SpellEffectImplicitTargetTypes implicittarget, SpellTargetObjectTypes usedtarget)
|
public StaticData(SpellEffectImplicitTargetTypes implicittarget, SpellTargetObjectTypes usedtarget)
|
||||||
@@ -3853,6 +4332,8 @@ namespace Game.Spells
|
|||||||
public float BonusCoefficientFromAP;
|
public float BonusCoefficientFromAP;
|
||||||
public List<Condition> ImplicitTargetConditions;
|
public List<Condition> ImplicitTargetConditions;
|
||||||
public ScalingInfo Scaling;
|
public ScalingInfo Scaling;
|
||||||
|
|
||||||
|
ImmunityInfo _immunityInfo;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public struct ScalingInfo
|
public struct ScalingInfo
|
||||||
@@ -4208,5 +4689,17 @@ namespace Game.Spells
|
|||||||
public DiminishingLevels DiminishMaxLevel = DiminishingLevels.Immune;
|
public DiminishingLevels DiminishMaxLevel = DiminishingLevels.Immune;
|
||||||
public int DiminishDurationLimit;
|
public int DiminishDurationLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ImmunityInfo
|
||||||
|
{
|
||||||
|
public uint SchoolImmuneMask;
|
||||||
|
public uint ApplyHarmfulAuraImmuneMask;
|
||||||
|
public uint MechanicImmuneMask;
|
||||||
|
public uint DispelImmune;
|
||||||
|
public uint DamageSchoolMask;
|
||||||
|
|
||||||
|
public List<AuraType> AuraTypeImmune = new List<AuraType>();
|
||||||
|
public List<SpellEffectName> SpellEffectImmune = new List<SpellEffectName>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2815,6 +2815,21 @@ namespace Game.Entities
|
|||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded SpellInfo diminishing infos in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded SpellInfo diminishing infos in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadSpellInfoImmunities()
|
||||||
|
{
|
||||||
|
uint oldMSTime = Time.GetMSTime();
|
||||||
|
|
||||||
|
foreach (SpellInfo spellInfo in mSpellInfoMap.Values)
|
||||||
|
{
|
||||||
|
if (spellInfo == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
spellInfo._LoadImmunityInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.outInfo(LogFilter.ServerLoading, "Loaded SpellInfo immunity infos in {0} ms", Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
|
}
|
||||||
|
|
||||||
public void LoadPetFamilySpellsStore()
|
public void LoadPetFamilySpellsStore()
|
||||||
{
|
{
|
||||||
Dictionary<uint, SpellLevelsRecord> levelsBySpell = new Dictionary<uint, SpellLevelsRecord>();
|
Dictionary<uint, SpellLevelsRecord> levelsBySpell = new Dictionary<uint, SpellLevelsRecord>();
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace Scripts.Northrend
|
|||||||
public npc_mageguard_dalaran(Creature creature) : base(creature)
|
public npc_mageguard_dalaran(Creature creature) : base(creature)
|
||||||
{
|
{
|
||||||
creature.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
creature.SetFlag(UnitFields.Flags, UnitFlags.NonAttackable);
|
||||||
creature.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchools.Normal, true);
|
creature.ApplySpellImmune(0, SpellImmunity.Damage, (uint)SpellSchools.Normal, true);
|
||||||
creature.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
|
creature.ApplySpellImmune(0, SpellImmunity.Damage, SpellSchoolMask.Magic, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user