Core/Spells: Defined and implemented new spell interrupt flags
Port From (https://github.com/TrinityCore/TrinityCore/commit/07a47947e2e189649e48a093b66c8c3de8872ac0)
This commit is contained in:
@@ -100,12 +100,18 @@ namespace Framework.Constants
|
|||||||
|
|
||||||
public enum SpellInterruptFlags
|
public enum SpellInterruptFlags
|
||||||
{
|
{
|
||||||
Movement = 0x01, // why need this for instant?
|
None = 0,
|
||||||
PushBack = 0x02, // push back
|
Movement = 0x01,
|
||||||
Unk3 = 0x04, // any info?
|
DamagePushbackPlayerOnly = 0x02,
|
||||||
Interrupt = 0x08, // interrupt
|
Stun = 0x04, // useless, even spells without it get interrupted
|
||||||
AbortOnDmg = 0x10 // _complete_ interrupt on direct damage
|
Combat = 0x08,
|
||||||
//SPELL_INTERRUPT_UNK = 0x20 // unk, 564 of 727 spells having this spell start with "Glyph"
|
DamageCancelsPlayerOnly = 0x10,
|
||||||
|
MeleeCombat = 0x20, // NYI
|
||||||
|
Immunity = 0x40, // NYI
|
||||||
|
DamageAbsorb = 0x80,
|
||||||
|
ZeroDamageCancels = 0x100,
|
||||||
|
DamagePushback = 0x200,
|
||||||
|
DamageCancels = 0x400
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SpellAuraInterruptFlags : uint
|
public enum SpellAuraInterruptFlags : uint
|
||||||
|
|||||||
@@ -1011,21 +1011,14 @@ namespace Game.Entities
|
|||||||
else
|
else
|
||||||
victim.RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Damage, 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)
|
if (damage == 0 && damagetype != DamageEffectType.DOT && cleanDamage != null && cleanDamage.absorbed_damage != 0)
|
||||||
{
|
{
|
||||||
if (victim != this && victim.IsTypeId(TypeId.Player))
|
if (victim != this && victim.IsPlayer())
|
||||||
{
|
{
|
||||||
Spell spell = victim.GetCurrentSpell(CurrentSpellTypes.Generic);
|
Spell spell = victim.GetCurrentSpell(CurrentSpellTypes.Generic);
|
||||||
if (spell)
|
if (spell != null)
|
||||||
{
|
if (spell.GetState() == SpellState.Preparing && spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamageAbsorb))
|
||||||
if (spell.GetState() == SpellState.Preparing)
|
victim.InterruptNonMeleeSpells(false);
|
||||||
{
|
|
||||||
SpellInterruptFlags interruptFlags = spell.m_spellInfo.InterruptFlags;
|
|
||||||
if (interruptFlags.HasAnyFlag(SpellInterruptFlags.AbortOnDmg))
|
|
||||||
victim.InterruptNonMeleeSpells(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1179,10 +1172,9 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damagetype != DamageEffectType.NoDamage && damage != 0)
|
if (damagetype != DamageEffectType.NoDamage)
|
||||||
{
|
{
|
||||||
if (victim != this && victim.IsTypeId(TypeId.Player) && // does not support creature push_back
|
if (victim != this && (spellProto == null || !spellProto.HasAttribute(SpellAttr7.NoPushbackOnDamage)))
|
||||||
(spellProto == null || !(spellProto.HasAttribute(SpellAttr7.NoPushbackOnDamage))))
|
|
||||||
{
|
{
|
||||||
if (damagetype != DamageEffectType.DOT)
|
if (damagetype != DamageEffectType.DOT)
|
||||||
{
|
{
|
||||||
@@ -1191,20 +1183,52 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
if (spell.GetState() == SpellState.Preparing)
|
if (spell.GetState() == SpellState.Preparing)
|
||||||
{
|
{
|
||||||
var interruptFlags = spell.m_spellInfo.InterruptFlags;
|
bool isCastInterrupted()
|
||||||
if (interruptFlags.HasAnyFlag(SpellInterruptFlags.AbortOnDmg))
|
{
|
||||||
|
if (damage == 0)
|
||||||
|
return spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.ZeroDamageCancels);
|
||||||
|
|
||||||
|
if (victim.IsPlayer() && spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamageCancelsPlayerOnly))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamageCancels))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool isCastDelayed()
|
||||||
|
{
|
||||||
|
if (damage == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (victim.IsPlayer() && spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamagePushbackPlayerOnly))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.DamagePushback))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCastInterrupted())
|
||||||
victim.InterruptNonMeleeSpells(false);
|
victim.InterruptNonMeleeSpells(false);
|
||||||
else if (interruptFlags.HasAnyFlag(SpellInterruptFlags.PushBack))
|
else if (isCastDelayed())
|
||||||
spell.Delayed();
|
spell.Delayed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (damage != 0 && victim.IsPlayer())
|
||||||
|
{
|
||||||
|
Spell spell1 = victim.GetCurrentSpell(CurrentSpellTypes.Channeled);
|
||||||
|
if (spell1 != null)
|
||||||
|
if (spell1.GetState() == SpellState.Casting && spell1.m_spellInfo.HasChannelInterruptFlag(SpellAuraInterruptFlags.DamageChannelDuration))
|
||||||
|
spell1.DelayedChannel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Spell spell1 = victim.GetCurrentSpell(CurrentSpellTypes.Channeled);
|
|
||||||
if (spell1 != null)
|
|
||||||
if (spell1.GetState() == SpellState.Casting && spell1.m_spellInfo.HasChannelInterruptFlag(SpellAuraInterruptFlags.DamageChannelDuration) && damagetype != DamageEffectType.DOT)
|
|
||||||
spell1.DelayedChannel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// last damage from duel opponent
|
// last damage from duel opponent
|
||||||
if (duel_hasEnded)
|
if (duel_hasEnded)
|
||||||
{
|
{
|
||||||
@@ -1443,6 +1467,11 @@ namespace Game.Entities
|
|||||||
aurApp.GetBase().CallScriptEnterLeaveCombatHandlers(aurApp, true);
|
aurApp.GetBase().CallScriptEnterLeaveCombatHandlers(aurApp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Spell spell = GetCurrentSpell(CurrentSpellTypes.Generic);
|
||||||
|
if (spell != null)
|
||||||
|
if (spell.GetState() == SpellState.Preparing && spell.m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.Combat))
|
||||||
|
InterruptNonMeleeSpells(false);
|
||||||
|
|
||||||
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnteringCombat);
|
RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.EnteringCombat);
|
||||||
ProcSkillsAndAuras(enemy, ProcFlags.EnterCombat, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
ProcSkillsAndAuras(enemy, ProcFlags.EnterCombat, ProcFlags.None, ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.None, ProcFlagsHit.None, null, null, null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6688,8 +6688,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
bool IsAutoActionResetSpell()
|
bool IsAutoActionResetSpell()
|
||||||
{
|
{
|
||||||
// @todo changed SPELL_INTERRUPT_FLAG_AUTOATTACK . SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
|
if (IsTriggered())
|
||||||
if (IsTriggered() || !m_spellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.Interrupt))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_casttime == 0 && m_spellInfo.HasAttribute(SpellAttr6.NotResetSwingIfInstant))
|
if (m_casttime == 0 && m_spellInfo.HasAttribute(SpellAttr6.NotResetSwingIfInstant))
|
||||||
|
|||||||
@@ -2696,9 +2696,7 @@ namespace Game.Spells
|
|||||||
// check if we can interrupt spell
|
// check if we can interrupt spell
|
||||||
if ((spell.GetState() == SpellState.Casting
|
if ((spell.GetState() == SpellState.Casting
|
||||||
|| (spell.GetState() == SpellState.Preparing && spell.GetCastTime() > 0.0f))
|
|| (spell.GetState() == SpellState.Preparing && spell.GetCastTime() > 0.0f))
|
||||||
&& (curSpellInfo.PreventionType.HasAnyFlag(SpellPreventionType.Silence))
|
&& curSpellInfo.CanBeInterrupted(m_caster, unitTarget))
|
||||||
&& ((i == CurrentSpellTypes.Generic && curSpellInfo.InterruptFlags.HasAnyFlag(SpellInterruptFlags.Interrupt))
|
|
||||||
|| (i == CurrentSpellTypes.Channeled)))
|
|
||||||
{
|
{
|
||||||
if (m_originalCaster != null)
|
if (m_originalCaster != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3609,6 +3609,18 @@ namespace Game.Spells
|
|||||||
public bool HasAttribute(SpellAttr14 attribute) { return Convert.ToBoolean(AttributesEx14 & attribute); }
|
public bool HasAttribute(SpellAttr14 attribute) { return Convert.ToBoolean(AttributesEx14 & attribute); }
|
||||||
public bool HasAttribute(SpellCustomAttributes attribute) { return Convert.ToBoolean(AttributesCu & attribute); }
|
public bool HasAttribute(SpellCustomAttributes attribute) { return Convert.ToBoolean(AttributesCu & attribute); }
|
||||||
|
|
||||||
|
public bool CanBeInterrupted(Unit interruptCaster, Unit interruptTarget)
|
||||||
|
{
|
||||||
|
return HasAttribute(SpellAttr7.CanAlwaysBeInterrupted)
|
||||||
|
|| HasChannelInterruptFlag(SpellAuraInterruptFlags.Damage | SpellAuraInterruptFlags.EnteringCombat)
|
||||||
|
|| (interruptTarget.IsPlayer() && InterruptFlags.HasFlag(SpellInterruptFlags.DamageCancelsPlayerOnly))
|
||||||
|
|| InterruptFlags.HasFlag(SpellInterruptFlags.DamageCancels)
|
||||||
|
|| interruptCaster.HasAuraTypeWithMiscvalue(AuraType.AllowInterruptSpell, (int)Id)
|
||||||
|
|| ((interruptTarget.GetMechanicImmunityMask() & (1 << (int)Mechanics.Interrupt)) == 0
|
||||||
|
&& !interruptTarget.HasAuraTypeWithAffectMask(AuraType.PreventInterrupt, this)
|
||||||
|
&& PreventionType.HasAnyFlag(SpellPreventionType.Silence));
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasAnyAuraInterruptFlag() { return AuraInterruptFlags != SpellAuraInterruptFlags.None || AuraInterruptFlags2 != SpellAuraInterruptFlags2.None; }
|
public bool HasAnyAuraInterruptFlag() { return AuraInterruptFlags != SpellAuraInterruptFlags.None || AuraInterruptFlags2 != SpellAuraInterruptFlags2.None; }
|
||||||
public bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) { return AuraInterruptFlags.HasAnyFlag(flag); }
|
public bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) { return AuraInterruptFlags.HasAnyFlag(flag); }
|
||||||
public bool HasAuraInterruptFlag(SpellAuraInterruptFlags2 flag) { return AuraInterruptFlags2.HasAnyFlag(flag); }
|
public bool HasAuraInterruptFlag(SpellAuraInterruptFlags2 flag) { return AuraInterruptFlags2.HasAnyFlag(flag); }
|
||||||
|
|||||||
Reference in New Issue
Block a user