diff options
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 9 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 3 | ||||
| -rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 2 | ||||
| -rw-r--r-- | src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp | 5 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 17 | 
5 files changed, 28 insertions, 8 deletions
| diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ee815f199bd..0e9aa4395a3 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3189,6 +3189,15 @@ int32 Unit::GetCurrentSpellCastTime(uint32 spell_id) const      return 0;  } +bool Unit::CanMoveDuringChannel() const +{ +    if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL]) +        if (spell->getState() != SPELL_STATE_FINISHED) +            return spell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING) && spell->IsChannelActive(); + +    return false; +} +  bool Unit::isInFrontInMap(Unit const* target, float distance,  float arc) const  {      return IsWithinDistInMap(target, distance) && HasInArc(arc, target); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index d49d2fd9842..b1571e4379f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1858,6 +1858,9 @@ class TC_GAME_API Unit : public WorldObject          Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;          int32 GetCurrentSpellCastTime(uint32 spell_id) const; +        // Check if our current channel spell has attribute SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING +        bool CanMoveDuringChannel() const; +          SpellHistory* GetSpellHistory() { return m_spellHistory; }          SpellHistory const* GetSpellHistory() const { return m_spellHistory; } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index f9a98cffd0e..125cd69178b 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -456,7 +456,7 @@ enum SpellAttr4  enum SpellAttr5  { -    SPELL_ATTR5_UNK0                             = 0x00000001, //  0 +    SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING          = 0x00000001, //  0 available casting channel spell when moving      SPELL_ATTR5_NO_REAGENT_WHILE_PREP            = 0x00000002, //  1 not need reagents if UNIT_FLAG_PREPARATION      SPELL_ATTR5_UNK2                             = 0x00000004, //  2      SPELL_ATTR5_USABLE_WHILE_STUNNED             = 0x00000008, //  3 usable while stunned diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 403ccf684e7..3fd3b702ba5 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -36,6 +36,9 @@ void TargetedMovementGeneratorMedium<T, D>::_setTargetLocation(T* owner, bool up      if (owner->HasUnitState(UNIT_STATE_NOT_MOVE))          return; +    if (owner->HasUnitState(UNIT_STATE_CASTING) && !owner->CanMoveDuringChannel()) +        return; +      if (owner->GetTypeId() == TYPEID_UNIT && !i_target->isInAccessiblePlaceFor(owner->ToCreature()))      {          owner->ToCreature()->SetCannotReachTarget(true); @@ -146,7 +149,7 @@ bool TargetedMovementGeneratorMedium<T, D>::DoUpdate(T* owner, uint32 time_diff)      }      // prevent movement while casting spells with cast time or channel time -    if (owner->HasUnitState(UNIT_STATE_CASTING)) +    if (owner->HasUnitState(UNIT_STATE_CASTING) && !owner->CanMoveDuringChannel())      {          if (!owner->IsStopped())              owner->StopMoving(); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 60554e0717c..4176e8fb20e 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2986,12 +2986,17 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered          }      // don't allow channeled spells / spells with cast time to be cast while 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)      if ((m_spellInfo->IsChanneled() || m_casttime) && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isMoving() && m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)      { -        SendCastResult(SPELL_FAILED_MOVING); -        finish(false); -        return; +        // 1. Is a channel spell, 2. Has no casttime, 3. And has flag to allow movement during channel +        if (!(m_spellInfo->IsChanneled() && !m_casttime && m_spellInfo->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING))) +        { +            SendCastResult(SPELL_FAILED_MOVING); +            finish(false); +            return; +        }      }      // set timer base at cast time @@ -3528,11 +3533,11 @@ void Spell::update(uint32 difftime)      // check if the player caster has moved before the spell finished      if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && -        m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) && -        (m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR))) +        m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT && +        (m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR))))      {          // don't cancel for melee, autorepeat, triggered and instant spells -        if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered()) +        if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING)))              cancel();      } | 
