aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp5
-rw-r--r--src/server/game/Spells/Spell.cpp73
-rw-r--r--src/server/game/Spells/Spell.h1
4 files changed, 41 insertions, 40 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 35fc80c0e22..03f2b9f783e 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -3363,7 +3363,7 @@ bool Creature::IsMovementPreventedByCasting() const
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
{
if (spell->getState() != SPELL_STATE_FINISHED && spell->IsChannelActive())
- if (spell->GetSpellInfo()->IsMoveAllowedChannel())
+ if (spell->CheckMovement() != SPELL_CAST_OK)
return false;
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 5ae10b11ca9..b4a689e6f4a 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -2784,8 +2784,7 @@ void Unit::_UpdateAutoRepeatSpell()
// check "realtime" interrupts
// don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
- if (((GetTypeId() == TYPEID_PLAYER && ToPlayer()->isMoving()) || IsNonMeleeSpellCast(false, false, true, autoRepeatSpellInfo->Id == 75)) &&
- !CanCastSpellWhileMoving(autoRepeatSpellInfo))
+ if ((isMoving() && m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckMovement() != SPELL_CAST_OK) || IsNonMeleeSpellCast(false, false, true, autoRepeatSpellInfo->Id == 75))
{
// cancel wand shoot
if (autoRepeatSpellInfo->Id != 75)
@@ -3015,7 +3014,7 @@ bool Unit::IsMovementPreventedByCasting() const
// channeled spells during channel stage (after the initial cast timer) allow movement with a specific spell attribute
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
if (spell->getState() != SPELL_STATE_FINISHED && spell->IsChannelActive())
- if (spell->GetSpellInfo()->IsMoveAllowedChannel())
+ if (spell->GetSpellInfo()->IsMoveAllowedChannel() || CanCastSpellWhileMoving(spell->GetSpellInfo()))
return false;
// prohibit movement for all other spell casts
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 119585fb60b..e207befbf55 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -3375,19 +3375,14 @@ SpellCastResult Spell::prepare(SpellCastTargets const& targets, AuraEffect const
else
m_casttime = m_spellInfo->CalcCastTime(this);
- // don't allow channeled spells / spells with cast time to be cast while moving
- // 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) && m_caster->GetTypeId() == TYPEID_PLAYER && !(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))
+ if (m_caster->IsUnit() && m_caster->ToUnit()->isMoving())
{
- // 1. Has casttime, 2. Or doesn't have flag to allow movement during channel
- if (m_casttime || !m_spellInfo->IsMoveAllowedChannel())
+ result = CheckMovement();
+ if (result != SPELL_CAST_OK)
{
- SendCastResult(SPELL_FAILED_MOVING);
+ SendCastResult(result);
finish(false);
- return SPELL_FAILED_MOVING;
+ return result;
}
}
@@ -4110,20 +4105,13 @@ void Spell::update(uint32 difftime)
// check if the player caster has moved before the spell finished
// with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect
- if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
- m_caster->ToUnit()->isMoving() && (m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::Movement)) &&
- (!m_spellInfo->HasEffect(SPELL_EFFECT_STUCK) || !m_caster->ToUnit()->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) &&
- !m_caster->ToUnit()->CanCastSpellWhileMoving(m_spellInfo))
+ if (m_timer != 0 && m_caster->IsUnit() && m_caster->ToUnit()->isMoving() && CheckMovement() != SPELL_CAST_OK)
{
- // don't cancel for melee, autorepeat, triggered and instant spells
- if (!m_spellInfo->IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo->IsMoveAllowedChannel()))
- {
- // 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();
- }
+ // 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();
}
switch (m_spellState)
@@ -5579,19 +5567,6 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32
return SPELL_FAILED_AFFECTING_COMBAT;
}
- // 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->GetTypeId() == TYPEID_PLAYER && 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_FALLING_FAR) || !m_spellInfo->HasEffect(SPELL_EFFECT_STUCK)) &&
- (IsAutoRepeat() || m_spellInfo->HasAuraInterruptFlag(SpellAuraInterruptFlags::Standing)))
- return SPELL_FAILED_MOVING;
- }
-
// Check vehicle flags
if (!(_triggeredCastFlags & TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE))
{
@@ -6861,6 +6836,32 @@ SpellCastResult Spell::CheckArenaAndRatedBattlegroundCastRules()
return SPELL_CAST_OK;
}
+SpellCastResult Spell::CheckMovement() const
+{
+ if (IsTriggered())
+ return SPELL_CAST_OK;
+
+ if (Unit* unitCaster = m_caster->ToUnit())
+ {
+ if (!unitCaster->CanCastSpellWhileMoving(m_spellInfo))
+ {
+ if (m_casttime)
+ {
+ if (m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::Movement))
+ return SPELL_FAILED_MOVING;
+ }
+ else
+ {
+ // only fail channeled casts if they are instant but cannot be channeled while moving
+ if (m_spellInfo->IsChanneled() && !m_spellInfo->IsMoveAllowedChannel())
+ return SPELL_FAILED_MOVING;
+ }
+ }
+ }
+
+ return SPELL_CAST_OK;
+}
+
int32 Spell::CalculateDamage(SpellEffectInfo const& spellEffectInfo, Unit const* target, float* var /*= nullptr*/) const
{
bool needRecalculateBasePoints = !(m_spellValue->CustomBasePointsMask & (1 << spellEffectInfo.EffectIndex));
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 23e044c30e2..86a6404fd6d 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -464,6 +464,7 @@ class TC_GAME_API Spell
SpellCastResult CheckRuneCost() const;
SpellCastResult CheckCasterAuras(int32* param1) const;
SpellCastResult CheckArenaAndRatedBattlegroundCastRules();
+ SpellCastResult CheckMovement() const;
bool CheckSpellCancelsAuraEffect(AuraType auraType, int32* param1) const;
bool CheckSpellCancelsCharm(int32* param1) const;