aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNawuko <nawuko@nitx.de>2016-04-25 11:46:35 -0300
committerjoschiwald <joschiwald.trinity@gmail.com>2017-01-08 18:06:43 +0100
commit955bfae5efbb7cb0de367db539e03716691e75ba (patch)
tree37f48b60db21d0e5f34e7b6ac073a2dce423281b /src
parent86aa3997e4bdf6ee8a475e884cdb8b670eca790d (diff)
Core/Movement: Fix issues where creatures cancel spell casts chasing target and Implement SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING
(cherry picked from commit bf2cee8cce39e64590dc68bc35e5d3d2dd19cbaf)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp9
-rw-r--r--src/server/game/Entities/Unit/Unit.h3
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp5
-rw-r--r--src/server/game/Spells/Spell.cpp13
5 files changed, 26 insertions, 6 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 871b04c46f5..6f23f57b3c7 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -2983,6 +2983,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 6e16f94422c..26bf7a56751 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1957,6 +1957,9 @@ class TC_GAME_API Unit : public WorldObject
virtual SpellInfo const* GetCastSpellInfo(SpellInfo const* spellInfo) const;
uint32 GetCastSpellXSpellVisualId(SpellInfo const* spellInfo) const;
+ // Check if our current channel spell has attribute SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING
+ bool CanMoveDuringChannel() const;
+
SpellHistory* GetSpellHistory() { return _spellHistory; }
SpellHistory const* GetSpellHistory() const { return _spellHistory; }
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index e2366680b81..5a7f92babb9 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -540,7 +540,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 1d160aad634..04f4c9edb63 100755
--- 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 69e2369da39..6fc944770fd 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -3036,14 +3036,19 @@ 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)
// 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->isMoving() &&
m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) && !m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
{
- 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
@@ -3589,7 +3594,7 @@ void Spell::update(uint32 difftime)
!m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
{
// 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();
}