diff options
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 73 |
1 files changed, 37 insertions, 36 deletions
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)); |