Core/Spells: Rename SpellAttr3 to use official attribute names
Port From (https://github.com/TrinityCore/TrinityCore/commit/88d7b58a3dd8b0eb95c233a20c1608ddce73d9ea)
This commit is contained in:
@@ -1688,38 +1688,38 @@ namespace Framework.Constants
|
|||||||
}
|
}
|
||||||
public enum SpellAttr3 : uint
|
public enum SpellAttr3 : uint
|
||||||
{
|
{
|
||||||
Unk0 = 0x01, // 0
|
PvpEnabling = 0x01, // Pvp Enabling
|
||||||
NoProcEquipRequirement = 0x02, // 1 Ignores subclass mask check when checking proc
|
NoProcEquipRequirement = 0x02, // No Proc Equip Requirement Description Ignores Subclass Mask Check When Checking Proc
|
||||||
Unk2 = 0x04, // 2
|
NoCastingBarText = 0x04, // No Casting Bar Text
|
||||||
BlockableSpell = 0x08, // 3 Only Dmg Class Melee In 3.1.3
|
CompletelyBlocked = 0x08, // Completely Blocked
|
||||||
IgnoreResurrectionTimer = 0x10, // 4 You Don'T Have To Wait To Be Resurrected With These Spells
|
NoResTimer = 0x10, // No Res Timer
|
||||||
NoDurabilityLoss = 0x20, // 5 No Durability Loss
|
NoDurabilityLoss = 0x20, // No Durability Loss
|
||||||
Unk6 = 0x40, // 6
|
NoAvoidance = 0x40, // No Avoidance
|
||||||
StackForDiffCasters = 0x80, // 7 Separate Stack For Every Caster
|
DotStackingRule = 0x80, // Dot Stacking Rule Description Stack Separately For Each Caster
|
||||||
OnlyTargetPlayers = 0x100, // 8 Can Only Target Players
|
OnlyOnPlayer = 0x100, // Only On Player
|
||||||
NotAProc = 0x200, // 9 Without this attribute, any triggered spell will be unable to trigger other auras' procs
|
NotAProc = 0x200, // Not A Proc Description Without This Attribute, Any Triggered Spell Will Be Unable To Trigger Other Auras' Procs
|
||||||
MainHand = 0x400, // 10 Main Hand Weapon Required
|
RequiresMainHandWeapon = 0x400, // Requires Main-Hand Weapon
|
||||||
Battleground = 0x800, // 11 Can Casted Only On Battleground
|
OnlyBattlegrounds = 0x800, // Only Battlegrounds
|
||||||
OnlyTargetGhosts = 0x1000, // 12
|
OnlyOnGhosts = 0x1000, // Only On Ghosts
|
||||||
DontDisplayChannelBar = 0x2000, // 13 Clientside attribute - will not display channeling bar
|
HideChannelBar = 0x2000, // Hide Channel Bar (Client Only)
|
||||||
IsHonorlessTarget = 0x4000, // 14 "Honorless Target" Only This Spells Have This Flag
|
HideInRaidFilter = 0x4000, // Hide In Raid Filter (Client Only)
|
||||||
Unk15 = 0x8000, // 15 Auto Shoot, Shoot, Throw, - This Is Autoshot Flag
|
NormalRangedAttack = 0x8000, // Normal Ranged Attack Description Auto Shoot, Shoot, Throw - Ranged Normal Attack Attribute?
|
||||||
CantTriggerProc = 0x10000, // 16 Confirmed With Many Patchnotes
|
SuppressCasterProcs = 0x10000, // Suppress Caster Procs
|
||||||
NoInitialAggro = 0x20000, // 17 Soothe Animal, 39758, Mind Soothe
|
SuppressTargetProcs = 0x20000, // Suppress Target Procs
|
||||||
IgnoreHitResult = 0x40000, // 18 Spell Should Always Hit Its Target
|
AlwaysHit = 0x40000, // Always Hit Description Spell Cannot Miss, Or Be Dodged/Parried/Blocked
|
||||||
DisableProc = 0x80000, // 19 During Aura Proc No Spells Can Trigger (20178, 20375)
|
InstantTargetProcs = 0x80000, // Instant Target Procs Description Proc Events Are Triggered Before Spell Batching Processes The Spell Hit On Target
|
||||||
DeathPersistent = 0x100000, // 20 Death Persistent Spells
|
AllowAuraWhileDead = 0x100000, // Allow Aura While Dead
|
||||||
Unk21 = 0x200000, // 21 Unused
|
OnlyProcOutdoors = 0x200000, // Only Proc Outdoors
|
||||||
ReqWand = 0x400000, // 22 Req Wand
|
DoNotTriggerTargetStand = 0x400000, // Do Not Trigger Target Stand
|
||||||
Unk23 = 0x800000, // 23
|
NoDamageHistory = 0x800000, /*Nyi, No Damage History Implementation*/ // No Damage History
|
||||||
ReqOffhand = 0x1000000, // 24 Req Offhand Weapon
|
RequiresOffHandWeapon = 0x1000000, // Requires Off-Hand Weapon
|
||||||
TreatAsPeriodic = 0x2000000, // 25 Makes the spell appear as periodic in client combat logs - used by spells that trigger another spell on each tick
|
TreatAsPeriodic = 0x2000000, // Treat As Periodic
|
||||||
CanProcFromProcs = 0x4000000, // 26 Can Proc From Procs
|
CanProcFromProcs = 0x4000000, // Can Proc From Procs
|
||||||
DrainSoul = 0x8000000, // 27 Only Drain Soul Has This Flag
|
OnlyProcOnCaster = 0x8000000, // Only Proc On Caster
|
||||||
Unk28 = 0x10000000, // 28
|
IgnoreCasterAndTargetRestrictions = 0x10000000, /*Nyi*/ // Ignore Caster & Target Restrictions
|
||||||
NoDoneBonus = 0x20000000, // 29 Ignore Caster Spellpower And Done Damage Mods? Client Doesn'T Apply Spellmods For Those Spells
|
IgnoreCasterModifiers = 0x20000000, // Ignore Caster Modifiers
|
||||||
DontDisplayRange = 0x40000000, // 30 Client Doesn'T Display Range In Tooltip For Those Spells
|
DoNotDisplayRange = 0x40000000, // Do Not Display Range (Client Only)
|
||||||
Unk31 = 0x80000000 // 31
|
NotOnAoeImmune = 0x80000000 /*Nyi, No Aoe Immunity Implementation*/ // Not On Aoe Immune
|
||||||
}
|
}
|
||||||
public enum SpellAttr4 : uint
|
public enum SpellAttr4 : uint
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ namespace Game.AI
|
|||||||
var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID());
|
var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID());
|
||||||
if (spellInfo != null)
|
if (spellInfo != null)
|
||||||
{
|
{
|
||||||
bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers);
|
bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyOnPlayer);
|
||||||
target = SelectTarget(SelectTargetMethod.Random, 0, spellInfo.GetMaxRange(false), playerOnly);
|
target = SelectTarget(SelectTargetMethod.Random, 0, spellInfo.GetMaxRange(false), playerOnly);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -278,7 +278,7 @@ namespace Game.AI
|
|||||||
var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID());
|
var spellInfo = Global.SpellMgr.GetSpellInfo(spellId, me.GetMap().GetDifficultyID());
|
||||||
if (spellInfo != null)
|
if (spellInfo != null)
|
||||||
{
|
{
|
||||||
bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers);
|
bool playerOnly = spellInfo.HasAttribute(SpellAttr3.OnlyOnPlayer);
|
||||||
float range = spellInfo.GetMaxRange(false);
|
float range = spellInfo.GetMaxRange(false);
|
||||||
|
|
||||||
DefaultTargetSelector targetSelector = new(me, range, playerOnly, true, -(int)spellId);
|
DefaultTargetSelector targetSelector = new(me, range, playerOnly, true, -(int)spellId);
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ namespace Game.Combat
|
|||||||
{
|
{
|
||||||
if (spell.HasAttribute(SpellAttr1.NoThreat))
|
if (spell.HasAttribute(SpellAttr1.NoThreat))
|
||||||
return;
|
return;
|
||||||
if (!_owner.IsEngaged() && spell.HasAttribute(SpellAttr3.NoInitialAggro))
|
if (!_owner.IsEngaged() && spell.HasAttribute(SpellAttr2.NoInitialThreat))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1914,7 +1914,7 @@ namespace Game.Entities
|
|||||||
if (!unitCaster)
|
if (!unitCaster)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(spellInfo.HasAttribute(SpellAttr0.IsAbility) || spellInfo.HasAttribute(SpellAttr0.IsTradeskill) || spellInfo.HasAttribute(SpellAttr3.NoDoneBonus)) &&
|
if (!(spellInfo.HasAttribute(SpellAttr0.IsAbility) || spellInfo.HasAttribute(SpellAttr0.IsTradeskill) || spellInfo.HasAttribute(SpellAttr3.IgnoreCasterModifiers)) &&
|
||||||
((IsPlayer() && spellInfo.SpellFamilyName != 0) || IsCreature()))
|
((IsPlayer() && spellInfo.SpellFamilyName != 0) || IsCreature()))
|
||||||
castTime = unitCaster.CanInstantCast() ? 0 : (int)(castTime * unitCaster.m_unitData.ModCastingSpeed);
|
castTime = unitCaster.CanInstantCast() ? 0 : (int)(castTime * unitCaster.m_unitData.ModCastingSpeed);
|
||||||
else if (spellInfo.HasAttribute(SpellAttr0.UsesRangedSlot) && !spellInfo.HasAttribute(SpellAttr2.AutoRepeat))
|
else if (spellInfo.HasAttribute(SpellAttr0.UsesRangedSlot) && !spellInfo.HasAttribute(SpellAttr2.AutoRepeat))
|
||||||
@@ -1940,7 +1940,7 @@ namespace Game.Entities
|
|||||||
if (!unitCaster)
|
if (!unitCaster)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(spellInfo.HasAttribute(SpellAttr0.IsAbility) || spellInfo.HasAttribute(SpellAttr0.IsTradeskill) || spellInfo.HasAttribute(SpellAttr3.NoDoneBonus)) &&
|
if (!(spellInfo.HasAttribute(SpellAttr0.IsAbility) || spellInfo.HasAttribute(SpellAttr0.IsTradeskill) || spellInfo.HasAttribute(SpellAttr3.IgnoreCasterModifiers)) &&
|
||||||
((IsPlayer() && spellInfo.SpellFamilyName != 0) || IsCreature()))
|
((IsPlayer() && spellInfo.SpellFamilyName != 0) || IsCreature()))
|
||||||
duration = (int)(duration * unitCaster.m_unitData.ModCastingSpeed);
|
duration = (int)(duration * unitCaster.m_unitData.ModCastingSpeed);
|
||||||
else if (spellInfo.HasAttribute(SpellAttr0.UsesRangedSlot) && !spellInfo.HasAttribute(SpellAttr2.AutoRepeat))
|
else if (spellInfo.HasAttribute(SpellAttr0.UsesRangedSlot) && !spellInfo.HasAttribute(SpellAttr2.AutoRepeat))
|
||||||
@@ -1963,6 +1963,9 @@ namespace Game.Entities
|
|||||||
if (!victim.IsAlive() && !victim.IsPlayer())
|
if (!victim.IsAlive() && !victim.IsPlayer())
|
||||||
return SpellMissInfo.None;
|
return SpellMissInfo.None;
|
||||||
|
|
||||||
|
if (spellInfo.HasAttribute(SpellAttr3.NoAvoidance))
|
||||||
|
return SpellMissInfo.None;
|
||||||
|
|
||||||
float missChance;
|
float missChance;
|
||||||
if (spellInfo.HasAttribute(SpellAttr7.NoAttackMiss))
|
if (spellInfo.HasAttribute(SpellAttr7.NoAttackMiss))
|
||||||
{
|
{
|
||||||
@@ -2005,7 +2008,7 @@ namespace Game.Entities
|
|||||||
modOwner.ApplySpellMod(spellInfo, SpellModOp.HitChance, ref modHitChance);
|
modOwner.ApplySpellMod(spellInfo, SpellModOp.HitChance, ref modHitChance);
|
||||||
|
|
||||||
// Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects
|
// Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects
|
||||||
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
if (!spellInfo.HasAttribute(SpellAttr3.AlwaysHit))
|
||||||
{
|
{
|
||||||
// Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras
|
// Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras
|
||||||
modHitChance += victim.GetTotalAuraModifierByMiscMask(AuraType.ModAttackerSpellHitChance, (int)schoolMask);
|
modHitChance += victim.GetTotalAuraModifierByMiscMask(AuraType.ModAttackerSpellHitChance, (int)schoolMask);
|
||||||
@@ -2087,7 +2090,7 @@ namespace Game.Entities
|
|||||||
return SpellMissInfo.Reflect;
|
return SpellMissInfo.Reflect;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
if (spellInfo.HasAttribute(SpellAttr3.AlwaysHit))
|
||||||
return SpellMissInfo.None;
|
return SpellMissInfo.None;
|
||||||
|
|
||||||
switch (spellInfo.DmgClass)
|
switch (spellInfo.DmgClass)
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace Game.Entities
|
|||||||
return pdamage;
|
return pdamage;
|
||||||
|
|
||||||
// Some spells don't benefit from done mods
|
// Some spells don't benefit from done mods
|
||||||
if (spellProto.HasAttribute(SpellAttr3.NoDoneBonus))
|
if (spellProto.HasAttribute(SpellAttr3.IgnoreCasterModifiers))
|
||||||
return pdamage;
|
return pdamage;
|
||||||
|
|
||||||
// For totems get damage bonus from owner
|
// For totems get damage bonus from owner
|
||||||
@@ -117,7 +117,7 @@ namespace Game.Entities
|
|||||||
if ((spellProto.IsRangedWeaponSpell() && spellProto.DmgClass != SpellDmgClass.Melee))
|
if ((spellProto.IsRangedWeaponSpell() && spellProto.DmgClass != SpellDmgClass.Melee))
|
||||||
attType = WeaponAttackType.RangedAttack;
|
attType = WeaponAttackType.RangedAttack;
|
||||||
|
|
||||||
if (spellProto.HasAttribute(SpellAttr3.ReqOffhand) && !spellProto.HasAttribute(SpellAttr3.MainHand))
|
if (spellProto.HasAttribute(SpellAttr3.RequiresOffHandWeapon) && !spellProto.HasAttribute(SpellAttr3.RequiresMainHandWeapon))
|
||||||
attType = WeaponAttackType.OffAttack;
|
attType = WeaponAttackType.OffAttack;
|
||||||
|
|
||||||
float APbonus = (float)(victim.GetTotalAuraModifier(attType != WeaponAttackType.RangedAttack ? AuraType.MeleeAttackPowerAttackerBonus : AuraType.RangedAttackPowerAttackerBonus));
|
float APbonus = (float)(victim.GetTotalAuraModifier(attType != WeaponAttackType.RangedAttack ? AuraType.MeleeAttackPowerAttackerBonus : AuraType.RangedAttackPowerAttackerBonus));
|
||||||
@@ -160,7 +160,7 @@ namespace Game.Entities
|
|||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
||||||
// Some spells don't benefit from done mods
|
// Some spells don't benefit from done mods
|
||||||
if (spellProto.HasAttribute(SpellAttr3.NoDoneBonus))
|
if (spellProto.HasAttribute(SpellAttr3.IgnoreCasterModifiers))
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
||||||
// Some spells don't benefit from pct done mods
|
// Some spells don't benefit from pct done mods
|
||||||
@@ -498,7 +498,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Some spells don't benefit from done mods
|
// Some spells don't benefit from done mods
|
||||||
if (spellProto.HasAttribute(SpellAttr3.NoDoneBonus))
|
if (spellProto.HasAttribute(SpellAttr3.IgnoreCasterModifiers))
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
|
||||||
// Some spells don't benefit from done mods
|
// Some spells don't benefit from done mods
|
||||||
@@ -736,6 +736,9 @@ namespace Game.Entities
|
|||||||
// Melee based spells hit result calculations
|
// Melee based spells hit result calculations
|
||||||
public override SpellMissInfo MeleeSpellHitResult(Unit victim, SpellInfo spellInfo)
|
public override SpellMissInfo MeleeSpellHitResult(Unit victim, SpellInfo spellInfo)
|
||||||
{
|
{
|
||||||
|
if (spellInfo.HasAttribute(SpellAttr3.NoAvoidance))
|
||||||
|
return SpellMissInfo.None;
|
||||||
|
|
||||||
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
||||||
|
|
||||||
// Check damage class instead of attack type to correctly handle judgements
|
// Check damage class instead of attack type to correctly handle judgements
|
||||||
@@ -763,7 +766,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
bool canDodge = !spellInfo.HasAttribute(SpellAttr7.NoAttackDodge);
|
bool canDodge = !spellInfo.HasAttribute(SpellAttr7.NoAttackDodge);
|
||||||
bool canParry = !spellInfo.HasAttribute(SpellAttr7.NoAttackParry);
|
bool canParry = !spellInfo.HasAttribute(SpellAttr7.NoAttackParry);
|
||||||
bool canBlock = spellInfo.HasAttribute(SpellAttr3.BlockableSpell);
|
bool canBlock = spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked);
|
||||||
|
|
||||||
// if victim is casting or cc'd it can't avoid attacks
|
// if victim is casting or cc'd it can't avoid attacks
|
||||||
if (victim.IsNonMeleeSpellCast(false, false, true) || victim.HasUnitState(UnitState.Controlled))
|
if (victim.IsNonMeleeSpellCast(false, false, true) || victim.HasUnitState(UnitState.Controlled))
|
||||||
@@ -1336,7 +1339,7 @@ namespace Game.Entities
|
|||||||
AuraType aura = spellEffectInfo.ApplyAuraName;
|
AuraType aura = spellEffectInfo.ApplyAuraName;
|
||||||
if (aura != 0)
|
if (aura != 0)
|
||||||
{
|
{
|
||||||
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
if (!spellInfo.HasAttribute(SpellAttr3.AlwaysHit))
|
||||||
{
|
{
|
||||||
var list = m_spellImmune[(int)SpellImmunity.State];
|
var list = m_spellImmune[(int)SpellImmunity.State];
|
||||||
if (list.ContainsKey(aura))
|
if (list.ContainsKey(aura))
|
||||||
@@ -1379,7 +1382,7 @@ namespace Game.Entities
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// for example 40175
|
// for example 40175
|
||||||
if (spellInfo.HasAttribute(SpellAttr0.NoImmunities) && spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
if (spellInfo.HasAttribute(SpellAttr0.NoImmunities) && spellInfo.HasAttribute(SpellAttr3.AlwaysHit))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (spellInfo.HasAttribute(SpellAttr1.ImmunityToHostileAndFriendlyEffects) || spellInfo.HasAttribute(SpellAttr2.NoSchoolImmunities))
|
if (spellInfo.HasAttribute(SpellAttr1.ImmunityToHostileAndFriendlyEffects) || spellInfo.HasAttribute(SpellAttr2.NoSchoolImmunities))
|
||||||
@@ -1578,14 +1581,7 @@ namespace Game.Entities
|
|||||||
if (aurApp.GetRemoveMode() != 0)
|
if (aurApp.GetRemoveMode() != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SpellInfo spellInfo = aurApp.GetBase().GetSpellInfo();
|
|
||||||
if (spellInfo.HasAttribute(SpellAttr3.DisableProc))
|
|
||||||
SetCantProc(true);
|
|
||||||
|
|
||||||
aurApp.GetBase().TriggerProcOnEvent(procEffectMask, aurApp, eventInfo);
|
aurApp.GetBase().TriggerProcOnEvent(procEffectMask, aurApp, eventInfo);
|
||||||
|
|
||||||
if (spellInfo.HasAttribute(SpellAttr3.DisableProc))
|
|
||||||
SetCantProc(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disableProcs)
|
if (disableProcs)
|
||||||
@@ -1762,7 +1758,7 @@ namespace Game.Entities
|
|||||||
bool IsSpellBlocked(Unit victim, SpellInfo spellProto, WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
bool IsSpellBlocked(Unit victim, SpellInfo spellProto, WeaponAttackType attackType = WeaponAttackType.BaseAttack)
|
||||||
{
|
{
|
||||||
// These spells can't be blocked
|
// These spells can't be blocked
|
||||||
if (spellProto != null && (spellProto.HasAttribute(SpellAttr0.NoActiveDefense) || spellProto.HasAttribute(SpellAttr3.IgnoreHitResult)))
|
if (spellProto != null && (spellProto.HasAttribute(SpellAttr0.NoActiveDefense) || spellProto.HasAttribute(SpellAttr3.AlwaysHit)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Can't block when casting/controlled
|
// Can't block when casting/controlled
|
||||||
@@ -1961,7 +1957,7 @@ namespace Game.Entities
|
|||||||
if (damageSchoolMask.HasAnyFlag(SpellSchoolMask.Normal))
|
if (damageSchoolMask.HasAnyFlag(SpellSchoolMask.Normal))
|
||||||
{
|
{
|
||||||
// Spells with this attribute were already calculated in MeleeSpellHitResult
|
// Spells with this attribute were already calculated in MeleeSpellHitResult
|
||||||
if (!spellInfo.HasAttribute(SpellAttr3.BlockableSpell))
|
if (!spellInfo.HasAttribute(SpellAttr3.CompletelyBlocked))
|
||||||
{
|
{
|
||||||
// Get blocked status
|
// Get blocked status
|
||||||
blocked = IsSpellBlocked(victim, spellInfo, attackType);
|
blocked = IsSpellBlocked(victim, spellInfo, attackType);
|
||||||
@@ -3439,7 +3435,7 @@ namespace Game.Entities
|
|||||||
Aura aura = aurApp.GetBase();
|
Aura aura = aurApp.GetBase();
|
||||||
return (!aura.GetSpellInfo().HasAttribute(SpellAttr4.DontRemoveInArena) // don't remove stances, shadowform, pally/hunter auras
|
return (!aura.GetSpellInfo().HasAttribute(SpellAttr4.DontRemoveInArena) // don't remove stances, shadowform, pally/hunter auras
|
||||||
&& !aura.IsPassive() // don't remove passive auras
|
&& !aura.IsPassive() // don't remove passive auras
|
||||||
&& (aurApp.IsPositive() || !aura.GetSpellInfo().HasAttribute(SpellAttr3.DeathPersistent))) || // not negative death persistent auras
|
&& (aurApp.IsPositive() || !aura.GetSpellInfo().HasAttribute(SpellAttr3.AllowAuraWhileDead))) || // not negative death persistent auras
|
||||||
aura.GetSpellInfo().HasAttribute(SpellAttr5.RemoveEnteringArena); // special marker, always remove
|
aura.GetSpellInfo().HasAttribute(SpellAttr5.RemoveEnteringArena); // special marker, always remove
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2173,7 +2173,7 @@ namespace Game.Maps
|
|||||||
if (u.IsTypeId(TypeId.Unit) && u.IsTotem())
|
if (u.IsTypeId(TypeId.Unit) && u.IsTotem())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (_spellInfo != null && _spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers) && !u.IsPlayer())
|
if (_spellInfo != null && _spellInfo.HasAttribute(SpellAttr3.OnlyOnPlayer) && !u.IsPlayer())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!i_funit.IsValidAttackTarget(u, _spellInfo))
|
if (!i_funit.IsValidAttackTarget(u, _spellInfo))
|
||||||
|
|||||||
@@ -1564,7 +1564,7 @@ namespace Game.Spells
|
|||||||
if (existingAura.GetSpellInfo().IsChanneled())
|
if (existingAura.GetSpellInfo().IsChanneled())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (m_spellInfo.HasAttribute(SpellAttr3.StackForDiffCasters))
|
if (m_spellInfo.HasAttribute(SpellAttr3.DotStackingRule))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// check same periodic auras
|
// check same periodic auras
|
||||||
@@ -1820,6 +1820,14 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_spellInfo.HasAttribute(SpellAttr3.OnlyProcOutdoors))
|
||||||
|
if (!target.IsOutdoors())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (m_spellInfo.HasAttribute(SpellAttr3.OnlyProcOnCaster))
|
||||||
|
if (target.GetGUID() != GetCasterGUID())
|
||||||
|
return 0;
|
||||||
|
|
||||||
bool success = RandomHelper.randChance(CalcProcChance(procEntry, eventInfo));
|
bool success = RandomHelper.randChance(CalcProcChance(procEntry, eventInfo));
|
||||||
|
|
||||||
SetLastProcAttemptTime(now);
|
SetLastProcAttemptTime(now);
|
||||||
|
|||||||
+31
-22
@@ -289,7 +289,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
if (noTargetFound)
|
if (noTargetFound)
|
||||||
{
|
{
|
||||||
SendCastResult(m_spellInfo.Id == 51690 ? SpellCastResult.OutOfRange : SpellCastResult.BadTargets);
|
SendCastResult(SpellCastResult.BadImplicitTargets);
|
||||||
Finish(false);
|
Finish(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1558,9 +1558,9 @@ namespace Game.Spells
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers))
|
if (m_spellInfo.HasAttribute(SpellAttr3.OnlyOnPlayer))
|
||||||
retMask &= GridMapTypeMask.Corpse | GridMapTypeMask.Player;
|
retMask &= GridMapTypeMask.Corpse | GridMapTypeMask.Player;
|
||||||
if (m_spellInfo.HasAttribute(SpellAttr3.OnlyTargetGhosts))
|
if (m_spellInfo.HasAttribute(SpellAttr3.OnlyOnGhosts))
|
||||||
retMask &= GridMapTypeMask.Player;
|
retMask &= GridMapTypeMask.Player;
|
||||||
|
|
||||||
if (condList != null)
|
if (condList != null)
|
||||||
@@ -2943,7 +2943,8 @@ namespace Game.Spells
|
|||||||
if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreAuraInterruptFlags) && !m_spellInfo.HasAttribute(SpellAttr2.NotAnAction))
|
if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreAuraInterruptFlags) && !m_spellInfo.HasAttribute(SpellAttr2.NotAnAction))
|
||||||
m_originalCaster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ActionDelayed, m_spellInfo);
|
m_originalCaster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ActionDelayed, m_spellInfo);
|
||||||
|
|
||||||
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Cast, hitMask, this, null, null);
|
if (!m_spellInfo.HasAttribute(SpellAttr3.SuppressCasterProcs))
|
||||||
|
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Cast, hitMask, this, null, null);
|
||||||
|
|
||||||
// Call CreatureAI hook OnSpellCast
|
// Call CreatureAI hook OnSpellCast
|
||||||
Creature caster = m_originalCaster.ToCreature();
|
Creature caster = m_originalCaster.ToCreature();
|
||||||
@@ -3209,7 +3210,8 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Finish, m_hitMask, this, null, null);
|
if (!m_spellInfo.HasAttribute(SpellAttr3.SuppressCasterProcs))
|
||||||
|
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Finish, m_hitMask, this, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendSpellCooldown()
|
void SendSpellCooldown()
|
||||||
@@ -3354,7 +3356,8 @@ namespace Game.Spells
|
|||||||
if (creatureCaster != null)
|
if (creatureCaster != null)
|
||||||
creatureCaster.ReleaseSpellFocus(this);
|
creatureCaster.ReleaseSpellFocus(this);
|
||||||
|
|
||||||
Unit.ProcSkillsAndAuras(unitCaster, null, new ProcFlagsInit(ProcFlags.CastEnded), new ProcFlagsInit(), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, this, null, null);
|
if (!m_spellInfo.HasAttribute(SpellAttr3.SuppressCasterProcs))
|
||||||
|
Unit.ProcSkillsAndAuras(unitCaster, null, new ProcFlagsInit(ProcFlags.CastEnded), new ProcFlagsInit(), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, this, null, null);
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return;
|
return;
|
||||||
@@ -4229,7 +4232,7 @@ namespace Game.Spells
|
|||||||
resurrectRequest.ResurrectOffererVirtualRealmAddress = Global.WorldMgr.GetVirtualRealmAddress();
|
resurrectRequest.ResurrectOffererVirtualRealmAddress = Global.WorldMgr.GetVirtualRealmAddress();
|
||||||
resurrectRequest.Name = sentName;
|
resurrectRequest.Name = sentName;
|
||||||
resurrectRequest.Sickness = m_caster.IsUnit() && !m_caster.IsTypeId(TypeId.Player); // "you'll be afflicted with resurrection sickness"
|
resurrectRequest.Sickness = m_caster.IsUnit() && !m_caster.IsTypeId(TypeId.Player); // "you'll be afflicted with resurrection sickness"
|
||||||
resurrectRequest.UseTimer = !m_spellInfo.HasAttribute(SpellAttr3.IgnoreResurrectionTimer);
|
resurrectRequest.UseTimer = !m_spellInfo.HasAttribute(SpellAttr3.NoResTimer);
|
||||||
|
|
||||||
Pet pet = target.GetPet();
|
Pet pet = target.GetPet();
|
||||||
if (pet)
|
if (pet)
|
||||||
@@ -4866,8 +4869,8 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Spell casted only on Battleground
|
// Spell casted only on Battleground
|
||||||
if (m_spellInfo.HasAttribute(SpellAttr3.Battleground) && m_caster.IsTypeId(TypeId.Player))
|
if (m_spellInfo.HasAttribute(SpellAttr3.OnlyBattlegrounds))
|
||||||
if (!m_caster.ToPlayer().InBattleground())
|
if (!m_caster.GetMap().IsBattleground())
|
||||||
return SpellCastResult.OnlyBattlegrounds;
|
return SpellCastResult.OnlyBattlegrounds;
|
||||||
|
|
||||||
// do not allow spells to be cast in arenas or rated Battlegrounds
|
// do not allow spells to be cast in arenas or rated Battlegrounds
|
||||||
@@ -6783,7 +6786,7 @@ namespace Game.Spells
|
|||||||
});
|
});
|
||||||
|
|
||||||
// main hand weapon required
|
// main hand weapon required
|
||||||
if (m_spellInfo.HasAttribute(SpellAttr3.MainHand))
|
if (m_spellInfo.HasAttribute(SpellAttr3.RequiresMainHandWeapon))
|
||||||
{
|
{
|
||||||
SpellCastResult mainHandResult = weaponCheck(WeaponAttackType.BaseAttack);
|
SpellCastResult mainHandResult = weaponCheck(WeaponAttackType.BaseAttack);
|
||||||
if (mainHandResult != SpellCastResult.SpellCastOk)
|
if (mainHandResult != SpellCastResult.SpellCastOk)
|
||||||
@@ -6791,7 +6794,7 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
|
|
||||||
// offhand hand weapon required
|
// offhand hand weapon required
|
||||||
if (m_spellInfo.HasAttribute(SpellAttr3.ReqOffhand))
|
if (m_spellInfo.HasAttribute(SpellAttr3.RequiresOffHandWeapon))
|
||||||
{
|
{
|
||||||
SpellCastResult offHandResult = weaponCheck(WeaponAttackType.OffAttack);
|
SpellCastResult offHandResult = weaponCheck(WeaponAttackType.OffAttack);
|
||||||
if (offHandResult != SpellCastResult.SpellCastOk)
|
if (offHandResult != SpellCastResult.SpellCastOk)
|
||||||
@@ -8195,13 +8198,12 @@ namespace Game.Spells
|
|||||||
if ((MissCondition == SpellMissInfo.Immune || MissCondition == SpellMissInfo.Immune2) && spell.GetCaster().IsPlayer() && unit.IsPlayer() && spell.GetCaster().IsValidAttackTarget(unit, spell.GetSpellInfo()))
|
if ((MissCondition == SpellMissInfo.Immune || MissCondition == SpellMissInfo.Immune2) && spell.GetCaster().IsPlayer() && unit.IsPlayer() && spell.GetCaster().IsValidAttackTarget(unit, spell.GetSpellInfo()))
|
||||||
unit.SetInCombatWith(spell.GetCaster().ToPlayer());
|
unit.SetInCombatWith(spell.GetCaster().ToPlayer());
|
||||||
|
|
||||||
_enablePVP = false; // need to check PvP state before spell effects, but act on it afterwards
|
// if target is flagged for pvp also flag caster if a player
|
||||||
|
_enablePVP = (MissCondition == SpellMissInfo.None || spell.m_spellInfo.HasAttribute(SpellAttr3.PvpEnabling))
|
||||||
|
&& unit.IsPvP() && spell.GetCaster().IsPlayer(); // need to check PvP state before spell effects, but act on it afterwards
|
||||||
|
|
||||||
if (_spellHitTarget)
|
if (_spellHitTarget)
|
||||||
{
|
{
|
||||||
// if target is flagged for pvp also flag caster if a player
|
|
||||||
if (unit.IsPvP() && spell.GetCaster().IsPlayer())
|
|
||||||
_enablePVP = true; // Decide on PvP flagging now, but act on it later.
|
|
||||||
|
|
||||||
SpellMissInfo missInfo = spell.PreprocessSpellHit(_spellHitTarget, this);
|
SpellMissInfo missInfo = spell.PreprocessSpellHit(_spellHitTarget, this);
|
||||||
if (missInfo != SpellMissInfo.None)
|
if (missInfo != SpellMissInfo.None)
|
||||||
{
|
{
|
||||||
@@ -8276,8 +8278,9 @@ namespace Game.Spells
|
|||||||
ProcFlagsHit hitMask = ProcFlagsHit.None;
|
ProcFlagsHit hitMask = ProcFlagsHit.None;
|
||||||
|
|
||||||
// Spells with this flag cannot trigger if effect is cast on self
|
// Spells with this flag cannot trigger if effect is cast on self
|
||||||
bool canEffectTrigger = !spell.m_spellInfo.HasAttribute(SpellAttr3.CantTriggerProc) && spell.unitTarget.CanProc() &&
|
bool canEffectTrigger = (!spell.m_spellInfo.HasAttribute(SpellAttr3.SuppressCasterProcs) || !spell.m_spellInfo.HasAttribute(SpellAttr3.SuppressTargetProcs))
|
||||||
(spell.CanExecuteTriggersOnHit(EffectMask) || MissCondition == SpellMissInfo.Immune || MissCondition == SpellMissInfo.Immune2);
|
&& spell.unitTarget.CanProc()
|
||||||
|
&& (spell.CanExecuteTriggersOnHit(EffectMask) || MissCondition == SpellMissInfo.Immune || MissCondition == SpellMissInfo.Immune2);
|
||||||
|
|
||||||
// Trigger info was not filled in Spell::prepareDataForTriggerSystem - we do it now
|
// Trigger info was not filled in Spell::prepareDataForTriggerSystem - we do it now
|
||||||
if (canEffectTrigger && !procAttacker && !procVictim)
|
if (canEffectTrigger && !procAttacker && !procVictim)
|
||||||
@@ -8440,6 +8443,12 @@ namespace Game.Spells
|
|||||||
// Do triggers for unit
|
// Do triggers for unit
|
||||||
if (canEffectTrigger)
|
if (canEffectTrigger)
|
||||||
{
|
{
|
||||||
|
if (spell.m_spellInfo.HasAttribute(SpellAttr3.SuppressCasterProcs))
|
||||||
|
procAttacker = new ProcFlagsInit();
|
||||||
|
|
||||||
|
if (spell.m_spellInfo.HasAttribute(SpellAttr3.SuppressTargetProcs))
|
||||||
|
procVictim = new ProcFlagsInit();
|
||||||
|
|
||||||
Unit.ProcSkillsAndAuras(caster, spell.unitTarget, procAttacker, procVictim, procSpellType, ProcFlagsSpellPhase.Hit, hitMask, spell, spellDamageInfo, healInfo);
|
Unit.ProcSkillsAndAuras(caster, spell.unitTarget, procAttacker, procVictim, procSpellType, ProcFlagsSpellPhase.Hit, hitMask, spell, spellDamageInfo, healInfo);
|
||||||
|
|
||||||
// item spells (spell hit of non-damage spell may also activate items, for example seal of corruption hidden hit)
|
// item spells (spell hit of non-damage spell may also activate items, for example seal of corruption hidden hit)
|
||||||
@@ -8465,7 +8474,7 @@ namespace Game.Spells
|
|||||||
if (unitCaster != null)
|
if (unitCaster != null)
|
||||||
unitCaster.AtTargetAttacked(unit, spell.m_spellInfo.HasInitialAggro());
|
unitCaster.AtTargetAttacked(unit, spell.m_spellInfo.HasInitialAggro());
|
||||||
|
|
||||||
if (!unit.IsStandState())
|
if (!spell.m_spellInfo.HasAttribute(SpellAttr3.DoNotTriggerTargetStand) && !unit.IsStandState())
|
||||||
unit.SetStandState(UnitStandStateType.Stand);
|
unit.SetStandState(UnitStandStateType.Stand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8508,10 +8517,10 @@ namespace Game.Spells
|
|||||||
|
|
||||||
// Needs to be called after dealing damage/healing to not remove breaking on damage auras
|
// Needs to be called after dealing damage/healing to not remove breaking on damage auras
|
||||||
spell.DoTriggersOnSpellHit(_spellHitTarget, EffectMask);
|
spell.DoTriggersOnSpellHit(_spellHitTarget, EffectMask);
|
||||||
|
|
||||||
if (_enablePVP)
|
|
||||||
spell.GetCaster().ToPlayer().UpdatePvP(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_enablePVP)
|
||||||
|
spell.GetCaster().ToPlayer().UpdatePvP(true);
|
||||||
|
|
||||||
spell.spellAura = HitAura;
|
spell.spellAura = HitAura;
|
||||||
spell.CallScriptAfterHitHandlers();
|
spell.CallScriptAfterHitHandlers();
|
||||||
|
|||||||
@@ -475,7 +475,7 @@ namespace Game.Spells
|
|||||||
public bool IsStackableOnOneSlotWithDifferentCasters()
|
public bool IsStackableOnOneSlotWithDifferentCasters()
|
||||||
{
|
{
|
||||||
// TODO: Re-verify meaning of SPELL_ATTR3_STACK_FOR_DIFF_CASTERS and update conditions here
|
// TODO: Re-verify meaning of SPELL_ATTR3_STACK_FOR_DIFF_CASTERS and update conditions here
|
||||||
return StackAmount > 1 && !IsChanneled() && !HasAttribute(SpellAttr3.StackForDiffCasters);
|
return StackAmount > 1 && !IsChanneled() && !HasAttribute(SpellAttr3.DotStackingRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsCooldownStartedOnEvent()
|
public bool IsCooldownStartedOnEvent()
|
||||||
@@ -489,12 +489,12 @@ namespace Game.Spells
|
|||||||
|
|
||||||
public bool IsDeathPersistent()
|
public bool IsDeathPersistent()
|
||||||
{
|
{
|
||||||
return HasAttribute(SpellAttr3.DeathPersistent);
|
return HasAttribute(SpellAttr3.AllowAuraWhileDead);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsRequiringDeadTarget()
|
public bool IsRequiringDeadTarget()
|
||||||
{
|
{
|
||||||
return HasAttribute(SpellAttr3.OnlyTargetGhosts);
|
return HasAttribute(SpellAttr3.OnlyOnGhosts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAllowingDeadTarget()
|
public bool IsAllowingDeadTarget()
|
||||||
@@ -594,7 +594,7 @@ namespace Game.Spells
|
|||||||
switch (DmgClass)
|
switch (DmgClass)
|
||||||
{
|
{
|
||||||
case SpellDmgClass.Melee:
|
case SpellDmgClass.Melee:
|
||||||
if (HasAttribute(SpellAttr3.ReqOffhand))
|
if (HasAttribute(SpellAttr3.RequiresOffHandWeapon))
|
||||||
result = WeaponAttackType.OffAttack;
|
result = WeaponAttackType.OffAttack;
|
||||||
else
|
else
|
||||||
result = WeaponAttackType.BaseAttack;
|
result = WeaponAttackType.BaseAttack;
|
||||||
@@ -643,7 +643,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
bool IsAffectedBySpellMods()
|
bool IsAffectedBySpellMods()
|
||||||
{
|
{
|
||||||
return !HasAttribute(SpellAttr3.NoDoneBonus);
|
return !HasAttribute(SpellAttr3.IgnoreCasterModifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsAffectedBySpellMod(SpellModifier mod)
|
public bool IsAffectedBySpellMod(SpellModifier mod)
|
||||||
@@ -1025,9 +1025,9 @@ namespace Game.Spells
|
|||||||
return SpellCastResult.TargetAffectingCombat;
|
return SpellCastResult.TargetAffectingCombat;
|
||||||
|
|
||||||
// only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
|
// only spells with SPELL_ATTR3_ONLY_TARGET_GHOSTS can target ghosts
|
||||||
if (HasAttribute(SpellAttr3.OnlyTargetGhosts) != unitTarget.HasAuraType(AuraType.Ghost))
|
if (HasAttribute(SpellAttr3.OnlyOnGhosts) != unitTarget.HasAuraType(AuraType.Ghost))
|
||||||
{
|
{
|
||||||
if (HasAttribute(SpellAttr3.OnlyTargetGhosts))
|
if (HasAttribute(SpellAttr3.OnlyOnGhosts))
|
||||||
return SpellCastResult.TargetNotGhost;
|
return SpellCastResult.TargetNotGhost;
|
||||||
else
|
else
|
||||||
return SpellCastResult.BadTargets;
|
return SpellCastResult.BadTargets;
|
||||||
@@ -1089,7 +1089,7 @@ namespace Game.Spells
|
|||||||
return SpellCastResult.SpellCastOk;
|
return SpellCastResult.SpellCastOk;
|
||||||
|
|
||||||
// corpseOwner and unit specific target checks
|
// corpseOwner and unit specific target checks
|
||||||
if (HasAttribute(SpellAttr3.OnlyTargetPlayers) && !unitTarget.IsTypeId(TypeId.Player))
|
if (HasAttribute(SpellAttr3.OnlyOnPlayer) && !unitTarget.IsTypeId(TypeId.Player))
|
||||||
return SpellCastResult.TargetNotPlayer;
|
return SpellCastResult.TargetNotPlayer;
|
||||||
|
|
||||||
if (!IsAllowingDeadTarget() && !unitTarget.IsAlive())
|
if (!IsAllowingDeadTarget() && !unitTarget.IsAlive())
|
||||||
@@ -2544,7 +2544,7 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!auraSpellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
if (!auraSpellInfo.HasAttribute(SpellAttr3.AlwaysHit))
|
||||||
{
|
{
|
||||||
AuraType auraName = auraSpellEffectInfo.ApplyAuraName;
|
AuraType auraName = auraSpellEffectInfo.ApplyAuraName;
|
||||||
if (auraName != 0)
|
if (auraName != 0)
|
||||||
@@ -2868,7 +2868,7 @@ namespace Game.Spells
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
WeaponAttackType slot = WeaponAttackType.BaseAttack;
|
WeaponAttackType slot = WeaponAttackType.BaseAttack;
|
||||||
if (!HasAttribute(SpellAttr3.MainHand) && HasAttribute(SpellAttr3.ReqOffhand))
|
if (!HasAttribute(SpellAttr3.RequiresMainHandWeapon) && HasAttribute(SpellAttr3.RequiresOffHandWeapon))
|
||||||
slot = WeaponAttackType.OffAttack;
|
slot = WeaponAttackType.OffAttack;
|
||||||
|
|
||||||
speed = unitCaster.GetBaseAttackTime(slot);
|
speed = unitCaster.GetBaseAttackTime(slot);
|
||||||
@@ -3175,7 +3175,7 @@ namespace Game.Spells
|
|||||||
return this;
|
return this;
|
||||||
|
|
||||||
// Client ignores spell with these attributes (sub_53D9D0)
|
// Client ignores spell with these attributes (sub_53D9D0)
|
||||||
if (HasAttribute(SpellAttr0.AuraIsDebuff) || HasAttribute(SpellAttr2.AllowLowLevelBuff) || HasAttribute(SpellAttr3.DrainSoul))
|
if (HasAttribute(SpellAttr0.AuraIsDebuff) || HasAttribute(SpellAttr2.AllowLowLevelBuff) || HasAttribute(SpellAttr3.OnlyProcOnCaster))
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
bool needRankSelection = false;
|
bool needRankSelection = false;
|
||||||
|
|||||||
@@ -2734,7 +2734,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
// spells ignoring hit result should not be binary
|
// spells ignoring hit result should not be binary
|
||||||
if (!spellInfo.HasAttribute(SpellAttr3.IgnoreHitResult))
|
if (!spellInfo.HasAttribute(SpellAttr3.AlwaysHit))
|
||||||
{
|
{
|
||||||
bool setFlag = false;
|
bool setFlag = false;
|
||||||
foreach (var spellEffectInfo in spellInfo.GetEffects())
|
foreach (var spellEffectInfo in spellInfo.GetEffects())
|
||||||
@@ -3185,12 +3185,6 @@ namespace Game.Entities
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Execute
|
|
||||||
ApplySpellFix(new[] { 5308 }, spellInfo =>
|
|
||||||
{
|
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.CantTriggerProc;
|
|
||||||
});
|
|
||||||
|
|
||||||
ApplySpellFix(new[] {
|
ApplySpellFix(new[] {
|
||||||
31347, // Doom
|
31347, // Doom
|
||||||
36327, // Shoot Arcane Explosion Arrow
|
36327, // Shoot Arcane Explosion Arrow
|
||||||
@@ -3340,7 +3334,7 @@ namespace Game.Entities
|
|||||||
// Oscillation Field
|
// Oscillation Field
|
||||||
ApplySpellFix(new[] { 37408 }, spellInfo =>
|
ApplySpellFix(new[] { 37408 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.StackForDiffCasters;
|
spellInfo.AttributesEx3 |= SpellAttr3.DotStackingRule;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Crafty's Ultra-Advanced Proto-Typical Shortening Blaster
|
// Crafty's Ultra-Advanced Proto-Typical Shortening Blaster
|
||||||
@@ -3397,12 +3391,6 @@ namespace Game.Entities
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Vampiric Embrace
|
|
||||||
ApplySpellFix(new[] { 15290 }, spellInfo =>
|
|
||||||
{
|
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.NoInitialAggro;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Earthbind Totem (instant pulse)
|
// Earthbind Totem (instant pulse)
|
||||||
ApplySpellFix(new[] { 6474 }, spellInfo =>
|
ApplySpellFix(new[] { 6474 }, spellInfo =>
|
||||||
{
|
{
|
||||||
@@ -3475,7 +3463,7 @@ namespace Game.Entities
|
|||||||
// Paralyze
|
// Paralyze
|
||||||
ApplySpellFix(new[] { 48278 }, spellInfo =>
|
ApplySpellFix(new[] { 48278 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.StackForDiffCasters;
|
spellInfo.AttributesEx3 |= SpellAttr3.DotStackingRule;
|
||||||
});
|
});
|
||||||
|
|
||||||
ApplySpellFix(new[] {
|
ApplySpellFix(new[] {
|
||||||
@@ -3685,7 +3673,7 @@ namespace Game.Entities
|
|||||||
64381 // Strength of the Pack (Auriaya)
|
64381 // Strength of the Pack (Auriaya)
|
||||||
}, spellInfo =>
|
}, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.StackForDiffCasters;
|
spellInfo.AttributesEx3 |= SpellAttr3.DotStackingRule;
|
||||||
});
|
});
|
||||||
|
|
||||||
ApplySpellFix(new[] {
|
ApplySpellFix(new[] {
|
||||||
@@ -3845,13 +3833,7 @@ namespace Game.Entities
|
|||||||
// Shadow's Fate
|
// Shadow's Fate
|
||||||
ApplySpellFix(new[] { 71169 }, spellInfo =>
|
ApplySpellFix(new[] { 71169 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.StackForDiffCasters;
|
spellInfo.AttributesEx3 |= SpellAttr3.DotStackingRule;
|
||||||
});
|
|
||||||
|
|
||||||
// Lock Players and Tap Chest
|
|
||||||
ApplySpellFix(new[] { 72347 }, spellInfo =>
|
|
||||||
{
|
|
||||||
spellInfo.AttributesEx3 &= ~SpellAttr3.NoInitialAggro;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Resistant Skin (Deathbringer Saurfang adds)
|
// Resistant Skin (Deathbringer Saurfang adds)
|
||||||
@@ -3918,7 +3900,7 @@ namespace Game.Entities
|
|||||||
// Empowered Flare (Blood Prince Council)
|
// Empowered Flare (Blood Prince Council)
|
||||||
ApplySpellFix(new[] { 71708 }, spellInfo =>
|
ApplySpellFix(new[] { 71708 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.NoDoneBonus;
|
spellInfo.AttributesEx3 |= SpellAttr3.IgnoreCasterModifiers;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Swarming Shadows
|
// Swarming Shadows
|
||||||
@@ -3930,7 +3912,7 @@ namespace Game.Entities
|
|||||||
// Corruption
|
// Corruption
|
||||||
ApplySpellFix(new[] { 70602 }, spellInfo =>
|
ApplySpellFix(new[] { 70602 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.StackForDiffCasters;
|
spellInfo.AttributesEx3 |= SpellAttr3.DotStackingRule;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Column of Frost (visual marker)
|
// Column of Frost (visual marker)
|
||||||
@@ -3974,7 +3956,7 @@ namespace Game.Entities
|
|||||||
// Chilled to the Bone
|
// Chilled to the Bone
|
||||||
ApplySpellFix(new[] { 70106 }, spellInfo =>
|
ApplySpellFix(new[] { 70106 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.NoDoneBonus;
|
spellInfo.AttributesEx3 |= SpellAttr3.IgnoreCasterModifiers;
|
||||||
spellInfo.AttributesEx6 |= SpellAttr6.IgnoreCasterDamageModifiers;
|
spellInfo.AttributesEx6 |= SpellAttr6.IgnoreCasterDamageModifiers;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -4024,7 +4006,7 @@ namespace Game.Entities
|
|||||||
// Harvest Soul
|
// Harvest Soul
|
||||||
ApplySpellFix(new[] { 73655 }, spellInfo =>
|
ApplySpellFix(new[] { 73655 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.NoDoneBonus;
|
spellInfo.AttributesEx3 |= SpellAttr3.IgnoreCasterModifiers;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Summon Shadow Trap
|
// Summon Shadow Trap
|
||||||
@@ -4194,12 +4176,6 @@ namespace Game.Entities
|
|||||||
spellInfo.Stances = 1ul << ((int)ShapeShiftForm.TreeOfLife - 1);
|
spellInfo.Stances = 1ul << ((int)ShapeShiftForm.TreeOfLife - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Feral Charge (Cat Form)
|
|
||||||
ApplySpellFix(new[] { 49376 }, spellInfo =>
|
|
||||||
{
|
|
||||||
spellInfo.AttributesEx3 &= ~SpellAttr3.CantTriggerProc;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Gaze of Occu'thar
|
// Gaze of Occu'thar
|
||||||
ApplySpellFix(new[] { 96942 }, spellInfo =>
|
ApplySpellFix(new[] { 96942 }, spellInfo =>
|
||||||
{
|
{
|
||||||
@@ -4254,13 +4230,13 @@ namespace Game.Entities
|
|||||||
// Baron Rivendare (Stratholme) - Unholy Aura
|
// Baron Rivendare (Stratholme) - Unholy Aura
|
||||||
ApplySpellFix(new [] { 17466, 17467 }, spellInfo =>
|
ApplySpellFix(new [] { 17466, 17467 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.NoInitialAggro;
|
spellInfo.AttributesEx2 |= SpellAttr2.NoInitialThreat;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Spore - Spore Visual
|
// Spore - Spore Visual
|
||||||
ApplySpellFix(new[] { 42525 }, spellInfo =>
|
ApplySpellFix(new[] { 42525 }, spellInfo =>
|
||||||
{
|
{
|
||||||
spellInfo.AttributesEx3 |= SpellAttr3.DeathPersistent;
|
spellInfo.AttributesEx3 |= SpellAttr3.AllowAuraWhileDead;
|
||||||
spellInfo.AttributesEx2 |= SpellAttr2.AllowDeadTarget;
|
spellInfo.AttributesEx2 |= SpellAttr2.AllowDeadTarget;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user