Core/Spell: revamp of immunities system
This commit is contained in:
@@ -302,6 +302,7 @@ namespace Framework.Constants
|
||||
Sapped = 30,
|
||||
Enraged = 31,
|
||||
Wounded = 32,
|
||||
Max = 33,
|
||||
|
||||
ImmuneToMovementImpairmentAndLossControlMask = ((1 << Charm) | (1 << Disoriented) |
|
||||
(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
|
||||
Unk24 = 0x1000000, // 24
|
||||
Unk25 = 0x2000000, // 25
|
||||
Unk26 = 0x4000000, // 26 Unaffected By School Immunity
|
||||
UnaffectedByAuraSchoolImmune = 0x4000000, // 26 Unaffected By School Immunity
|
||||
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
|
||||
TriggeredCanTriggerProc = 0x40000000, // 30 Spell Can Trigger Even If Triggered
|
||||
FoodBuff = 0x80000000 // 31 Food Or Drink Buff (Like Well Fed)
|
||||
@@ -1539,7 +1540,7 @@ namespace Framework.Constants
|
||||
Unk17 = 0x20000, // 17 Only 27965 (Suicide) Spell.
|
||||
HasChargeEffect = 0x40000, // 18 Only Spells That Have Charge Among Effects.
|
||||
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
|
||||
Unk22 = 0x400000, // 22
|
||||
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)
|
||||
{
|
||||
if (victim.IsImmunedToDamage(spellProto))
|
||||
{
|
||||
SendSpellDamageImmune(victim, spellProto.Id, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (victim.IsAIEnabled)
|
||||
victim.GetAI().DamageTaken(this, ref damage);
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Game.Entities
|
||||
//Spells
|
||||
protected Dictionary<CurrentSpellTypes, Spell> m_currentSpells = new Dictionary<CurrentSpellTypes, Spell>((int)CurrentSpellTypes.Max);
|
||||
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];
|
||||
protected int m_procDeep;
|
||||
bool m_AutoRepeatFirstCast;
|
||||
@@ -132,12 +132,6 @@ namespace Game.Entities
|
||||
ushort _meleeAnimKitId;
|
||||
}
|
||||
|
||||
public struct SpellImmune
|
||||
{
|
||||
public uint spellType;
|
||||
public uint spellId;
|
||||
}
|
||||
|
||||
public class DiminishingReturn
|
||||
{
|
||||
public DiminishingReturn() { }
|
||||
|
||||
@@ -1403,7 +1403,7 @@ namespace Game.Entities
|
||||
return GetPositionZ() - offset;
|
||||
}
|
||||
|
||||
Unit GetUnitBeingMoved()
|
||||
public Unit GetUnitBeingMoved()
|
||||
{
|
||||
Player player = ToPlayer();
|
||||
if (player)
|
||||
|
||||
@@ -794,20 +794,20 @@ namespace Game.Entities
|
||||
// Parry
|
||||
// For spells
|
||||
// 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
|
||||
if (victim.IsImmunedToSpell(spell))
|
||||
if (victim.IsImmunedToSpell(spellInfo))
|
||||
return SpellMissInfo.Immune;
|
||||
|
||||
// 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!
|
||||
if (spell.IsPositive()
|
||||
if (spellInfo.IsPositive()
|
||||
&& (!IsHostileTo(victim))) // prevent from affecting enemy by "positive" spell
|
||||
return SpellMissInfo.None;
|
||||
// Check for immune
|
||||
if (victim.IsImmunedToDamage(spell))
|
||||
return SpellMissInfo.Immune;
|
||||
|
||||
if (this == victim)
|
||||
return SpellMissInfo.None;
|
||||
@@ -822,22 +822,22 @@ namespace Game.Entities
|
||||
int reflectchance = victim.GetTotalAuraModifier(AuraType.ReflectSpells);
|
||||
var mReflectSpellsSchool = victim.GetAuraEffectsByType(AuraType.ReflectSpellsSchool);
|
||||
foreach (var eff in mReflectSpellsSchool)
|
||||
if (Convert.ToBoolean(eff.GetMiscValue() & (int)spell.GetSchoolMask()))
|
||||
if (Convert.ToBoolean(eff.GetMiscValue() & (int)spellInfo.GetSchoolMask()))
|
||||
reflectchance += eff.GetAmount();
|
||||
|
||||
if (reflectchance > 0 && RandomHelper.randChance(reflectchance))
|
||||
return SpellMissInfo.Reflect;
|
||||
}
|
||||
|
||||
switch (spell.DmgClass)
|
||||
switch (spellInfo.DmgClass)
|
||||
{
|
||||
case SpellDmgClass.Ranged:
|
||||
case SpellDmgClass.Melee:
|
||||
return MeleeSpellHitResult(victim, spell);
|
||||
return MeleeSpellHitResult(victim, spellInfo);
|
||||
case SpellDmgClass.None:
|
||||
return SpellMissInfo.None;
|
||||
case SpellDmgClass.Magic:
|
||||
return MagicSpellHitResult(victim, spell);
|
||||
return MagicSpellHitResult(victim, spellInfo);
|
||||
}
|
||||
return SpellMissInfo.None;
|
||||
}
|
||||
@@ -845,11 +845,6 @@ namespace Game.Entities
|
||||
// Melee based spells hit result calculations
|
||||
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;
|
||||
|
||||
// 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);
|
||||
if (spell)
|
||||
if (spell.getState() != SpellState.Finished)
|
||||
return spell.GetSpellInfo().HasAttribute(SpellAttr5.CanChannelWhenMoving) && spell.IsChannelActive();
|
||||
if (spell.getState() != SpellState.Finished && spell.IsChannelActive())
|
||||
if (!spell.GetSpellInfo().IsMoveAllowedChannel())
|
||||
return false;
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasBreakableByDamageAuraType(AuraType type, uint excludeAura)
|
||||
@@ -1552,24 +1548,35 @@ namespace Game.Entities
|
||||
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)
|
||||
{
|
||||
m_spellImmune[op].RemoveAll(p => p.spellType == Convert.ToUInt32(type));
|
||||
|
||||
SpellImmune Immune = new SpellImmune();
|
||||
Immune.spellId = spellId;
|
||||
Immune.spellType = Convert.ToUInt32(type);
|
||||
m_spellImmune.Add(op, Immune);
|
||||
m_spellImmune[(int)op].Add(type, spellId);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1581,28 +1588,27 @@ namespace Game.Entities
|
||||
return false;
|
||||
|
||||
// Single spell immunity.
|
||||
var idList = m_spellImmune.LookupByKey(SpellImmunity.Id);
|
||||
foreach (var immune in idList)
|
||||
if (immune.spellType == spellInfo.Id)
|
||||
return true;
|
||||
var idList = m_spellImmune[(int)SpellImmunity.Id];
|
||||
if (idList.ContainsKey(spellInfo.Id))
|
||||
return true;
|
||||
|
||||
if (spellInfo.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||
return false;
|
||||
|
||||
if (spellInfo.Dispel != 0)
|
||||
uint dispel = (uint)spellInfo.Dispel;
|
||||
if (dispel != 0)
|
||||
{
|
||||
var dispelList = m_spellImmune.LookupByKey(SpellImmunity.Dispel);
|
||||
foreach (var immune in dispelList)
|
||||
if (immune.spellType == (int)spellInfo.Dispel)
|
||||
return true;
|
||||
var dispelList = m_spellImmune[(int)SpellImmunity.Dispel];
|
||||
if (dispelList.ContainsKey(dispel))
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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);
|
||||
foreach (var immune in mechanicList)
|
||||
if (immune.spellType == (int)spellInfo.Mechanic)
|
||||
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
|
||||
if (mechanicList.ContainsKey(mechanic))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1611,7 +1617,7 @@ namespace Game.Entities
|
||||
{
|
||||
// State/effect immunities applied by aura expect full spell immunity
|
||||
// Ignore effects with mechanic, they are supposed to be checked separately
|
||||
if (effect == null || !effect.IsEffect())
|
||||
if (effect == null)
|
||||
continue;
|
||||
|
||||
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.
|
||||
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);
|
||||
foreach (var immune in schoolList)
|
||||
var schoolList = m_spellImmune[(int)SpellImmunity.School];
|
||||
foreach (var pair in schoolList)
|
||||
{
|
||||
SpellInfo immuneSpellInfo = Global.SpellMgr.GetSpellInfo(immune.spellId);
|
||||
if (Convert.ToBoolean(immune.spellType & (uint)spellInfo.GetSchoolMask())
|
||||
SpellInfo immuneSpellInfo = Global.SpellMgr.GetSpellInfo(pair.Value);
|
||||
if (Convert.ToBoolean(pair.Key & (uint)spellInfo.GetSchoolMask())
|
||||
&& !(immuneSpellInfo != null && immuneSpellInfo.IsPositive() && spellInfo.IsPositive())
|
||||
&& !spellInfo.CanPierceImmuneAura(immuneSpellInfo))
|
||||
return true;
|
||||
@@ -1642,18 +1648,18 @@ namespace Game.Entities
|
||||
public uint GetSchoolImmunityMask()
|
||||
{
|
||||
uint mask = 0;
|
||||
var mechanicList = m_spellImmune.LookupByKey(SpellImmunity.School);
|
||||
foreach (var spell in mechanicList)
|
||||
mask |= spell.spellType;
|
||||
var mechanicList = m_spellImmune[(int)SpellImmunity.School];
|
||||
foreach (var pair in mechanicList)
|
||||
mask |= pair.Key;
|
||||
|
||||
return mask;
|
||||
}
|
||||
public uint GetMechanicImmunityMask()
|
||||
{
|
||||
uint mask = 0;
|
||||
var mechanicList = m_spellImmune.LookupByKey(SpellImmunity.Mechanic);
|
||||
foreach (var spell in mechanicList)
|
||||
mask |= (uint)(1 << (int)spell.spellType);
|
||||
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
|
||||
foreach (var pair in mechanicList)
|
||||
mask |= (1u << (int)pair.Value);
|
||||
|
||||
return mask;
|
||||
}
|
||||
@@ -1668,75 +1674,76 @@ namespace Game.Entities
|
||||
|
||||
// If m_immuneToEffect type contain this effect type, IMMUNE effect.
|
||||
uint eff = (uint)effect.Effect;
|
||||
var effectList = m_spellImmune.LookupByKey(SpellImmunity.Effect);
|
||||
foreach (var immune in effectList)
|
||||
if (immune.spellType == eff)
|
||||
return true;
|
||||
var effectList = m_spellImmune[(int)SpellImmunity.Effect];
|
||||
if (effectList.ContainsKey(eff))
|
||||
return true;
|
||||
|
||||
uint mechanic = (uint)effect.Mechanic;
|
||||
if (mechanic != 0)
|
||||
{
|
||||
var mechanicList = m_spellImmune.LookupByKey(SpellImmunity.Mechanic);
|
||||
foreach (var immune in mechanicList)
|
||||
if (immune.spellType == mechanic)
|
||||
return true;
|
||||
var mechanicList = m_spellImmune[(int)SpellImmunity.Mechanic];
|
||||
if (mechanicList.ContainsKey(mechanic))
|
||||
return true;
|
||||
}
|
||||
|
||||
uint aura = (uint)effect.ApplyAuraName;
|
||||
if (aura != 0)
|
||||
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
||||
{
|
||||
var list = m_spellImmune.LookupByKey(SpellImmunity.State);
|
||||
foreach (var immune in list)
|
||||
if (immune.spellType == aura)
|
||||
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
||||
return true;
|
||||
|
||||
// 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
|
||||
uint aura = (uint)effect.ApplyAuraName;
|
||||
if (aura != 0)
|
||||
{
|
||||
var list = m_spellImmune[(int)SpellImmunity.State];
|
||||
if (list.ContainsKey(aura))
|
||||
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;
|
||||
}
|
||||
public bool IsImmunedToDamage(SpellSchoolMask shoolMask)
|
||||
public bool IsImmunedToDamage(SpellSchoolMask schoolMask)
|
||||
{
|
||||
// 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)
|
||||
if (Convert.ToBoolean(immune.spellType & (uint)shoolMask))
|
||||
if (Convert.ToBoolean(immune.Key & (uint)schoolMask))
|
||||
return true;
|
||||
|
||||
// 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)
|
||||
if (Convert.ToBoolean(immune.spellType & (uint)shoolMask))
|
||||
if (Convert.ToBoolean(immune.Key & (uint)schoolMask))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
public bool IsImmunedToDamage(SpellInfo spellInfo)
|
||||
{
|
||||
if (spellInfo.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||
if (spellInfo == null)
|
||||
return false;
|
||||
|
||||
uint shoolMask = (uint)spellInfo.GetSchoolMask();
|
||||
if (spellInfo.Id != 42292 && spellInfo.Id != 59752)
|
||||
{
|
||||
// If m_immuneToSchool type contain this school type, IMMUNE damage.
|
||||
var schoolList = m_spellImmune.LookupByKey(SpellImmunity.School);
|
||||
foreach (var immune in schoolList)
|
||||
if (Convert.ToBoolean(immune.spellType & shoolMask) && !spellInfo.CanPierceImmuneAura(Global.SpellMgr.GetSpellInfo(immune.spellId)))
|
||||
return true;
|
||||
}
|
||||
if (spellInfo.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune) || spellInfo.HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune))
|
||||
return false;
|
||||
|
||||
uint schoolMask = (uint)spellInfo.GetSchoolMask();
|
||||
// If m_immuneToSchool type contain this school type, IMMUNE damage.
|
||||
var schoolList = m_spellImmune[(int)SpellImmunity.School];
|
||||
foreach (var pair in schoolList)
|
||||
if (Convert.ToBoolean(pair.Key & schoolMask) && !spellInfo.CanPierceImmuneAura(Global.SpellMgr.GetSpellInfo(pair.Value)))
|
||||
return true;
|
||||
|
||||
// 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)
|
||||
if (Convert.ToBoolean(immune.spellType & shoolMask))
|
||||
if (Convert.ToBoolean(immune.Key & schoolMask))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -2173,7 +2180,7 @@ namespace Game.Entities
|
||||
bool isSpellBlocked(Unit victim, SpellInfo spellProto, WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
||||
{
|
||||
// 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;
|
||||
|
||||
// Can't block when casting/controlled
|
||||
@@ -2657,28 +2664,6 @@ namespace Game.Entities
|
||||
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)
|
||||
{
|
||||
DiminishingReturn diminish = m_Diminishing[(int)group];
|
||||
|
||||
@@ -54,6 +54,9 @@ namespace Game.Entities
|
||||
m_modAttackSpeedPct = new float[] { 1.0f, 1.0f, 1.0f };
|
||||
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)
|
||||
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.ModUnattackable, true);
|
||||
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.SchoolAbsorb, true);
|
||||
_me.ApplySpellImmune(0, SpellImmunity.Mechanic, Mechanics.Shield, true);
|
||||
_me.ApplySpellImmune(0, SpellImmunity.Mechanic, Mechanics.Immune_Shield, true);
|
||||
_me.ApplySpellImmune(0, SpellImmunity.Mechanic, (uint)Mechanics.Shield, true);
|
||||
_me.ApplySpellImmune(0, SpellImmunity.Mechanic, (uint)Mechanics.Immune_Shield, true);
|
||||
|
||||
// ... Resistance, Split damage, Change stats ...
|
||||
_me.ApplySpellImmune(0, SpellImmunity.State, AuraType.DamageShield, true);
|
||||
|
||||
@@ -377,6 +377,9 @@ namespace Game
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loading SpellInfo diminishing infos...");
|
||||
Global.SpellMgr.LoadSpellInfoDiminishing();
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loading SpellInfo immunity infos...");
|
||||
Global.SpellMgr.LoadSpellInfoImmunities();
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loading PetFamilySpellsStore Data...");
|
||||
Global.SpellMgr.LoadPetFamilySpellsStore();
|
||||
|
||||
|
||||
@@ -2703,7 +2703,7 @@ namespace Game.Spells
|
||||
{
|
||||
//Players on flying mounts must be immune to polymorph
|
||||
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)
|
||||
if (apply && target.HasAuraEffect(42016, 0) && target.GetMountID() != 0)
|
||||
@@ -2767,228 +2767,13 @@ namespace Game.Spells
|
||||
/*** IMMUNITY ***/
|
||||
/*********************************************************/
|
||||
[AuraEffectHandler(AuraType.MechanicImmunityMask)]
|
||||
void HandleModStateImmunityMask(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||
void HandleModMechanicImmunityMask(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||
{
|
||||
if (!mode.HasAnyFlag(AuraEffectHandleModes.Real))
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
List<AuraType> aura_immunity_list = new List<AuraType>();
|
||||
|
||||
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);
|
||||
}
|
||||
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.MechanicImmunity)]
|
||||
@@ -2998,52 +2783,7 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
uint mechanic;
|
||||
|
||||
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());
|
||||
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.EffectImmunity)]
|
||||
@@ -3053,8 +2793,7 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
|
||||
target.ApplySpellImmune(GetId(), SpellImmunity.Effect, GetMiscValue(), apply);
|
||||
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
|
||||
// when removing flag aura, handle flag drop
|
||||
Player player = target.ToPlayer();
|
||||
@@ -3078,11 +2817,7 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
|
||||
target.ApplySpellImmune(GetId(), SpellImmunity.State, GetMiscValue(), apply);
|
||||
|
||||
if (apply && GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity))
|
||||
target.RemoveAurasByType((AuraType)GetMiscValue(), ObjectGuid.Empty, GetBase());
|
||||
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.SchoolImmunity)]
|
||||
@@ -3092,8 +2827,7 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
|
||||
target.ApplySpellImmune(GetId(), SpellImmunity.School, (uint)GetMiscValue(), (apply));
|
||||
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
|
||||
if (GetSpellInfo().Mechanic == Mechanics.Banish)
|
||||
{
|
||||
@@ -3103,9 +2837,9 @@ namespace Game.Spells
|
||||
{
|
||||
bool banishFound = false;
|
||||
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;
|
||||
break;
|
||||
@@ -3124,21 +2858,6 @@ namespace Game.Spells
|
||||
if (GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity)
|
||||
&& GetSpellInfo().HasAttribute(SpellAttr2.DamageReducedShield))
|
||||
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)]
|
||||
@@ -3148,8 +2867,7 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
|
||||
target.ApplySpellImmune(GetId(), SpellImmunity.Damage, (uint)GetMiscValue(), apply);
|
||||
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.DispelImmunity)]
|
||||
@@ -3159,8 +2877,7 @@ namespace Game.Spells
|
||||
return;
|
||||
|
||||
Unit target = aurApp.GetTarget();
|
||||
|
||||
target.ApplySpellDispelImmunity(m_spellInfo, (DispelType)GetMiscValue(), (apply));
|
||||
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
@@ -4608,7 +4325,7 @@ namespace Game.Spells
|
||||
{
|
||||
// Recently Bandaged
|
||||
case 11196:
|
||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, GetMiscValue(), apply);
|
||||
target.ApplySpellImmune(GetId(), SpellImmunity.Mechanic, (uint)GetMiscValue(), apply);
|
||||
break;
|
||||
// Unstable Power
|
||||
case 24658:
|
||||
|
||||
+284
-221
@@ -2091,7 +2091,7 @@ namespace Game.Spells
|
||||
return SpellMissInfo.Evade;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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)
|
||||
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
|
||||
// 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)
|
||||
@@ -2548,7 +2549,10 @@ namespace Game.Spells
|
||||
m_caster.ToPlayer().SetSpellModTakingSpell(this, false);
|
||||
}
|
||||
|
||||
SendCastResult(result);
|
||||
if (param1 != 0 || param2 != 0)
|
||||
SendCastResult(result, param1, param2);
|
||||
else
|
||||
SendCastResult(result);
|
||||
|
||||
finish(false);
|
||||
return;
|
||||
@@ -2749,10 +2753,11 @@ namespace Game.Spells
|
||||
// skip check if done already (for instant cast spells for example)
|
||||
if (!skipCheck)
|
||||
{
|
||||
SpellCastResult castResult = CheckCast(false);
|
||||
uint param1 = 0, param2 = 0;
|
||||
SpellCastResult castResult = CheckCast(false, ref param1, ref param2);
|
||||
if (castResult != SpellCastResult.SpellCastOk)
|
||||
{
|
||||
SendCastResult(castResult);
|
||||
SendCastResult(castResult, param1, param2);
|
||||
SendInterrupted(0);
|
||||
//restore spell mods
|
||||
if (m_caster.IsTypeId(TypeId.Player))
|
||||
@@ -3316,7 +3321,7 @@ namespace Game.Spells
|
||||
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.SpellID = (int)spellInfo.Id;
|
||||
@@ -3325,112 +3330,183 @@ namespace Game.Spells
|
||||
switch (result)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
case SpellCastResult.RequiresArea: // AreaTable.dbc id
|
||||
// hardcode areas limitation case
|
||||
switch (spellInfo.Id)
|
||||
if (param1.HasValue)
|
||||
packet.FailedArg1 = (int)param1;
|
||||
else
|
||||
{
|
||||
case 41617: // Cenarion Mana Salve
|
||||
case 41619: // Cenarion Healing Salve
|
||||
packet.FailedArg1 = 3905;
|
||||
break;
|
||||
case 41618: // Bottled Nethergon Energy
|
||||
case 41620: // Bottled Nethergon Vapor
|
||||
packet.FailedArg1 = 3842;
|
||||
break;
|
||||
case 45373: // Bloodberry Elixir
|
||||
packet.FailedArg1 = 4075;
|
||||
break;
|
||||
default: // default case (don't must be)
|
||||
packet.FailedArg1 = 0;
|
||||
break;
|
||||
// hardcode areas limitation case
|
||||
switch (spellInfo.Id)
|
||||
{
|
||||
case 41617: // Cenarion Mana Salve
|
||||
case 41619: // Cenarion Healing Salve
|
||||
packet.FailedArg1 = 3905;
|
||||
break;
|
||||
case 41618: // Bottled Nethergon Energy
|
||||
case 41620: // Bottled Nethergon Vapor
|
||||
packet.FailedArg1 = 3842;
|
||||
break;
|
||||
case 45373: // Bloodberry Elixir
|
||||
packet.FailedArg1 = 4075;
|
||||
break;
|
||||
default: // default case (don't must be)
|
||||
packet.FailedArg1 = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SpellCastResult.Totems:
|
||||
if (spellInfo.Totem[0] != 0)
|
||||
packet.FailedArg1 = (int)spellInfo.Totem[0];
|
||||
if (spellInfo.Totem[1] != 0)
|
||||
packet.FailedArg2 = (int)spellInfo.Totem[1];
|
||||
if (param1.HasValue)
|
||||
{
|
||||
packet.FailedArg1 = (int)param1;
|
||||
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;
|
||||
case SpellCastResult.TotemCategory:
|
||||
if (spellInfo.TotemCategory[0] != 0)
|
||||
packet.FailedArg1 = (int)spellInfo.TotemCategory[0];
|
||||
if (spellInfo.TotemCategory[1] != 0)
|
||||
packet.FailedArg2 = (int)spellInfo.TotemCategory[1];
|
||||
if (param1.HasValue)
|
||||
{
|
||||
packet.FailedArg1 = (int)param1;
|
||||
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;
|
||||
case SpellCastResult.EquippedItemClass:
|
||||
case SpellCastResult.EquippedItemClassMainhand:
|
||||
case SpellCastResult.EquippedItemClassOffhand:
|
||||
packet.FailedArg1 = (int)spellInfo.EquippedItemClass;
|
||||
packet.FailedArg2 = spellInfo.EquippedItemSubClassMask;
|
||||
if (param1.HasValue && param2.HasValue)
|
||||
{
|
||||
packet.FailedArg1 = (int)param1;
|
||||
packet.FailedArg2 = (int)param2;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.FailedArg1 = (int)spellInfo.EquippedItemClass;
|
||||
packet.FailedArg2 = spellInfo.EquippedItemSubClassMask;
|
||||
}
|
||||
break;
|
||||
case SpellCastResult.TooManyOfItem:
|
||||
{
|
||||
uint item = 0;
|
||||
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(caster.GetMap().GetDifficultyID()))
|
||||
if (effect.ItemType != 0)
|
||||
item = effect.ItemType;
|
||||
ItemTemplate proto = Global.ObjectMgr.GetItemTemplate(item);
|
||||
if (proto != null && proto.GetItemLimitCategory() != 0)
|
||||
packet.FailedArg1 = (int)proto.GetItemLimitCategory();
|
||||
if (param1.HasValue)
|
||||
packet.FailedArg1 = (int)param1;
|
||||
else
|
||||
{
|
||||
uint item = 0;
|
||||
foreach (SpellEffectInfo effect in spellInfo.GetEffectsForDifficulty(caster.GetMap().GetDifficultyID()))
|
||||
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;
|
||||
}
|
||||
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;
|
||||
case SpellCastResult.NeedExoticAmmo:
|
||||
packet.FailedArg1 = spellInfo.EquippedItemSubClassMask; // seems correct...
|
||||
if (param1.HasValue)
|
||||
packet.FailedArg1 = (int)param1;
|
||||
else
|
||||
packet.FailedArg1 = spellInfo.EquippedItemSubClassMask; // seems correct...
|
||||
break;
|
||||
case SpellCastResult.NeedMoreItems:
|
||||
packet.FailedArg1 = 0; // Item id
|
||||
packet.FailedArg2 = 0; // Item count?
|
||||
if (param1.HasValue && param2.HasValue)
|
||||
{
|
||||
packet.FailedArg1 = (int)param1;
|
||||
packet.FailedArg2 = (int)param2;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.FailedArg1 = 0; // Item id
|
||||
packet.FailedArg2 = 0; // Item count?
|
||||
}
|
||||
break;
|
||||
case SpellCastResult.MinSkill:
|
||||
packet.FailedArg1 = 0; // SkillLine.dbc id
|
||||
packet.FailedArg2 = 0; // required skill value
|
||||
if (param1.HasValue && param2.HasValue)
|
||||
{
|
||||
packet.FailedArg1 = (int)param1;
|
||||
packet.FailedArg2 = (int)param2;
|
||||
}
|
||||
else
|
||||
{
|
||||
packet.FailedArg1 = 0; // SkillLine.dbc id
|
||||
packet.FailedArg2 = 0; // required skill value
|
||||
}
|
||||
break;
|
||||
case SpellCastResult.FishingTooLow:
|
||||
packet.FailedArg1 = 0; // required fishing skill
|
||||
if (param1.HasValue)
|
||||
packet.FailedArg1 = (int)param1;
|
||||
else
|
||||
packet.FailedArg1 = 0; // required fishing skill
|
||||
break;
|
||||
case SpellCastResult.CustomError:
|
||||
packet.FailedArg1 = (int)customError;
|
||||
break;
|
||||
case SpellCastResult.Silenced:
|
||||
packet.FailedArg1 = 0; // Unknown
|
||||
if (param1.HasValue)
|
||||
packet.FailedArg1 = (int)param1;
|
||||
else
|
||||
packet.FailedArg1 = 0; // Unknown
|
||||
break;
|
||||
case SpellCastResult.Reagents:
|
||||
{
|
||||
uint missingItem = 0;
|
||||
for (uint i = 0; i < SpellConst.MaxReagents; i++)
|
||||
if (param1.HasValue)
|
||||
packet.FailedArg1 = (int)param1;
|
||||
else
|
||||
{
|
||||
if (spellInfo.Reagent[i] <= 0)
|
||||
continue;
|
||||
|
||||
uint itemid = (uint)spellInfo.Reagent[i];
|
||||
uint itemcount = spellInfo.ReagentCount[i];
|
||||
|
||||
if (!caster.HasItemCount(itemid, itemcount))
|
||||
uint missingItem = 0;
|
||||
for (uint i = 0; i < SpellConst.MaxReagents; i++)
|
||||
{
|
||||
missingItem = itemid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (spellInfo.Reagent[i] <= 0)
|
||||
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;
|
||||
}
|
||||
case SpellCastResult.CantUntalent:
|
||||
{
|
||||
if (misc != null)
|
||||
{
|
||||
TalentRecord talent = CliDB.TalentStorage.LookupByKey(misc[0]);
|
||||
if (talent != null)
|
||||
packet.FailedArg1 = (int)talent.SpellID;
|
||||
}
|
||||
Contract.Assert(param1.HasValue);
|
||||
packet.FailedArg1 = (int)param1;
|
||||
break;
|
||||
}
|
||||
// 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)
|
||||
return;
|
||||
@@ -3447,7 +3523,7 @@ namespace Game.Spells
|
||||
if (!m_caster.IsTypeId(TypeId.Player))
|
||||
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;
|
||||
|
||||
if (_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.DontReportCastError))
|
||||
@@ -3455,11 +3531,11 @@ namespace Game.Spells
|
||||
|
||||
CastFailed castFailed = new CastFailed();
|
||||
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);
|
||||
}
|
||||
|
||||
public void SendPetCastResult(SpellCastResult result)
|
||||
public void SendPetCastResult(SpellCastResult result, uint? param1 = null, uint? param2 = null)
|
||||
{
|
||||
if (result == SpellCastResult.SpellCastOk)
|
||||
return;
|
||||
@@ -3472,18 +3548,18 @@ namespace Game.Spells
|
||||
result = SpellCastResult.DontReport;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
CastFailed packet = new CastFailed();
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -4329,6 +4405,12 @@ namespace Game.Spells
|
||||
}
|
||||
|
||||
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;
|
||||
// check death state
|
||||
@@ -4395,13 +4477,15 @@ namespace Game.Spells
|
||||
bool checkForm = true;
|
||||
// Ignore form req aura
|
||||
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;
|
||||
|
||||
checkForm = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (checkForm)
|
||||
{
|
||||
// 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)
|
||||
if (!m_spellInfo.IsPassive())
|
||||
{
|
||||
castResult = CheckItems();
|
||||
castResult = CheckItems(ref param1, ref param2);
|
||||
if (castResult != SpellCastResult.SpellCastOk)
|
||||
return castResult;
|
||||
}
|
||||
@@ -4650,7 +4734,7 @@ namespace Game.Spells
|
||||
|
||||
if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreCasterAuras))
|
||||
{
|
||||
castResult = CheckCasterAuras();
|
||||
castResult = CheckCasterAuras(ref param1);
|
||||
if (castResult != SpellCastResult.SpellCastOk)
|
||||
return castResult;
|
||||
}
|
||||
@@ -4909,7 +4993,7 @@ namespace Game.Spells
|
||||
break;
|
||||
|
||||
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))
|
||||
return SpellCastResult.BadTargets;
|
||||
|
||||
@@ -5139,7 +5223,10 @@ namespace Game.Spells
|
||||
if (talent == null)
|
||||
return SpellCastResult.DontReport;
|
||||
if (m_caster.GetSpellHistory().HasCooldown(talent.SpellID))
|
||||
{
|
||||
param1 = talent.SpellID;
|
||||
return SpellCastResult.CantUntalent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SpellEffectName.GiveArtifactPower:
|
||||
@@ -5362,146 +5449,109 @@ namespace Game.Spells
|
||||
return CheckCast(true);
|
||||
}
|
||||
|
||||
SpellCastResult CheckCasterAuras()
|
||||
SpellCastResult CheckCasterAuras(ref uint param1)
|
||||
{
|
||||
// spells totally immuned to caster auras (wsg flag drop, give marks etc)
|
||||
if (m_spellInfo.HasAttribute(SpellAttr6.IgnoreCasterAuras))
|
||||
return SpellCastResult.SpellCastOk;
|
||||
|
||||
int school_immune = 0;
|
||||
uint mechanic_immune = 0;
|
||||
uint dispel_immune = 0;
|
||||
|
||||
// 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))
|
||||
bool usableWhileStunned = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileStunned);
|
||||
bool usableWhileFeared = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileFeared);
|
||||
bool usableWhileConfused = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileConfused);
|
||||
if (m_spellInfo.HasAttribute(SpellAttr7.UsableInStunFearConfusion))
|
||||
{
|
||||
foreach (SpellEffectInfo effect in GetEffects())
|
||||
{
|
||||
if (effect == null)
|
||||
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;
|
||||
usableWhileStunned = true;
|
||||
usableWhileFeared = true;
|
||||
usableWhileConfused = true;
|
||||
}
|
||||
|
||||
bool usableInStun = m_spellInfo.HasAttribute(SpellAttr5.UsableWhileStunned);
|
||||
|
||||
// Check whether the cast should be prevented by any state you might have.
|
||||
SpellCastResult prevented_reason = SpellCastResult.SpellCastOk;
|
||||
// Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
|
||||
UnitFlags unitflag = (UnitFlags)m_caster.GetUInt32Value(UnitFields.Flags); // Get unit state
|
||||
if (Convert.ToBoolean(unitflag & UnitFlags.Stunned))
|
||||
SpellCastResult result = SpellCastResult.SpellCastOk;
|
||||
// Get unit state
|
||||
UnitFlags unitflag = (UnitFlags)m_caster.GetUInt32Value(UnitFields.Flags);
|
||||
if (!m_caster.GetCharmerGUID().IsEmpty())
|
||||
{
|
||||
// spell is usable while stunned, check if caster has allowed stun auras, another stun types must prevent cast spell
|
||||
if (usableInStun)
|
||||
{
|
||||
uint allowedStunMask =
|
||||
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;
|
||||
Unit charmer = m_caster.GetCharmer();
|
||||
if (charmer)
|
||||
if (charmer.GetUnitBeingMoved() != m_caster && CheckCasterNotImmunedCharmAuras(ref param1))
|
||||
result = SpellCastResult.Charmed;
|
||||
}
|
||||
else if (unitflag.HasAnyFlag(UnitFlags.Confused) && !m_spellInfo.HasAttribute(SpellAttr5.UsableWhileConfused))
|
||||
prevented_reason = SpellCastResult.Confused;
|
||||
else if (unitflag.HasAnyFlag(UnitFlags.Fleeing) && !m_spellInfo.HasAttribute(SpellAttr5.UsableWhileFeared))
|
||||
prevented_reason = SpellCastResult.Fleeing;
|
||||
else if (unitflag.HasAnyFlag(UnitFlags.Silenced) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence))
|
||||
prevented_reason = SpellCastResult.Silenced;
|
||||
else if (unitflag.HasAnyFlag(UnitFlags.Pacified) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify))
|
||||
prevented_reason = SpellCastResult.Pacified;
|
||||
else if (unitflag.HasAnyFlag(UnitFlags.Stunned) && !usableWhileStunned && CheckCasterNotImmunedStunAuras(ref param1))
|
||||
result = SpellCastResult.Stunned;
|
||||
else if (unitflag.HasAnyFlag(UnitFlags.Silenced) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence) && CheckCasterNotImmunedSilenceAuras(ref param1))
|
||||
result = SpellCastResult.Silenced;
|
||||
else if (unitflag.HasAnyFlag(UnitFlags.Pacified) && m_spellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Pacify) && CheckCasterNotImmunedPacifyAuras(ref param1))
|
||||
result = SpellCastResult.Pacified;
|
||||
else if (unitflag.HasAnyFlag(UnitFlags.Fleeing) && !usableWhileFeared && CheckCasterNotImmunedFearAuras(ref param1))
|
||||
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))
|
||||
prevented_reason = SpellCastResult.NoActions;
|
||||
result = SpellCastResult.NoActions;
|
||||
|
||||
// Attr must make flag drop spell totally immune from all effects
|
||||
if (prevented_reason != SpellCastResult.SpellCastOk)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (result != SpellCastResult.SpellCastOk)
|
||||
return (param1 != 0) ? SpellCastResult.PreventedByMechanic : result;
|
||||
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()
|
||||
{
|
||||
bool isRatedBattleground = false; // NYI
|
||||
@@ -5727,13 +5777,15 @@ namespace Game.Spells
|
||||
return SpellCastResult.SpellCastOk;
|
||||
}
|
||||
|
||||
SpellCastResult CheckItems()
|
||||
SpellCastResult CheckItems(ref uint param1, ref uint param2)
|
||||
{
|
||||
Player player = m_caster.ToPlayer();
|
||||
|
||||
if (!player)
|
||||
return SpellCastResult.SpellCastOk;
|
||||
|
||||
if (m_spellInfo.HasAttribute(SpellAttr2.IgnoreItemCheck))
|
||||
return SpellCastResult.SpellCastOk;
|
||||
|
||||
if (m_CastItem == null)
|
||||
{
|
||||
if (!m_castItemGUID.IsEmpty())
|
||||
@@ -5809,13 +5861,11 @@ namespace Game.Spells
|
||||
// check target item
|
||||
if (!m_targets.GetItemTargetGUID().IsEmpty())
|
||||
{
|
||||
if (!m_caster.IsTypeId(TypeId.Player))
|
||||
return SpellCastResult.BadTargets;
|
||||
|
||||
if (m_targets.GetItemTarget() == null)
|
||||
Item item = m_targets.GetItemTarget();
|
||||
if (item == null)
|
||||
return SpellCastResult.ItemGone;
|
||||
|
||||
if (!m_targets.GetItemTarget().IsFitToSpellRequirements(m_spellInfo))
|
||||
if (!item.IsFitToSpellRequirements(m_spellInfo))
|
||||
return SpellCastResult.EquippedItemClass;
|
||||
}
|
||||
// if not item target then required item must be equipped
|
||||
@@ -5868,7 +5918,10 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
if (!player.HasItemCount(itemid, itemcount))
|
||||
{
|
||||
param1 = itemid;
|
||||
return SpellCastResult.Reagents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6073,21 +6126,26 @@ namespace Game.Spells
|
||||
}
|
||||
case SpellEffectName.Prospecting:
|
||||
{
|
||||
if (m_targets.GetItemTarget() == null)
|
||||
Item item = m_targets.GetItemTarget();
|
||||
if (!item)
|
||||
return SpellCastResult.CantBeProspected;
|
||||
//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;
|
||||
//prevent prospecting in trade slot
|
||||
if (m_targets.GetItemTarget().GetOwnerGUID() != m_caster.GetGUID())
|
||||
if (item.GetOwnerGUID() != m_caster.GetGUID())
|
||||
return SpellCastResult.CantBeProspected;
|
||||
//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))
|
||||
return SpellCastResult.LowCastlevel;
|
||||
//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;
|
||||
}
|
||||
|
||||
if (!LootStorage.Prospecting.HaveLootFor(m_targets.GetItemTargetEntry()))
|
||||
return SpellCastResult.CantBeProspected;
|
||||
@@ -6096,21 +6154,26 @@ namespace Game.Spells
|
||||
}
|
||||
case SpellEffectName.Milling:
|
||||
{
|
||||
if (m_targets.GetItemTarget() == null)
|
||||
Item item = m_targets.GetItemTarget();
|
||||
if (!item)
|
||||
return SpellCastResult.CantBeMilled;
|
||||
//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;
|
||||
//prevent milling in trade slot
|
||||
if (m_targets.GetItemTarget().GetOwnerGUID() != m_caster.GetGUID())
|
||||
if (item.GetOwnerGUID() != m_caster.GetGUID())
|
||||
return SpellCastResult.CantBeMilled;
|
||||
//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))
|
||||
return SpellCastResult.LowCastlevel;
|
||||
//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;
|
||||
}
|
||||
|
||||
if (!LootStorage.Milling.HaveLootFor(m_targets.GetItemTargetEntry()))
|
||||
return SpellCastResult.CantBeMilled;
|
||||
@@ -7145,7 +7208,7 @@ namespace Game.Spells
|
||||
return false;
|
||||
}
|
||||
|
||||
public static implicit operator bool (Spell spell)
|
||||
public static implicit operator bool(Spell spell)
|
||||
{
|
||||
return spell != null;
|
||||
}
|
||||
|
||||
+507
-14
@@ -638,32 +638,35 @@ namespace Game.Spells
|
||||
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)
|
||||
if (HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||
return true;
|
||||
|
||||
// these spells (Cyclone for example) can pierce all... | ...but not these (Divine shield, Ice block, Cyclone and Banish for example)
|
||||
if (HasAttribute(SpellAttr1.UnaffectedBySchoolImmune)
|
||||
&& !(aura != null && (aura.Mechanic == Mechanics.Immune_Shield || aura.Mechanic == Mechanics.Invulnerability || aura.Mechanic == Mechanics.Banish)))
|
||||
// Dispels other auras on immunity, check if this spell makes the unit immune to aura
|
||||
if (HasAttribute(SpellAttr1.DispelAurasOnImmunity) && CanSpellProvideImmunityAgainstAura(auraSpellInfo))
|
||||
return true;
|
||||
|
||||
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
|
||||
if (aura.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||
if (auraSpellInfo.HasAttribute(SpellAttr0.UnaffectedByInvulnerability))
|
||||
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
|
||||
if (aura.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune))
|
||||
if (auraSpellInfo.HasAttribute(SpellAttr1.UnaffectedBySchoolImmune) || auraSpellInfo.HasAttribute(SpellAttr2.UnaffectedByAuraSchoolImmune))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -1204,7 +1207,7 @@ namespace Game.Spells
|
||||
|
||||
// if target is magnet (i.e Grounding Totem) the check is skipped
|
||||
//if (target.IsMagnet())
|
||||
//return true;
|
||||
//return true;
|
||||
|
||||
uint creatureType = target.GetCreatureTypeMask();
|
||||
return TargetCreatureType == 0 || creatureType == 0 || Convert.ToBoolean(creatureType & TargetCreatureType);
|
||||
@@ -2017,6 +2020,478 @@ namespace Game.Spells
|
||||
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)
|
||||
{
|
||||
if (RangeEntry == null)
|
||||
@@ -2594,8 +3069,8 @@ namespace Game.Spells
|
||||
var visual = CliDB.SpellXSpellVisualStorage.LookupByKey(GetSpellXSpellVisualId(caster));
|
||||
if (visual != null)
|
||||
{
|
||||
//if (visual->LowViolenceSpellVisualID && forPlayer->GetViolenceLevel() operator 2)
|
||||
// return visual->LowViolenceSpellVisualID;
|
||||
//if (visual.LowViolenceSpellVisualID && forPlayer.GetViolenceLevel() operator 2)
|
||||
// return visual.LowViolenceSpellVisualID;
|
||||
|
||||
return visual.SpellVisualID;
|
||||
}
|
||||
@@ -3213,6 +3688,8 @@ namespace Game.Spells
|
||||
Scaling.Coefficient = spellEffectScaling != null ? spellEffectScaling.Coefficient : 0.0f;
|
||||
Scaling.Variance = spellEffectScaling != null ? spellEffectScaling.Variance : 0.0f;
|
||||
Scaling.ResourceCoefficient = spellEffectScaling != null ? spellEffectScaling.ResourceCoefficient : 0.0f;
|
||||
|
||||
_immunityInfo = new ImmunityInfo();
|
||||
}
|
||||
|
||||
public bool IsEffect()
|
||||
@@ -3551,6 +4028,8 @@ namespace Game.Spells
|
||||
return _data[(int)Effect].UsedTargetObjectType;
|
||||
}
|
||||
|
||||
public ImmunityInfo GetImmunityInfo() { return _immunityInfo; }
|
||||
|
||||
public class StaticData
|
||||
{
|
||||
public StaticData(SpellEffectImplicitTargetTypes implicittarget, SpellTargetObjectTypes usedtarget)
|
||||
@@ -3853,6 +4332,8 @@ namespace Game.Spells
|
||||
public float BonusCoefficientFromAP;
|
||||
public List<Condition> ImplicitTargetConditions;
|
||||
public ScalingInfo Scaling;
|
||||
|
||||
ImmunityInfo _immunityInfo;
|
||||
#endregion
|
||||
|
||||
public struct ScalingInfo
|
||||
@@ -4208,5 +4689,17 @@ namespace Game.Spells
|
||||
public DiminishingLevels DiminishMaxLevel = DiminishingLevels.Immune;
|
||||
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));
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
Dictionary<uint, SpellLevelsRecord> levelsBySpell = new Dictionary<uint, SpellLevelsRecord>();
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Scripts.Northrend
|
||||
public npc_mageguard_dalaran(Creature creature) : base(creature)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user