diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index bfc77f3d1..fd11a6c15 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -2632,16 +2632,9 @@ namespace Game.Spells m_casttime = CallScriptCalcCastTimeHandlers(m_spellInfo.CalcCastTime(this)); + SpellCastResult movementResult = SpellCastResult.SpellCastOk; if (m_caster.IsUnit() && m_caster.ToUnit().IsMoving()) - { - result = CheckMovement(); - if (result != SpellCastResult.SpellCastOk) - { - SendCastResult(result); - Finish(result); - return result; - } - } + movementResult = CheckMovement(); // Creatures focus their target when possible if (m_casttime != 0 && m_caster.IsCreature() && !m_spellInfo.IsNextMeleeSwingSpell() && !IsAutoRepeat() && !m_caster.ToUnit().HasUnitFlag(UnitFlags.Possessed)) @@ -2654,6 +2647,24 @@ namespace Game.Spells m_caster.ToCreature().SetSpellFocus(this, null); } + if (movementResult != SpellCastResult.SpellCastOk) + { + if (m_caster.ToUnit().IsControlledByPlayer() || !CanStopMovementForSpellCasting(m_caster.ToUnit().GetMotionMaster().GetCurrentMovementGeneratorType())) + { + SendCastResult(movementResult); + Finish(movementResult); + return movementResult; + } + else + { + // Creatures (not controlled) give priority to spell casting over movement. + // We assume that the casting is always valid and the current movement + // is stopped immediately (because spells are updated before movement, so next Unit::Update would cancel the spell before stopping movement) + // and future attempts are stopped by by Unit::IsMovementPreventedByCasting in movement generators to prevent casting interruption. + m_caster.ToUnit().StopMoving(); + } + } + CallScriptOnPrecastHandler(); // set timer base at cast time @@ -3420,16 +3431,9 @@ namespace Game.Spells return; } - // check if the player caster has moved before the spell finished - // with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect + // check if the unit caster has moved before the spell finished if (m_timer != 0 && m_caster.IsUnit() && m_caster.ToUnit().IsMoving() && CheckMovement() != SpellCastResult.SpellCastOk) - { - // 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 - // however, checking what type of movement the spline is for every single spline would be really expensive - if (!m_caster.ToUnit().GetCharmerGUID().IsCreature()) - Cancel(); - } + Cancel(); switch (m_spellState) { @@ -4264,6 +4268,21 @@ namespace Game.Spells return (points, type); } + bool CanStopMovementForSpellCasting(MovementGeneratorType type) + { + // MovementGenerators that don't check Unit::IsMovementPreventedByCasting + switch (type) + { + case MovementGeneratorType.Home: + case MovementGeneratorType.Flight: + case MovementGeneratorType.Effect: // knockbacks, jumps, falling, land/takeoff transitions + return false; + default: + break; + } + return true; + } + void UpdateSpellHealPrediction(SpellHealPrediction healPrediction, bool withPeriodic) { healPrediction.BeaconGUID = ObjectGuid.Empty; @@ -8311,12 +8330,6 @@ namespace Game.Spells if (IsTriggered()) return SpellCastResult.SpellCastOk; - // Creatures (not controlled) give priority to spell casting over movement. - // We assume that the casting is always valid and the current movement - // is stopped by Unit:IsmovementPreventedByCasting to prevent casting interruption. - if (m_caster.IsCreature() && !m_caster.ToCreature().IsControlledByPlayer()) - return SpellCastResult.SpellCastOk; - Unit unitCaster = m_caster.ToUnit(); if (unitCaster != null) { diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 07b10993d..ed0190841 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -3314,6 +3314,7 @@ namespace Game.Spells } [SpellEffectHandler(SpellEffectName.Reputation)] + [SpellEffectHandler(SpellEffectName.Reputation2)] void EffectReputation() { if (effectHandleMode != SpellEffectHandleMode.HitTarget) @@ -3630,10 +3631,6 @@ namespace Game.Spells if (unitTarget.HasUnitState(UnitState.Root | UnitState.Stunned)) return; - // Instantly interrupt non melee spells being casted - if (unitTarget.IsNonMeleeSpellCast(true)) - unitTarget.InterruptNonMeleeSpells(true); - float ratio = 0.1f; float speedxy = effectInfo.MiscValue * ratio; float speedz = damage * ratio;