Core/Auras: Implemented SPELL_AURA_CAST_WHILE_WALKING_BY_SPELL_LABEL and SPELL_AURA_CAST_WHILE_WALKING_ALL

Port From (https://github.com/TrinityCore/TrinityCore/commit/3e81db7b9380269d4561eb5deb21fbef26913779)
This commit is contained in:
hondacrx
2021-10-16 18:33:43 -04:00
parent 5ad5b8ef18
commit 68c4407840
4 changed files with 37 additions and 15 deletions
@@ -398,7 +398,7 @@ namespace Framework.Constants
ModifyFallDamagePct = 374, ModifyFallDamagePct = 374,
ModPossessPet = 375, ModPossessPet = 375,
ModCurrencyGainFromSource = 376, // NYI ModCurrencyGainFromSource = 376, // NYI
CastWhileWalking2 = 377, // NYI CastWhileWalkingAll = 377, // Enables casting all spells while moving
Unk378 = 378, Unk378 = 378,
ModManaRegenPct = 379, ModManaRegenPct = 379,
Unk380 = 380, Unk380 = 380,
+26 -6
View File
@@ -1051,9 +1051,14 @@ namespace Game.Entities
if (!HasUnitState(UnitState.Casting)) if (!HasUnitState(UnitState.Casting))
return false; return false;
Spell spell = GetCurrentSpell(CurrentSpellTypes.Generic);
if (spell != null)
if (CanCastSpellWhileMoving(spell.GetSpellInfo()))
return false;
// channeled spells during channel stage (after the initial cast timer) allow movement with a specific spell attribute // channeled spells during channel stage (after the initial cast timer) allow movement with a specific spell attribute
Spell spell = m_currentSpells.LookupByKey(CurrentSpellTypes.Channeled); spell = m_currentSpells.LookupByKey(CurrentSpellTypes.Channeled);
if (spell) if (spell != null)
if (spell.GetState() != SpellState.Finished && spell.IsChannelActive()) if (spell.GetState() != SpellState.Finished && spell.IsChannelActive())
if (spell.GetSpellInfo().IsMoveAllowedChannel()) if (spell.GetSpellInfo().IsMoveAllowedChannel())
return false; return false;
@@ -1406,6 +1411,21 @@ namespace Game.Entities
return false; return false;
} }
public bool CanCastSpellWhileMoving(SpellInfo spellInfo)
{
if (HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, spellInfo))
return true;
if (HasAuraType(AuraType.CastWhileWalkingAll))
return true;
foreach (uint label in spellInfo.Labels)
if (HasAuraTypeWithMiscvalue(AuraType.CastWhileWalkingBySpellLabel, (int)label))
return true;
return false;
}
public static void ProcSkillsAndAuras(Unit actor, Unit actionTarget, ProcFlags typeMaskActor, ProcFlags typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo) public static void ProcSkillsAndAuras(Unit actor, Unit actionTarget, ProcFlags typeMaskActor, ProcFlags typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell spell, DamageInfo damageInfo, HealInfo healInfo)
{ {
WeaponAttackType attType = damageInfo != null ? damageInfo.GetAttackType() : WeaponAttackType.BaseAttack; WeaponAttackType attType = damageInfo != null ? damageInfo.GetAttackType() : WeaponAttackType.BaseAttack;
@@ -2777,14 +2797,14 @@ namespace Game.Entities
return dispelList; return dispelList;
} }
bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags flag, Unit unit, SpellInfo spellInfo)
{
return flag == SpellAuraInterruptFlags.Moving && unit.CanCastSpellWhileMoving(spellInfo);
}
bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags2 flag, Unit unit, SpellInfo spellInfo) bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags2 flag, Unit unit, SpellInfo spellInfo)
{ {
return false; 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) public void RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags flag, uint except = 0)
{ {
+1 -1
View File
@@ -1465,7 +1465,7 @@ namespace Game.Entities
// check "realtime" interrupts // check "realtime" interrupts
// don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect // don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
if (((IsTypeId(TypeId.Player) && ToPlayer().IsMoving()) || IsNonMeleeSpellCast(false, false, true, autoRepeatSpellInfo.Id == 75)) && if (((IsTypeId(TypeId.Player) && ToPlayer().IsMoving()) || IsNonMeleeSpellCast(false, false, true, autoRepeatSpellInfo.Id == 75)) &&
!HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, autoRepeatSpellInfo)) !CanCastSpellWhileMoving(autoRepeatSpellInfo))
{ {
// cancel wand shoot // cancel wand shoot
if (autoRepeatSpellInfo.Id != 75) if (autoRepeatSpellInfo.Id != 75)
+9 -7
View File
@@ -2332,8 +2332,8 @@ namespace Game.Spells
// exception are only channeled spells that have no casttime and SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING // exception are only channeled spells that have no casttime and SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING
// (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in) // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
// don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect // don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
if (((m_spellInfo.IsChanneled() || m_casttime != 0) && m_caster.IsPlayer() && !(m_caster.ToPlayer().IsCharmed() && m_caster.ToPlayer().GetCharmerGUID().IsCreature()) && m_caster.ToPlayer().IsMoving() && if (((m_spellInfo.IsChanneled() || m_casttime != 0) && m_caster.IsPlayer() && !(m_caster.ToUnit().IsCharmed() && m_caster.ToUnit().GetCharmerGUID().IsCreature()) && m_caster.ToUnit().IsMoving() &&
m_spellInfo.InterruptFlags.HasFlag(SpellInterruptFlags.Movement)) && !m_caster.ToPlayer().HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, m_spellInfo)) m_spellInfo.InterruptFlags.HasFlag(SpellInterruptFlags.Movement)) && !m_caster.ToUnit().CanCastSpellWhileMoving(m_spellInfo))
{ {
// 1. Has casttime, 2. Or doesn't have flag to allow movement during channel // 1. Has casttime, 2. Or doesn't have flag to allow movement during channel
if (m_casttime != 0 || !m_spellInfo.IsMoveAllowedChannel()) if (m_casttime != 0 || !m_spellInfo.IsMoveAllowedChannel())
@@ -3059,9 +3059,9 @@ namespace Game.Spells
// check if the player caster has moved before the spell finished // check if the player caster has moved before the spell finished
// with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect // with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect
if ((m_caster.IsTypeId(TypeId.Player) && m_timer != 0) && if ((m_caster.IsTypeId(TypeId.Player) && m_timer != 0) &&
m_caster.ToPlayer().IsMoving() && (m_spellInfo.InterruptFlags.HasFlag(SpellInterruptFlags.Movement)) && m_caster.ToUnit().IsMoving() && (m_spellInfo.InterruptFlags.HasFlag(SpellInterruptFlags.Movement)) &&
(m_spellInfo.HasEffect(SpellEffectName.Stuck) || !m_caster.ToPlayer().HasUnitMovementFlag(MovementFlag.FallingFar)) && (!m_spellInfo.HasEffect(SpellEffectName.Stuck) || !m_caster.ToUnit().HasUnitMovementFlag(MovementFlag.FallingFar)) &&
!m_caster.ToPlayer().HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, m_spellInfo)) !m_caster.ToUnit().CanCastSpellWhileMoving(m_spellInfo))
{ {
// don't cancel for melee, autorepeat, triggered and instant spells // don't cancel for melee, autorepeat, triggered and instant spells
if (!m_spellInfo.IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo.IsMoveAllowedChannel())) if (!m_spellInfo.IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo.IsMoveAllowedChannel()))
@@ -3069,7 +3069,7 @@ namespace Game.Spells
// if charmed by creature, trust the AI not to cheat and allow the cast to proceed // if charmed by creature, trust the AI not to cheat and allow the cast to proceed
// @todo this is a hack, "creature" movesplines don't differentiate turning/moving right now // @todo this is a hack, "creature" movesplines don't differentiate turning/moving right now
// however, checking what type of movement the spline is for every single spline would be really expensive // however, checking what type of movement the spline is for every single spline would be really expensive
if (!m_caster.ToPlayer().GetCharmerGUID().IsCreature()) if (!m_caster.ToUnit().GetCharmerGUID().IsCreature())
Cancel(); Cancel();
} }
} }
@@ -4500,7 +4500,9 @@ namespace Game.Spells
// cancel autorepeat spells if cast start when moving // cancel autorepeat spells if cast start when moving
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code) // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
// Do not cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect // Do not cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
if (unitCaster.IsPlayer() && unitCaster.ToPlayer().IsMoving() && (!unitCaster.IsCharmed() || !unitCaster.GetCharmerGUID().IsCreature()) && !unitCaster.HasAuraTypeWithAffectMask(AuraType.CastWhileWalking, m_spellInfo)) if (unitCaster.IsPlayer() && unitCaster.ToPlayer().IsMoving()
&& (!unitCaster.IsCharmed() || !unitCaster.GetCharmerGUID().IsCreature())
&& !unitCaster.CanCastSpellWhileMoving(m_spellInfo))
{ {
// skip stuck spell to allow use it in falling case and apply spell limitations at movement // skip stuck spell to allow use it in falling case and apply spell limitations at movement
if ((!unitCaster.HasUnitMovementFlag(MovementFlag.FallingFar) || !m_spellInfo.HasEffect(SpellEffectName.Stuck)) && if ((!unitCaster.HasUnitMovementFlag(MovementFlag.FallingFar) || !m_spellInfo.HasEffect(SpellEffectName.Stuck)) &&