Core/Spells: Cleanup movement checks in spells - use correct interrupt flags
Port From (https://github.com/TrinityCore/TrinityCore/commit/538fa8e97ff4b4e36a59e37fd74ea8958e6e30d2)
This commit is contained in:
@@ -1160,7 +1160,7 @@ namespace Game.Entities
|
|||||||
if (spell != null)
|
if (spell != null)
|
||||||
{
|
{
|
||||||
if (spell.GetState() != SpellState.Finished && spell.IsChannelActive())
|
if (spell.GetState() != SpellState.Finished && spell.IsChannelActive())
|
||||||
if (spell.GetSpellInfo().IsMoveAllowedChannel())
|
if (spell.CheckMovement() != SpellCastResult.SpellCastOk)
|
||||||
if (HasUnitState(UnitState.Casting))
|
if (HasUnitState(UnitState.Casting))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1058,7 +1058,7 @@ namespace Game.Entities
|
|||||||
spell = m_currentSpells.LookupByKey(CurrentSpellTypes.Channeled);
|
spell = m_currentSpells.LookupByKey(CurrentSpellTypes.Channeled);
|
||||||
if (spell != null)
|
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() || CanCastSpellWhileMoving(spell.GetSpellInfo()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// prohibit movement for all other spell casts
|
// prohibit movement for all other spell casts
|
||||||
|
|||||||
@@ -1563,8 +1563,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 ((IsMoving() && GetCurrentSpell(CurrentSpellTypes.AutoRepeat).CheckMovement() != SpellCastResult.SpellCastOk) || IsNonMeleeSpellCast(false, false, true, autoRepeatSpellInfo.Id == 75))
|
||||||
!CanCastSpellWhileMoving(autoRepeatSpellInfo))
|
|
||||||
{
|
{
|
||||||
// cancel wand shoot
|
// cancel wand shoot
|
||||||
if (autoRepeatSpellInfo.Id != 75)
|
if (autoRepeatSpellInfo.Id != 75)
|
||||||
|
|||||||
+38
-36
@@ -2511,19 +2511,14 @@ namespace Game.Spells
|
|||||||
else
|
else
|
||||||
m_casttime = m_spellInfo.CalcCastTime(this);
|
m_casttime = m_spellInfo.CalcCastTime(this);
|
||||||
|
|
||||||
// don't allow channeled spells / spells with cast time to be casted while moving
|
if (m_caster.IsUnit() && m_caster.ToUnit().IsMoving())
|
||||||
// exception are only channeled spells that have no casttime and dont have movement interrupt flag
|
|
||||||
// (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
|
|
||||||
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.ToUnit().CanCastSpellWhileMoving(m_spellInfo))
|
|
||||||
{
|
{
|
||||||
// 1. Has casttime, 2. Or doesn't have flag to allow movement during channel
|
result = CheckMovement();
|
||||||
if (m_casttime != 0 || !m_spellInfo.IsMoveAllowedChannel())
|
if (result != SpellCastResult.SpellCastOk)
|
||||||
{
|
{
|
||||||
SendCastResult(SpellCastResult.Moving);
|
SendCastResult(result);
|
||||||
Finish(false);
|
Finish(false);
|
||||||
return SpellCastResult.Moving;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3284,20 +3279,13 @@ 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_timer != 0 && m_caster.IsUnit() && m_caster.ToUnit().IsMoving() && CheckMovement() != SpellCastResult.SpellCastOk)
|
||||||
m_caster.ToUnit().IsMoving() && (m_spellInfo.InterruptFlags.HasFlag(SpellInterruptFlags.Movement)) &&
|
|
||||||
(!m_spellInfo.HasEffect(SpellEffectName.Stuck) || !m_caster.ToUnit().HasUnitMovementFlag(MovementFlag.FallingFar)) &&
|
|
||||||
!m_caster.ToUnit().CanCastSpellWhileMoving(m_spellInfo))
|
|
||||||
{
|
{
|
||||||
// don't cancel for melee, autorepeat, triggered and instant spells
|
// if charmed by creature, trust the AI not to cheat and allow the cast to proceed
|
||||||
if (!m_spellInfo.IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo.IsMoveAllowedChannel()))
|
// @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
|
||||||
// if charmed by creature, trust the AI not to cheat and allow the cast to proceed
|
if (!m_caster.ToUnit().GetCharmerGUID().IsCreature())
|
||||||
// @todo this is a hack, "creature" movesplines don't differentiate turning/moving right now
|
Cancel();
|
||||||
// however, checking what type of movement the spline is for every single spline would be really expensive
|
|
||||||
if (!m_caster.ToUnit().GetCharmerGUID().IsCreature())
|
|
||||||
Cancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_spellState)
|
switch (m_spellState)
|
||||||
@@ -4768,19 +4756,6 @@ namespace Game.Spells
|
|||||||
return SpellCastResult.AffectingCombat;
|
return SpellCastResult.AffectingCombat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cancel autorepeat spells if cast start when moving
|
|
||||||
// (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
|
|
||||||
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
|
|
||||||
if ((!unitCaster.HasUnitMovementFlag(MovementFlag.FallingFar) || !m_spellInfo.HasEffect(SpellEffectName.Stuck)) &&
|
|
||||||
(IsAutoRepeat() || m_spellInfo.HasAuraInterruptFlag(SpellAuraInterruptFlags.Standing)))
|
|
||||||
return SpellCastResult.Moving;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check vehicle flags
|
// Check vehicle flags
|
||||||
if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreCasterMountedOrOnVehicle))
|
if (!Convert.ToBoolean(_triggeredCastFlags & TriggerCastFlags.IgnoreCasterMountedOrOnVehicle))
|
||||||
{
|
{
|
||||||
@@ -7801,6 +7776,33 @@ namespace Game.Spells
|
|||||||
|
|
||||||
List<SpellScript> m_loadedScripts = new();
|
List<SpellScript> m_loadedScripts = new();
|
||||||
|
|
||||||
|
public SpellCastResult CheckMovement()
|
||||||
|
{
|
||||||
|
if (IsTriggered())
|
||||||
|
return SpellCastResult.SpellCastOk;
|
||||||
|
|
||||||
|
Unit unitCaster = m_caster.ToUnit();
|
||||||
|
if (unitCaster != null)
|
||||||
|
{
|
||||||
|
if (!unitCaster.CanCastSpellWhileMoving(m_spellInfo))
|
||||||
|
{
|
||||||
|
if (m_casttime != 0)
|
||||||
|
{
|
||||||
|
if (m_spellInfo.InterruptFlags.HasFlag(SpellInterruptFlags.Movement))
|
||||||
|
return SpellCastResult.Moving;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// only fail channeled casts if they are instant but cannot be channeled while moving
|
||||||
|
if (m_spellInfo.IsChanneled() && !m_spellInfo.IsMoveAllowedChannel())
|
||||||
|
return SpellCastResult.Moving;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SpellCastResult.SpellCastOk;
|
||||||
|
}
|
||||||
|
|
||||||
int CalculateDamage(SpellEffectInfo spellEffectInfo, Unit target)
|
int CalculateDamage(SpellEffectInfo spellEffectInfo, Unit target)
|
||||||
{
|
{
|
||||||
return CalculateDamage(spellEffectInfo, target, out _);
|
return CalculateDamage(spellEffectInfo, target, out _);
|
||||||
|
|||||||
Reference in New Issue
Block a user