Core/Auras: Defined and implemented many new interrupt flags
Port From (https://github.com/TrinityCore/TrinityCore/commit/9b5a46ca2bb3a4632cb9914e0899df611a47d935)
This commit is contained in:
@@ -1604,8 +1604,6 @@ namespace Framework.Constants
|
||||
|
||||
public enum MountFlags : ushort
|
||||
{
|
||||
CanPitch = 0x4, // client checks MOVEMENTFLAG2_FULL_SPEED_PITCHING
|
||||
CanSwim = 0x8, // client checks MOVEMENTFLAG_SWIMMING
|
||||
SelfMount = 0x02, // Player becomes the mount himself
|
||||
FactionSpecific = 0x04,
|
||||
PreferredSwimming = 0x10,
|
||||
|
||||
@@ -107,48 +107,71 @@ namespace Framework.Constants
|
||||
AbortOnDmg = 0x10 // _complete_ interrupt on direct damage
|
||||
//SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph"
|
||||
}
|
||||
public enum SpellChannelInterruptFlags
|
||||
{
|
||||
Interrupt = 0x08, // interrupt
|
||||
Delay = 0x4000
|
||||
}
|
||||
|
||||
public enum SpellAuraInterruptFlags : uint
|
||||
{
|
||||
Hitbyspell = 0x01, // 0 Removed When Getting Hit By A Negative Spell?
|
||||
TakeDamage = 0x02, // 1 Removed By Any Damage
|
||||
Cast = 0x04, // 2 Cast Any Spells
|
||||
Move = 0x08, // 3 Removed By Any Movement
|
||||
Turning = 0x10, // 4 Removed By Any Turning
|
||||
Jump = 0x20, // 5 Removed By Jumping
|
||||
NotMounted = 0x40, // 6 Removed By Dismounting
|
||||
NotAbovewater = 0x80, // 7 Removed By Entering Water
|
||||
NotUnderwater = 0x100, // 8 Removed By Leaving Water
|
||||
NotSheathed = 0x200, // 9 Removed By Unsheathing
|
||||
Talk = 0x400, // 10 Talk To Npc / Loot? Action On Creature
|
||||
Use = 0x800, // 11 Mine/Use/Open Action On Gameobject
|
||||
MeleeAttack = 0x1000, // 12 Removed By Attacking
|
||||
SpellAttack = 0x2000, // 13 ???
|
||||
Unk14 = 0x4000, // 14
|
||||
Transform = 0x8000, // 15 Removed By Transform?
|
||||
Unk16 = 0x10000, // 16
|
||||
Mount = 0x20000, // 17 Misdirect, Aspect, Swim Speed
|
||||
NotSeated = 0x40000, // 18 Removed By Standing Up (Used By Food And Drink Mostly And Sleep/Fake Death Like)
|
||||
ChangeMap = 0x80000, // 19 Leaving Map/Getting Teleported
|
||||
ImmuneOrLostSelection = 0x100000, // 20 Removed By Auras That Make You Invulnerable, Or Make Other To Lose Selection On You
|
||||
Unk21 = 0x200000, // 21
|
||||
Teleported = 0x400000, // 22
|
||||
EnterPvpCombat = 0x800000, // 23 Removed By Entering Pvp Combat
|
||||
DirectDamage = 0x1000000, // 24 Removed By Any Direct Damage
|
||||
Landing = 0x2000000, // 25 Removed By Hitting The Ground
|
||||
LeaveCombat = 0x80000000, // 31 removed by leaving combat
|
||||
None = 0,
|
||||
HostileActionReceived = 0x01,
|
||||
Damage = 0x02,
|
||||
Action = 0x04,
|
||||
Moving = 0x08,
|
||||
Turning = 0x10,
|
||||
Anim = 0x20,
|
||||
Dismount = 0x40,
|
||||
UnderWater = 0x80, // TODO: disallow casting when swimming (SPELL_FAILED_ONLY_ABOVEWATER)
|
||||
AboveWater = 0x100, // TODO: disallow casting when not swimming (SPELL_FAILED_ONLY_UNDERWATER)
|
||||
Sheathing = 0x200,
|
||||
Interacting = 0x400, // TODO: more than gossip, replace all the feign death removals by aura type
|
||||
Looting = 0x800,
|
||||
Attacking = 0x1000,
|
||||
ItemUse = 0x2000,
|
||||
DamageChannelDuration = 0x4000,
|
||||
Shapeshifting = 0x8000,
|
||||
ActionDelayed = 0x10000,
|
||||
Mount = 0x20000,
|
||||
Standing = 0x40000,
|
||||
LeaveWorld = 0x80000,
|
||||
StealthOrInvis = 0x100000,
|
||||
InvulnerabilityBuff = 0x200000,
|
||||
EnterWorld = 0x400000,
|
||||
PvPActive = 0x800000,
|
||||
NonPeriodicDamage = 0x1000000,
|
||||
LandingOrFlight = 0x2000000,
|
||||
Release = 0x4000000,
|
||||
DamageCancelsScript = 0x8000000, // NYI dedicated aura script hook
|
||||
EnteringCombat = 0x10000000,
|
||||
Login = 0x20000000,
|
||||
Summon = 0x40000000,
|
||||
LeavingCombat = 0x80000000,
|
||||
|
||||
NotVictim = (Hitbyspell | TakeDamage | DirectDamage)
|
||||
NotVictim = (HostileActionReceived | Damage | NonPeriodicDamage)
|
||||
}
|
||||
|
||||
public enum SpellAuraInterruptFlags2
|
||||
{
|
||||
|
||||
None = 0,
|
||||
Falling = 0x01, // NYI
|
||||
Swimming = 0x02, // NYI
|
||||
NotMoving = 0x04, // NYI
|
||||
Ground = 0x08, // NYI
|
||||
Transform = 0x10, // NYI
|
||||
Jump = 0x20,
|
||||
ChangeSpec = 0x40, // NYI
|
||||
AbandonVehicle = 0x80, // NYI
|
||||
StartOfEncounter = 0x100, // NYI
|
||||
EndOfEncounter = 0x200, // NYI
|
||||
Disconnect = 0x400, // NYI
|
||||
EnteringInstance = 0x800, // NYI
|
||||
DuelEnd = 0x1000, // NYI
|
||||
LeaveArenaOrBattleground = 0x2000, // NYI
|
||||
ChangeTalent = 0x4000, // NYI
|
||||
ChangeGlyph = 0x8000, // NYI
|
||||
SeamlessTransfer = 0x10000, // NYI
|
||||
WarModeLeave = 0x20000, // NYI
|
||||
TouchingGround = 0x40000, // NYI
|
||||
ChromieTime = 0x80000, // NYI
|
||||
SplineFlightOrFreeFlight = 0x100000, // NYI
|
||||
ProcOrPeriodicAttacking = 0x200000 // NYI
|
||||
}
|
||||
|
||||
// Enum with EffectRadiusIndex and their actual radius
|
||||
|
||||
@@ -427,7 +427,7 @@ namespace Game.BattleGrounds.Zones
|
||||
if (!(m_Nodes[node] == 0 || teamIndex == (int)m_Nodes[node] % 2))
|
||||
return;
|
||||
|
||||
source.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterPvpCombat);
|
||||
source.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
||||
uint sound;
|
||||
// If node is neutral, change to contested
|
||||
if (m_Nodes[node] == ABNodeStatus.Neutral)
|
||||
|
||||
@@ -672,7 +672,7 @@ namespace Game.BattleGrounds.Zones
|
||||
SetFlagPicker(player.GetGUID());
|
||||
//get flag aura on player
|
||||
player.CastSpell(player, EotSMisc.SpellNetherstormFlag, true);
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterPvpCombat);
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
||||
|
||||
if (player.GetTeam() == Team.Alliance)
|
||||
SendBroadcastText(EotSBroadcastTexts.TakenFlag, ChatMsg.BgSystemAlliance, player);
|
||||
@@ -803,7 +803,7 @@ namespace Game.BattleGrounds.Zones
|
||||
m_FlagState = EotSFlagState.WaitRespawn;
|
||||
player.RemoveAurasDueToSpell(EotSMisc.SpellNetherstormFlag);
|
||||
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterPvpCombat);
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
||||
|
||||
if (player.GetTeam() == Team.Alliance)
|
||||
{
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace Game.BattleGrounds.Zones
|
||||
|
||||
Team winner = 0;
|
||||
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterPvpCombat);
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
||||
if (player.GetTeam() == Team.Alliance)
|
||||
{
|
||||
if (!IsHordeFlagPickedup())
|
||||
@@ -535,7 +535,7 @@ namespace Game.BattleGrounds.Zones
|
||||
//target_obj.Delete();
|
||||
}
|
||||
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterPvpCombat);
|
||||
player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
||||
}
|
||||
|
||||
public override void RemovePlayer(Player player, ObjectGuid guid, Team team)
|
||||
|
||||
@@ -473,7 +473,7 @@ namespace Game.Combat
|
||||
Cypher.Assert(target); // if the ref has status online the target must be there !
|
||||
|
||||
// some units are prefered in comparison to others
|
||||
if (!noPriorityTargetFound && (target.IsImmunedToDamage(attacker.GetMeleeDamageSchoolMask()) || target.HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags.TakeDamage)))
|
||||
if (!noPriorityTargetFound && (target.IsImmunedToDamage(attacker.GetMeleeDamageSchoolMask()) || target.HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags.Damage)))
|
||||
{
|
||||
if (i != threatList.Count - 1)
|
||||
{
|
||||
|
||||
@@ -1787,7 +1787,7 @@ namespace Game.Entities
|
||||
InterruptNonMeleeSpells(true);
|
||||
|
||||
//remove auras before removing from map...
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ChangeMap | SpellAuraInterruptFlags.Move | SpellAuraInterruptFlags.Turning);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Moving | SpellAuraInterruptFlags.Turning);
|
||||
|
||||
if (!GetSession().PlayerLogout() && !options.HasAnyFlag(TeleportToOptions.Seamless))
|
||||
{
|
||||
@@ -2123,6 +2123,7 @@ namespace Game.Entities
|
||||
m_summon_expire = 0;
|
||||
|
||||
UpdateCriteria(CriteriaTypes.AcceptedSummonings, 1);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Summon);
|
||||
|
||||
m_summon_location.SetOrientation(GetOrientation());
|
||||
TeleportTo(m_summon_location);
|
||||
@@ -4047,6 +4048,8 @@ namespace Game.Entities
|
||||
CastSpell(this, 20584, true);
|
||||
CastSpell(this, 8326, true);
|
||||
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Release);
|
||||
|
||||
// there must be SMSG.FORCE_RUN_SPEED_CHANGE, SMSG.FORCE_SWIM_SPEED_CHANGE, SMSG.MOVE_WATER_WALK
|
||||
// there must be SMSG.STOP_MIRROR_TIMER
|
||||
|
||||
|
||||
@@ -288,7 +288,7 @@ namespace Game.Entities
|
||||
else
|
||||
ToPlayer().OnCombatExit();
|
||||
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.LeaveCombat);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.LeavingCombat);
|
||||
}
|
||||
|
||||
public void ClearInPetCombat()
|
||||
@@ -630,7 +630,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
CombatStart(victim);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.MeleeAttack);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Attacking);
|
||||
|
||||
// ignore ranged case
|
||||
if (attType != WeaponAttackType.BaseAttack && attType != WeaponAttackType.OffAttack)
|
||||
@@ -712,7 +712,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
CombatStart(victim);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.MeleeAttack);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Attacking);
|
||||
|
||||
if (attType != WeaponAttackType.BaseAttack && attType != WeaponAttackType.OffAttack)
|
||||
return; // ignore ranged case
|
||||
@@ -993,14 +993,14 @@ namespace Game.Entities
|
||||
|
||||
if (damagetype != DamageEffectType.NoDamage)
|
||||
{
|
||||
// interrupting auras with AURA_INTERRUPT_FLAG_DAMAGE before checking !damage (absorbed damage breaks that type of auras)
|
||||
// interrupting auras with SpellAuraInterruptFlags.Damage before checking !damage (absorbed damage breaks that type of auras)
|
||||
if (spellProto != null)
|
||||
{
|
||||
if (!spellProto.HasAttribute(SpellAttr4.DamageDoesntBreakAuras))
|
||||
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.TakeDamage, spellProto.Id);
|
||||
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Damage, spellProto.Id);
|
||||
}
|
||||
else
|
||||
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.TakeDamage, 0);
|
||||
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Damage, 0);
|
||||
|
||||
// interrupt spells with SPELL_INTERRUPT_FLAG_ABORT_ON_DMG on absorbed damage (no dots)
|
||||
if (damage == 0 && damagetype != DamageEffectType.DOT && cleanDamage != null && cleanDamage.absorbed_damage != 0)
|
||||
@@ -1140,7 +1140,7 @@ namespace Game.Entities
|
||||
victim.ModifyHealth(-(int)damage);
|
||||
|
||||
if (damagetype == DamageEffectType.Direct || damagetype == DamageEffectType.SpellDirect)
|
||||
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.DirectDamage, spellProto != null ? spellProto.Id : 0);
|
||||
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NonPeriodicDamage, spellProto != null ? spellProto.Id : 0);
|
||||
|
||||
if (!victim.IsTypeId(TypeId.Player))
|
||||
{
|
||||
@@ -1179,6 +1179,7 @@ namespace Game.Entities
|
||||
{
|
||||
Spell spell = victim.GetCurrentSpell(CurrentSpellTypes.Generic);
|
||||
if (spell != null)
|
||||
{
|
||||
if (spell.GetState() == SpellState.Preparing)
|
||||
{
|
||||
var interruptFlags = spell.m_spellInfo.InterruptFlags;
|
||||
@@ -1187,10 +1188,11 @@ namespace Game.Entities
|
||||
else if (interruptFlags.HasAnyFlag(SpellInterruptFlags.PushBack))
|
||||
spell.Delayed();
|
||||
}
|
||||
}
|
||||
}
|
||||
Spell spell1 = victim.GetCurrentSpell(CurrentSpellTypes.Channeled);
|
||||
if (spell1 != null)
|
||||
if (spell1.GetState() == SpellState.Casting && spell1.m_spellInfo.HasChannelInterruptFlag(SpellChannelInterruptFlags.Delay) && damagetype != DamageEffectType.DOT)
|
||||
if (spell1.GetState() == SpellState.Casting && spell1.m_spellInfo.HasChannelInterruptFlag(SpellAuraInterruptFlags.DamageChannelDuration) && damagetype != DamageEffectType.DOT)
|
||||
spell1.DelayedChannel();
|
||||
}
|
||||
}
|
||||
@@ -1352,7 +1354,7 @@ namespace Game.Entities
|
||||
if (me != null && who.IsPvP() && (!who.IsTypeId(TypeId.Player) || me.duel == null || me.duel.opponent != who))
|
||||
{
|
||||
me.UpdatePvP(true);
|
||||
me.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterPvpCombat);
|
||||
me.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.PvPActive);
|
||||
}
|
||||
}
|
||||
public void SetInCombatWith(Unit enemy)
|
||||
@@ -1426,6 +1428,7 @@ namespace Game.Entities
|
||||
foreach (var unit in m_Controlled)
|
||||
unit.SetInCombatState(PvP, enemy);
|
||||
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnteringCombat);
|
||||
ProcSkillsAndAuras(enemy, ProcFlags.EnterCombat, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,8 @@ namespace Game.Entities
|
||||
protected Dictionary<CurrentSpellTypes, Spell> m_currentSpells = new((int)CurrentSpellTypes.Max);
|
||||
Dictionary<SpellValueMod, int> CustomSpellValueMod = new();
|
||||
MultiMap<uint, uint>[] m_spellImmune = new MultiMap<uint, uint>[(int)SpellImmunity.Max];
|
||||
uint[] m_interruptMask = new uint[2];
|
||||
SpellAuraInterruptFlags m_interruptMask;
|
||||
SpellAuraInterruptFlags2 m_interruptMask2;
|
||||
protected int m_procDeep;
|
||||
bool m_AutoRepeatFirstCast;
|
||||
SpellHistory _spellHistory;
|
||||
|
||||
@@ -582,7 +582,7 @@ namespace Game.Entities
|
||||
|
||||
if (relocated)
|
||||
{
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Move);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Moving);
|
||||
|
||||
// move and update visible state if need
|
||||
if (IsTypeId(TypeId.Player))
|
||||
@@ -787,9 +787,9 @@ namespace Game.Entities
|
||||
{
|
||||
// remove appropriate auras if we are swimming/not swimming respectively
|
||||
if (inWater)
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotAbovewater);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.UnderWater);
|
||||
else
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotUnderwater);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.AboveWater);
|
||||
}
|
||||
|
||||
public virtual void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> liquidData)
|
||||
@@ -1348,7 +1348,7 @@ namespace Game.Entities
|
||||
RemoveVehicleKit();
|
||||
}
|
||||
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotMounted);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Dismount);
|
||||
|
||||
// only resummon old pet if the player is already added to a map
|
||||
// this prevents adding a pet to a not created map which would otherwise cause a crash
|
||||
|
||||
@@ -1476,7 +1476,7 @@ namespace Game.Entities
|
||||
var auras = GetAuraEffectsByType(type);
|
||||
foreach (var eff in auras)
|
||||
if ((excludeAura == 0 || excludeAura != eff.GetSpellInfo().Id) && //Avoid self interrupt of channeled Crowd Control spells like Seduction
|
||||
eff.GetSpellInfo().HasAuraInterruptFlag(SpellAuraInterruptFlags.TakeDamage))
|
||||
eff.GetSpellInfo().HasAuraInterruptFlag(SpellAuraInterruptFlags.Damage))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -2913,11 +2913,12 @@ namespace Game.Entities
|
||||
}
|
||||
public void UpdateInterruptMask()
|
||||
{
|
||||
m_interruptMask.Clear();
|
||||
m_interruptMask = SpellAuraInterruptFlags.None;
|
||||
m_interruptMask2 = SpellAuraInterruptFlags2.None;
|
||||
foreach (AuraApplication aurApp in m_interruptableAuras)
|
||||
{
|
||||
for (var i = 0; i < m_interruptMask.Length; ++i)
|
||||
m_interruptMask[i] |= aurApp.GetBase().GetSpellInfo().AuraInterruptFlags[i];
|
||||
m_interruptMask |= aurApp.GetBase().GetSpellInfo().AuraInterruptFlags;
|
||||
m_interruptMask2 |= aurApp.GetBase().GetSpellInfo().AuraInterruptFlags2;
|
||||
}
|
||||
|
||||
Spell spell = GetCurrentSpell(CurrentSpellTypes.Channeled);
|
||||
@@ -2925,8 +2926,8 @@ namespace Game.Entities
|
||||
{
|
||||
if (spell.GetState() == SpellState.Casting)
|
||||
{
|
||||
for (var i = 0; i < m_interruptMask.Length; ++i)
|
||||
m_interruptMask[i] |= spell.m_spellInfo.ChannelInterruptFlags[i];
|
||||
m_interruptMask |= spell.m_spellInfo.ChannelInterruptFlags;
|
||||
m_interruptMask2 |= spell.m_spellInfo.ChannelInterruptFlags2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3161,27 +3162,32 @@ namespace Game.Entities
|
||||
|
||||
public bool HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags flag, ObjectGuid guid = default)
|
||||
{
|
||||
return HasNegativeAuraWithInterruptFlag((uint)flag, 0, guid);
|
||||
}
|
||||
|
||||
public bool HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags2 flag, ObjectGuid guid = default)
|
||||
{
|
||||
return HasNegativeAuraWithInterruptFlag((uint)flag, 1, guid);
|
||||
}
|
||||
|
||||
public bool HasNegativeAuraWithInterruptFlag(uint flag, int index, ObjectGuid guid = default)
|
||||
{
|
||||
if (!Convert.ToBoolean(m_interruptMask[index] & flag))
|
||||
if (!HasInterruptFlag(flag))
|
||||
return false;
|
||||
|
||||
foreach (var aura in m_interruptableAuras)
|
||||
{
|
||||
if (!aura.IsPositive() && Convert.ToBoolean(aura.GetBase().GetSpellInfo().AuraInterruptFlags[index] & flag)
|
||||
if (!aura.IsPositive() && aura.GetBase().GetSpellInfo().HasAuraInterruptFlag(flag)
|
||||
&& (guid.IsEmpty() || aura.GetBase().GetCasterGUID() == guid))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool HasNegativeAuraWithInterruptFlag(SpellAuraInterruptFlags2 flag, ObjectGuid guid = default)
|
||||
{
|
||||
if (!HasInterruptFlag(flag))
|
||||
return false;
|
||||
|
||||
foreach (var aura in m_interruptableAuras)
|
||||
{
|
||||
if (!aura.IsPositive() && aura.GetBase().GetSpellInfo().HasAuraInterruptFlag(flag)
|
||||
&& (guid.IsEmpty() || aura.GetBase().GetCasterGUID() == guid))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasNegativeAuraWithAttribute(SpellAttr0 flag, ObjectGuid guid = default)
|
||||
{
|
||||
foreach (var list in GetAppliedAuras())
|
||||
@@ -3267,19 +3273,18 @@ namespace Game.Entities
|
||||
return dispelList;
|
||||
}
|
||||
|
||||
bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags2 flag, Unit unit, SpellInfo spellInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags flag, Unit unit, SpellInfo spellInfo)
|
||||
{
|
||||
return flag == SpellAuraInterruptFlags.Moving && unit.HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, spellInfo);
|
||||
}
|
||||
|
||||
public void RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags flag, uint except = 0)
|
||||
{
|
||||
RemoveAurasWithInterruptFlags((uint)flag, 0, except);
|
||||
}
|
||||
|
||||
public void RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2 flag, uint except = 0)
|
||||
{
|
||||
RemoveAurasWithInterruptFlags((uint)flag, 1, except);
|
||||
}
|
||||
|
||||
void RemoveAurasWithInterruptFlags(uint flag, int index, uint except = 0)
|
||||
{
|
||||
if (!Convert.ToBoolean(m_interruptMask[index] & flag))
|
||||
if (!HasInterruptFlag(flag))
|
||||
return;
|
||||
|
||||
// interrupt auras
|
||||
@@ -3287,8 +3292,7 @@ namespace Game.Entities
|
||||
{
|
||||
Aura aura = m_interruptableAuras[i].GetBase();
|
||||
|
||||
if (Convert.ToBoolean(aura.GetSpellInfo().AuraInterruptFlags[index] & flag) && (except == 0 || aura.GetId() != except)
|
||||
&& !(Convert.ToBoolean(flag & (uint)SpellAuraInterruptFlags.Move) && HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, aura.GetSpellInfo())))
|
||||
if (aura.GetSpellInfo().HasAuraInterruptFlag(flag) && (except == 0 || aura.GetId() != except) && !IsInterruptFlagIgnoredForSpell(flag, this, aura.GetSpellInfo()))
|
||||
{
|
||||
uint removedAuras = m_removedAurasCount;
|
||||
RemoveAura(aura, AuraRemoveMode.Interrupt);
|
||||
@@ -3302,9 +3306,43 @@ namespace Game.Entities
|
||||
if (spell != null)
|
||||
{
|
||||
if (spell.GetState() == SpellState.Casting
|
||||
&& Convert.ToBoolean(spell.GetSpellInfo().ChannelInterruptFlags[index] & flag)
|
||||
&& spell.GetSpellInfo().HasChannelInterruptFlag(flag)
|
||||
&& spell.GetSpellInfo().Id != except
|
||||
&& !(Convert.ToBoolean(flag & (uint)SpellAuraInterruptFlags.Move) && HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, spell.GetSpellInfo())))
|
||||
&& !IsInterruptFlagIgnoredForSpell(flag, this, spell.GetSpellInfo()))
|
||||
InterruptNonMeleeSpells(false);
|
||||
}
|
||||
|
||||
UpdateInterruptMask();
|
||||
|
||||
}
|
||||
|
||||
public void RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2 flag, uint except = 0)
|
||||
{
|
||||
if (!HasInterruptFlag(flag))
|
||||
return;
|
||||
|
||||
// interrupt auras
|
||||
for (var i = 0; i < m_interruptableAuras.Count; i++)
|
||||
{
|
||||
Aura aura = m_interruptableAuras[i].GetBase();
|
||||
|
||||
if (aura.GetSpellInfo().HasAuraInterruptFlag(flag) && (except == 0 || aura.GetId() != except) && !IsInterruptFlagIgnoredForSpell(flag, this, aura.GetSpellInfo()))
|
||||
{
|
||||
uint removedAuras = m_removedAurasCount;
|
||||
RemoveAura(aura, AuraRemoveMode.Interrupt);
|
||||
if (m_removedAurasCount > removedAuras + 1)
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// interrupt channeled spell
|
||||
Spell spell = GetCurrentSpell(CurrentSpellTypes.Channeled);
|
||||
if (spell != null)
|
||||
{
|
||||
if (spell.GetState() == SpellState.Casting
|
||||
&& spell.GetSpellInfo().HasChannelInterruptFlag(flag)
|
||||
&& spell.GetSpellInfo().Id != except
|
||||
&& !IsInterruptFlagIgnoredForSpell(flag, this, spell.GetSpellInfo()))
|
||||
InterruptNonMeleeSpells(false);
|
||||
}
|
||||
|
||||
@@ -4173,7 +4211,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
// Sitdown on apply aura req seated
|
||||
if (aura.GetSpellInfo().HasAuraInterruptFlag(SpellAuraInterruptFlags.NotSeated) && !IsSitState())
|
||||
if (aura.GetSpellInfo().HasAuraInterruptFlag(SpellAuraInterruptFlags.Standing) && !IsSitState())
|
||||
SetStandState(UnitStandStateType.Sit);
|
||||
|
||||
Unit caster = aura.GetCaster();
|
||||
|
||||
@@ -434,6 +434,13 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddToWorld()
|
||||
{
|
||||
base.AddToWorld();
|
||||
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnterWorld);
|
||||
}
|
||||
|
||||
public override void RemoveFromWorld()
|
||||
{
|
||||
// cleanup
|
||||
@@ -447,6 +454,7 @@ namespace Game.Entities
|
||||
RemoveCharmAuras();
|
||||
RemoveAurasByType(AuraType.BindSight);
|
||||
RemoveNotOwnSingleTargetAuras();
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.LeaveWorld);
|
||||
|
||||
RemoveAllGameObjects();
|
||||
RemoveAllDynObjects();
|
||||
@@ -1552,7 +1560,7 @@ namespace Game.Entities
|
||||
if (aurSpellInfo.HasAnyAuraInterruptFlag())
|
||||
{
|
||||
m_interruptableAuras.Add(aurApp);
|
||||
AddInterruptMask(aurSpellInfo.AuraInterruptFlags);
|
||||
AddInterruptMask(aurSpellInfo.AuraInterruptFlags, aurSpellInfo.AuraInterruptFlags2);
|
||||
}
|
||||
|
||||
AuraStateType aState = aura.GetSpellInfo().GetAuraState();
|
||||
@@ -1562,10 +1570,14 @@ namespace Game.Entities
|
||||
aura._ApplyForTarget(this, caster, aurApp);
|
||||
return aurApp;
|
||||
}
|
||||
public void AddInterruptMask(uint[] mask)
|
||||
|
||||
bool HasInterruptFlag(SpellAuraInterruptFlags flags) { return m_interruptMask.HasFlag(flags); }
|
||||
bool HasInterruptFlag(SpellAuraInterruptFlags2 flags) { return m_interruptMask2.HasFlag(flags); }
|
||||
|
||||
public void AddInterruptMask(SpellAuraInterruptFlags flags, SpellAuraInterruptFlags2 flags2)
|
||||
{
|
||||
for (int i = 0; i < m_interruptMask.Length; ++i)
|
||||
m_interruptMask[i] |= mask[i];
|
||||
m_interruptMask |= flags;
|
||||
m_interruptMask2 |= flags2;
|
||||
}
|
||||
|
||||
void _UpdateAutoRepeatSpell()
|
||||
@@ -1673,6 +1685,13 @@ namespace Game.Entities
|
||||
SetPowerType(displayPower);
|
||||
}
|
||||
|
||||
public void SetSheath(SheathState sheathed)
|
||||
{
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.SheatheState), (byte)sheathed);
|
||||
if (sheathed == SheathState.Unarmed)
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Sheathing);
|
||||
}
|
||||
|
||||
public FactionTemplateRecord GetFactionTemplateEntry()
|
||||
{
|
||||
FactionTemplateRecord entry = CliDB.FactionTemplateStorage.LookupByKey(GetFaction());
|
||||
@@ -2030,7 +2049,6 @@ namespace Game.Entities
|
||||
public void SetEmoteState(Emote emote) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.EmoteState), (int)emote); }
|
||||
|
||||
public SheathState GetSheath() { return (SheathState)(byte)m_unitData.SheatheState; }
|
||||
public void SetSheath(SheathState sheathed) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.SheatheState), (byte)sheathed); }
|
||||
|
||||
public uint GetCombatTimer() { return combatTimer; }
|
||||
public UnitPVPStateFlags GetPvpFlags() { return (UnitPVPStateFlags)(byte)m_unitData.PvpFlags; }
|
||||
@@ -2364,7 +2382,7 @@ namespace Game.Entities
|
||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StandState), (byte)state);
|
||||
|
||||
if (IsStandState())
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.NotSeated);
|
||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Standing);
|
||||
|
||||
if (IsTypeId(TypeId.Player))
|
||||
{
|
||||
|
||||
@@ -825,6 +825,9 @@ namespace Game
|
||||
pCurrChar.SetInGuild(0);
|
||||
}
|
||||
}
|
||||
|
||||
pCurrChar.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Login);
|
||||
|
||||
pCurrChar.SendInitialPacketsAfterAddToMap();
|
||||
|
||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_CHAR_ONLINE);
|
||||
|
||||
@@ -571,9 +571,9 @@ namespace Game
|
||||
if (em == null)
|
||||
return;
|
||||
|
||||
uint emote_anim = em.EmoteId;
|
||||
Emote emoteAnim = (Emote)em.EmoteId;
|
||||
|
||||
switch ((Emote)emote_anim)
|
||||
switch (emoteAnim)
|
||||
{
|
||||
case Emote.StateSleep:
|
||||
case Emote.StateSit:
|
||||
@@ -582,13 +582,13 @@ namespace Game
|
||||
break;
|
||||
case Emote.StateDance:
|
||||
case Emote.StateRead:
|
||||
GetPlayer().SetEmoteState((Emote)emote_anim);
|
||||
GetPlayer().SetEmoteState(emoteAnim);
|
||||
break;
|
||||
default:
|
||||
// Only allow text-emotes for "dead" entities (feign death included)
|
||||
if (GetPlayer().HasUnitState(UnitState.Died))
|
||||
break;
|
||||
GetPlayer().HandleEmoteCommand((Emote)emote_anim);
|
||||
GetPlayer().HandleEmoteCommand(emoteAnim);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -611,6 +611,9 @@ namespace Game
|
||||
if (creature)
|
||||
creature.GetAI().ReceiveEmote(GetPlayer(), (TextEmotes)packet.EmoteID);
|
||||
}
|
||||
|
||||
if (emoteAnim != Emote.OneshotNone)
|
||||
_player.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Anim);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.ChatReportIgnored)]
|
||||
|
||||
@@ -297,6 +297,8 @@ namespace Game
|
||||
// interrupt cast
|
||||
if (GetPlayer().IsNonMeleeSpellCast(false))
|
||||
GetPlayer().InterruptNonMeleeSpells(false);
|
||||
|
||||
GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Looting);
|
||||
}
|
||||
|
||||
[WorldPacketHandler(ClientOpcodes.LootRelease)]
|
||||
|
||||
@@ -137,8 +137,8 @@ namespace Game
|
||||
plrMover.HandleFall(movementInfo);
|
||||
|
||||
// interrupt parachutes upon falling or landing in water
|
||||
if (opcode == ClientOpcodes.MoveFallLand || opcode == ClientOpcodes.MoveStartSwim)
|
||||
mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Landing); // Parachutes
|
||||
if (opcode == ClientOpcodes.MoveFallLand || opcode == ClientOpcodes.MoveStartSwim || opcode == ClientOpcodes.MoveSetFly)
|
||||
mover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.LandingOrFlight); // Parachutes
|
||||
|
||||
uint mstime = GameTime.GetGameTimeMS();
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace Game
|
||||
|
||||
if (opcode == ClientOpcodes.MoveJump)
|
||||
{
|
||||
plrMover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Jump, 605); // Mind Control
|
||||
plrMover.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags2.Jump); // Mind Control
|
||||
plrMover.ProcSkillsAndAuras(null, ProcFlags.Jump, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace Game
|
||||
if (factionTemplateEntry != null)
|
||||
GetPlayer().GetReputationMgr().SetVisible(factionTemplateEntry);
|
||||
|
||||
GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Talk);
|
||||
GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Interacting);
|
||||
|
||||
// Stop the npc if moving
|
||||
unit.PauseMovement(WorldConfig.GetUIntValue(WorldCfg.CreatureStopForPlayer));
|
||||
|
||||
@@ -115,6 +115,8 @@ namespace Game
|
||||
}
|
||||
}
|
||||
|
||||
user.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ItemUse);
|
||||
|
||||
SpellCastTargets targets = new(user, packet.Cast);
|
||||
|
||||
// Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
|
||||
|
||||
@@ -919,7 +919,7 @@ namespace Game.Spells
|
||||
if (apply && mode.HasAnyFlag(AuraEffectHandleModes.Real))
|
||||
{
|
||||
// drop flag at invisibiliy in bg
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.StealthOrInvis);
|
||||
}
|
||||
target.UpdateObjectVisibility();
|
||||
}
|
||||
@@ -987,7 +987,7 @@ namespace Game.Spells
|
||||
if (apply && mode.HasAnyFlag(AuraEffectHandleModes.Real))
|
||||
{
|
||||
// drop flag at stealth in bg
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.StealthOrInvis);
|
||||
}
|
||||
target.UpdateObjectVisibility();
|
||||
}
|
||||
@@ -1113,14 +1113,7 @@ namespace Game.Spells
|
||||
Unit target = aurApp.GetTarget();
|
||||
|
||||
if (apply)
|
||||
{
|
||||
PhasingHandler.AddPhase(target, (uint)GetMiscValueB(), true);
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
// phase auras normally not expected at BG but anyway better check
|
||||
// drop flag at invisibiliy in bg
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||
}
|
||||
else
|
||||
PhasingHandler.RemovePhase(target, (uint)GetMiscValueB(), true);
|
||||
}
|
||||
@@ -1134,14 +1127,7 @@ namespace Game.Spells
|
||||
Unit target = aurApp.GetTarget();
|
||||
|
||||
if (apply)
|
||||
{
|
||||
PhasingHandler.AddPhaseGroup(target, (uint)GetMiscValueB(), true);
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
// phase auras normally not expected at BG but anyway better check
|
||||
// drop flag at invisibiliy in bg
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||
}
|
||||
else
|
||||
PhasingHandler.RemovePhaseGroup(target, (uint)GetMiscValueB(), true);
|
||||
}
|
||||
@@ -1226,6 +1212,9 @@ namespace Game.Spells
|
||||
if (transformSpellInfo == null || !GetSpellInfo().IsPositive())
|
||||
target.SetDisplayId(modelid);
|
||||
}
|
||||
|
||||
if (!shapeInfo.Flags.HasAnyFlag(SpellShapeshiftFormFlags.Stance))
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Shapeshifting, GetId());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1602,7 +1591,6 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
target.CombatStop();
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||
|
||||
// prevent interrupt message
|
||||
if (GetCasterGUID() == target.GetGUID() && target.GetCurrentSpell(CurrentSpellTypes.Generic) != null)
|
||||
@@ -1647,10 +1635,7 @@ namespace Game.Spells
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
if (apply && mode.HasAnyFlag(AuraEffectHandleModes.Real))
|
||||
{
|
||||
target.CombatStop();
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||
}
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.ModDisarm)]
|
||||
@@ -2686,8 +2671,9 @@ namespace Game.Spells
|
||||
m_spellInfo.ApplyAllSpellImmunitiesTo(target, GetSpellEffectInfo(), apply);
|
||||
|
||||
// when removing flag aura, handle flag drop
|
||||
// TODO: this should be handled in aura script for flag spells using AfterEffectRemove hook
|
||||
Player player = target.ToPlayer();
|
||||
if (!apply && player != null && GetSpellInfo().HasAuraInterruptFlag(SpellAuraInterruptFlags.ImmuneOrLostSelection))
|
||||
if (!apply && player != null && GetSpellInfo().HasAuraInterruptFlag(SpellAuraInterruptFlags.StealthOrInvis))
|
||||
{
|
||||
if (player.InBattleground())
|
||||
{
|
||||
@@ -2741,13 +2727,16 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
|
||||
if (apply && GetMiscValue() == (int)SpellSchoolMask.Normal)
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||
// TODO: should be changed to a proc script on flag spell (they have "Taken positive" proc flags in db2)
|
||||
{
|
||||
if (apply && GetMiscValue() == (int)SpellSchoolMask.Normal)
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.StealthOrInvis);
|
||||
|
||||
// remove all flag auras (they are positive, but they must be removed when you are immune)
|
||||
if (GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity)
|
||||
&& GetSpellInfo().HasAttribute(SpellAttr2.DamageReducedShield))
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ImmuneOrLostSelection);
|
||||
// remove all flag auras (they are positive, but they must be removed when you are immune)
|
||||
if (GetSpellInfo().HasAttribute(SpellAttr1.DispelAurasOnImmunity)
|
||||
&& GetSpellInfo().HasAttribute(SpellAttr2.DamageReducedShield))
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.StealthOrInvis);
|
||||
}
|
||||
}
|
||||
|
||||
[AuraEffectHandler(AuraType.DamageImmunity)]
|
||||
|
||||
@@ -2007,7 +2007,7 @@ namespace Game.Spells
|
||||
// Failed Pickpocket, reveal rogue
|
||||
if (missInfo == SpellMissInfo.Resist && m_spellInfo.HasAttribute(SpellCustomAttributes.PickPocket) && unitTarget.IsTypeId(TypeId.Unit))
|
||||
{
|
||||
m_caster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Talk);
|
||||
m_caster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Interacting);
|
||||
unitTarget.ToCreature().EngageWithTarget(m_caster);
|
||||
}
|
||||
}
|
||||
@@ -2096,7 +2096,7 @@ namespace Game.Spells
|
||||
return SpellMissInfo.Evade;
|
||||
|
||||
if (m_caster._IsValidAttackTarget(unit, m_spellInfo))
|
||||
unit.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Hitbyspell);
|
||||
unit.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.HostileActionReceived);
|
||||
else if (m_caster.IsFriendlyTo(unit))
|
||||
{
|
||||
// for delayed spells ignore negative spells (after duel end) for friendly targets
|
||||
@@ -2556,17 +2556,7 @@ namespace Game.Spells
|
||||
// stealth must be removed at cast starting (at show channel bar)
|
||||
// skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
|
||||
if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreAuraInterruptFlags) && m_spellInfo.IsBreakingStealth())
|
||||
{
|
||||
m_caster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Cast);
|
||||
foreach (SpellEffectInfo effect in m_spellInfo.GetEffects())
|
||||
{
|
||||
if (effect != null && effect.GetUsedTargetObjectType() == SpellTargetObjectTypes.Unit)
|
||||
{
|
||||
m_caster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.SpellAttack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_caster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Action);
|
||||
|
||||
m_caster.SetCurrentCastSpell(this);
|
||||
|
||||
@@ -2917,6 +2907,7 @@ namespace Game.Spells
|
||||
if (!hitMask.HasAnyFlag(ProcFlagsHit.Critical))
|
||||
hitMask |= ProcFlagsHit.Normal;
|
||||
|
||||
m_originalCaster.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.ActionDelayed);
|
||||
m_originalCaster.ProcSkillsAndAuras(null, procAttacker, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Cast, hitMask, this, null, null);
|
||||
|
||||
// Call CreatureAI hook OnSuccessfulSpellCast
|
||||
@@ -2943,13 +2934,13 @@ namespace Game.Spells
|
||||
m_caster.ModSpellDurationTime(m_spellInfo, ref duration, this);
|
||||
|
||||
m_spellState = SpellState.Casting;
|
||||
m_caster.AddInterruptMask(m_spellInfo.ChannelInterruptFlags);
|
||||
m_caster.AddInterruptMask(m_spellInfo.ChannelInterruptFlags, m_spellInfo.ChannelInterruptFlags2);
|
||||
SendChannelStart((uint)duration);
|
||||
}
|
||||
else if (duration == -1)
|
||||
{
|
||||
m_spellState = SpellState.Casting;
|
||||
m_caster.AddInterruptMask(m_spellInfo.ChannelInterruptFlags);
|
||||
m_caster.AddInterruptMask(m_spellInfo.ChannelInterruptFlags, m_spellInfo.ChannelInterruptFlags2);
|
||||
SendChannelStart((uint)duration);
|
||||
}
|
||||
}
|
||||
@@ -4591,7 +4582,7 @@ namespace Game.Spells
|
||||
// skip stuck spell to allow use it in falling case and apply spell limitations at movement
|
||||
SpellEffectInfo effect = m_spellInfo.GetEffect(0);
|
||||
if ((!m_caster.HasUnitMovementFlag(MovementFlag.FallingFar) || (effect != null && effect.Effect != SpellEffectName.Stuck)) &&
|
||||
(IsAutoRepeat() || m_spellInfo.HasAuraInterruptFlag(SpellAuraInterruptFlags.NotSeated)))
|
||||
(IsAutoRepeat() || m_spellInfo.HasAuraInterruptFlag(SpellAuraInterruptFlags.Standing)))
|
||||
return SpellCastResult.Moving;
|
||||
}
|
||||
|
||||
|
||||
@@ -2698,7 +2698,7 @@ namespace Game.Spells
|
||||
|| (spell.GetState() == SpellState.Preparing && spell.GetCastTime() > 0.0f))
|
||||
&& (curSpellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence))
|
||||
&& ((i == CurrentSpellTypes.Generic && curSpellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.Interrupt))
|
||||
|| (i == CurrentSpellTypes.Channeled && curSpellInfo.HasChannelInterruptFlag(SpellChannelInterruptFlags.Interrupt))))
|
||||
|| (i == CurrentSpellTypes.Channeled)))
|
||||
{
|
||||
if (m_originalCaster != null)
|
||||
{
|
||||
|
||||
@@ -179,8 +179,10 @@ namespace Game.Spells
|
||||
if (_interrupt != null)
|
||||
{
|
||||
InterruptFlags = (SpellInterruptFlags)_interrupt.InterruptFlags;
|
||||
Array.Copy(_interrupt.AuraInterruptFlags, AuraInterruptFlags, 2);
|
||||
Array.Copy(_interrupt.ChannelInterruptFlags, ChannelInterruptFlags, 2);
|
||||
AuraInterruptFlags = (SpellAuraInterruptFlags)_interrupt.AuraInterruptFlags[0];
|
||||
AuraInterruptFlags2 = (SpellAuraInterruptFlags2)_interrupt.AuraInterruptFlags[1];
|
||||
ChannelInterruptFlags = (SpellAuraInterruptFlags)_interrupt.ChannelInterruptFlags[0];
|
||||
ChannelInterruptFlags2 = (SpellAuraInterruptFlags2)_interrupt.ChannelInterruptFlags[1];
|
||||
}
|
||||
|
||||
// SpellLevelsEntry
|
||||
@@ -559,7 +561,7 @@ namespace Game.Spells
|
||||
|
||||
public bool IsMoveAllowedChannel()
|
||||
{
|
||||
return IsChanneled() && (HasAttribute(SpellAttr5.CanChannelWhenMoving) || !ChannelInterruptFlags[0].HasAnyFlag((uint)(SpellAuraInterruptFlags.Move | SpellAuraInterruptFlags.Turning)));
|
||||
return IsChanneled() && (HasAttribute(SpellAttr5.CanChannelWhenMoving) || !ChannelInterruptFlags.HasAnyFlag(SpellAuraInterruptFlags.Moving | SpellAuraInterruptFlags.Turning));
|
||||
}
|
||||
|
||||
public bool NeedsComboPoints()
|
||||
@@ -1447,7 +1449,7 @@ namespace Game.Spells
|
||||
case SpellFamilyNames.Generic:
|
||||
{
|
||||
// Food / Drinks (mostly)
|
||||
if (HasAuraInterruptFlag(SpellAuraInterruptFlags.NotSeated))
|
||||
if (HasAuraInterruptFlag(SpellAuraInterruptFlags.Standing))
|
||||
{
|
||||
bool food = false;
|
||||
bool drink = false;
|
||||
@@ -2405,6 +2407,9 @@ namespace Game.Spells
|
||||
auraSpellInfo.Id != Id); // Don't remove self
|
||||
});
|
||||
}
|
||||
|
||||
if (apply && (schoolImmunity & (uint)SpellSchoolMask.Normal) != 0)
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.InvulnerabilityBuff);
|
||||
}
|
||||
|
||||
uint mechanicImmunity = immuneInfo.MechanicImmuneMask;
|
||||
@@ -2438,8 +2443,13 @@ namespace Game.Spells
|
||||
|
||||
uint damageImmunity = immuneInfo.DamageSchoolMask;
|
||||
if (damageImmunity != 0)
|
||||
{
|
||||
target.ApplySpellImmune(Id, SpellImmunity.Damage, damageImmunity, apply);
|
||||
|
||||
if (apply && (damageImmunity & (uint)SpellSchoolMask.Normal) != 0)
|
||||
target.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.InvulnerabilityBuff);
|
||||
}
|
||||
|
||||
foreach (AuraType auraType in immuneInfo.AuraTypeImmune)
|
||||
{
|
||||
target.ApplySpellImmune(Id, SpellImmunity.State, auraType, apply);
|
||||
@@ -3599,12 +3609,13 @@ namespace Game.Spells
|
||||
public bool HasAttribute(SpellAttr14 attribute) { return Convert.ToBoolean(AttributesEx14 & attribute); }
|
||||
public bool HasAttribute(SpellCustomAttributes attribute) { return Convert.ToBoolean(AttributesCu & attribute); }
|
||||
|
||||
public bool HasAnyAuraInterruptFlag() { return AuraInterruptFlags.Any(flag => flag != 0); }
|
||||
public bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) { return (AuraInterruptFlags[0] & (uint)flag) != 0; }
|
||||
public bool HasAuraInterruptFlag(SpellAuraInterruptFlags2 flag) { return (AuraInterruptFlags[1] & (uint)flag) != 0; }
|
||||
|
||||
public bool HasChannelInterruptFlag(SpellChannelInterruptFlags flag) { return (ChannelInterruptFlags[0] & (uint)flag) != 0; }
|
||||
public bool HasAnyAuraInterruptFlag() { return AuraInterruptFlags != SpellAuraInterruptFlags.None || AuraInterruptFlags2 != SpellAuraInterruptFlags2.None; }
|
||||
public bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) { return AuraInterruptFlags.HasAnyFlag(flag); }
|
||||
public bool HasAuraInterruptFlag(SpellAuraInterruptFlags2 flag) { return AuraInterruptFlags2.HasAnyFlag(flag); }
|
||||
|
||||
public bool HasChannelInterruptFlag(SpellAuraInterruptFlags flag) { return ChannelInterruptFlags.HasAnyFlag(flag); }
|
||||
public bool HasChannelInterruptFlag(SpellAuraInterruptFlags2 flag) { return ChannelInterruptFlags2.HasAnyFlag(flag); }
|
||||
|
||||
#region Fields
|
||||
public uint Id { get; set; }
|
||||
public Difficulty Difficulty { get; set; }
|
||||
@@ -3648,8 +3659,10 @@ namespace Game.Spells
|
||||
public uint StartRecoveryCategory { get; set; }
|
||||
public uint StartRecoveryTime { get; set; }
|
||||
public SpellInterruptFlags InterruptFlags { get; set; }
|
||||
public uint[] AuraInterruptFlags { get; set; } = new uint[2];
|
||||
public uint[] ChannelInterruptFlags { get; set; } = new uint[2];
|
||||
public SpellAuraInterruptFlags AuraInterruptFlags { get; set; }
|
||||
public SpellAuraInterruptFlags2 AuraInterruptFlags2 { get; set; }
|
||||
public SpellAuraInterruptFlags ChannelInterruptFlags { get; set; }
|
||||
public SpellAuraInterruptFlags2 ChannelInterruptFlags2 { get; set; }
|
||||
public ProcFlags ProcFlags { get; set; }
|
||||
public uint ProcChance { get; set; }
|
||||
public uint ProcCharges { get; set; }
|
||||
|
||||
@@ -2546,10 +2546,10 @@ namespace Game.Entities
|
||||
spellInfo.StartRecoveryCategory = spellsResult.Read<uint>(37);
|
||||
spellInfo.StartRecoveryTime = spellsResult.Read<uint>(38);
|
||||
spellInfo.InterruptFlags = (SpellInterruptFlags)spellsResult.Read<uint>(39);
|
||||
spellInfo.AuraInterruptFlags[0] = spellsResult.Read<uint>(40);
|
||||
spellInfo.AuraInterruptFlags[1] = spellsResult.Read<uint>(41);
|
||||
spellInfo.ChannelInterruptFlags[0] = spellsResult.Read<uint>(42);
|
||||
spellInfo.ChannelInterruptFlags[1] = spellsResult.Read<uint>(43);
|
||||
spellInfo.AuraInterruptFlags = (SpellAuraInterruptFlags)spellsResult.Read<uint>(40);
|
||||
spellInfo.AuraInterruptFlags2 = (SpellAuraInterruptFlags2)spellsResult.Read<uint>(41);
|
||||
spellInfo.ChannelInterruptFlags = (SpellAuraInterruptFlags)spellsResult.Read<uint>(42);
|
||||
spellInfo.ChannelInterruptFlags2 = (SpellAuraInterruptFlags2)spellsResult.Read<uint>(43);
|
||||
spellInfo.ProcFlags = (ProcFlags)spellsResult.Read<uint>(44);
|
||||
spellInfo.ProcChance = spellsResult.Read<uint>(45);
|
||||
spellInfo.ProcCharges = spellsResult.Read<uint>(46);
|
||||
@@ -3175,7 +3175,7 @@ namespace Game.Entities
|
||||
spellInfo.GetEffect(0).BasePoints = 0;// force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)"
|
||||
break;
|
||||
case 61719: // Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with
|
||||
spellInfo.AuraInterruptFlags[0] = (uint)(SpellAuraInterruptFlags.Hitbyspell | SpellAuraInterruptFlags.TakeDamage);
|
||||
spellInfo.AuraInterruptFlags = SpellAuraInterruptFlags.HostileActionReceived | SpellAuraInterruptFlags.Damage;
|
||||
break;
|
||||
case 71838: // Drain Life - Bryntroll Normal
|
||||
case 71839: // Drain Life - Bryntroll Heroic
|
||||
@@ -3210,7 +3210,7 @@ namespace Game.Entities
|
||||
spellInfo.AttributesEx |= SpellAttr1.NoThreat;
|
||||
break;
|
||||
case 29726: // Test Ribbon Pole Channel
|
||||
spellInfo.InterruptFlags &= ~SpellInterruptFlags.Interrupt;//AURA_INTERRUPT_FLAG_CAST
|
||||
spellInfo.ChannelInterruptFlags &= ~SpellAuraInterruptFlags.Action;//AURA_INTERRUPT_FLAG_CAST
|
||||
break;
|
||||
case 42767: // Sic'em
|
||||
spellInfo.GetEffect(0).TargetA = new SpellImplicitTargetInfo(Targets.UnitNearbyEntry);
|
||||
@@ -3284,7 +3284,8 @@ namespace Game.Entities
|
||||
break;
|
||||
case 63414: // Spinning Up (Mimiron)
|
||||
spellInfo.GetEffect(0).TargetB = new SpellImplicitTargetInfo(Targets.UnitCaster);
|
||||
spellInfo.ChannelInterruptFlags.Clear();
|
||||
spellInfo.ChannelInterruptFlags = SpellAuraInterruptFlags.None;
|
||||
spellInfo.ChannelInterruptFlags2 = SpellAuraInterruptFlags2.None;
|
||||
break;
|
||||
case 63036: // Rocket Strike (Mimiron)
|
||||
spellInfo.Speed = 0;
|
||||
@@ -3508,7 +3509,7 @@ namespace Game.Entities
|
||||
spellInfo.GetEffect(0).MaxRadiusEntry = CliDB.SpellRadiusStorage.LookupByKey(EffectRadiusIndex.Yards45);
|
||||
break;
|
||||
case 24314: // Threatening Gaze
|
||||
spellInfo.AuraInterruptFlags[0] |= (uint)(SpellAuraInterruptFlags.Cast | SpellAuraInterruptFlags.Move | SpellAuraInterruptFlags.Jump);
|
||||
spellInfo.AuraInterruptFlags |= SpellAuraInterruptFlags.Action | SpellAuraInterruptFlags.Moving | SpellAuraInterruptFlags.Anim;
|
||||
break;
|
||||
case 783: // Travel Form (dummy) - cannot be cast indoors.
|
||||
spellInfo.Attributes |= SpellAttr0.OutdoorsOnly;
|
||||
@@ -3546,7 +3547,7 @@ namespace Game.Entities
|
||||
break;
|
||||
// Blaze of Glory
|
||||
case 99252:
|
||||
spellInfo.AuraInterruptFlags[0] |= (uint)SpellAuraInterruptFlags.ChangeMap;
|
||||
spellInfo.AuraInterruptFlags |= SpellAuraInterruptFlags.LeaveWorld;
|
||||
break;
|
||||
// ENDOF FIRELANDS SPELLS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user