diff options
author | Nawuko <nawuko@nitx.de> | 2016-04-25 11:46:35 -0300 |
---|---|---|
committer | Keader <keader.android@gmail.com> | 2016-05-11 20:54:50 -0300 |
commit | bf2cee8cce39e64590dc68bc35e5d3d2dd19cbaf (patch) | |
tree | f258d836774edc93a316c1b0756d563570d5298f | |
parent | 2640f37c665b2a11b7801f9e039ef7de1909ff83 (diff) |
Core/Movement: Fix issues where creatures cancel spell casts chasing target and Implement SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING
-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 d2d85dbfca6..9ec55343e7d 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 1a6fbeb44fb..47193cd0c45 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1857,6 +1857,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 94c37a8d6a3..533b087c7a1 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())) return; @@ -139,7 +142,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 1ce1c433620..8329e0f3ca1 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2974,12 +2974,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 @@ -3516,11 +3521,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(); } |