diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 23 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 1 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraDefines.h | 4 | ||||
| -rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 6 | ||||
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 16 | 
5 files changed, 36 insertions, 14 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f8baf13cdd1..bf2a9a1fc1f 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2745,7 +2745,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)) && -        !HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, autoRepeatSpellInfo)) +        !CanCastSpellWhileMoving(autoRepeatSpellInfo))      {          // cancel wand shoot          if (autoRepeatSpellInfo->Id != 75) @@ -2967,6 +2967,10 @@ bool Unit::IsMovementPreventedByCasting() const      if (!HasUnitState(UNIT_STATE_CASTING))          return false; +    if (Spell* spell = m_currentSpells[CURRENT_GENERIC_SPELL]) +        if (CanCastSpellWhileMoving(spell->GetSpellInfo())) +            return false; +      // 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()) @@ -2977,6 +2981,21 @@ bool Unit::IsMovementPreventedByCasting() const      return true;  } +bool Unit::CanCastSpellWhileMoving(SpellInfo const* spellInfo) const +{ +    if (HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, spellInfo)) +        return true; + +    if (HasAuraType(SPELL_AURA_CAST_WHILE_WALKING_ALL)) +        return true; + +    for (uint32 label : spellInfo->Labels) +        if (HasAuraTypeWithMiscvalue(SPELL_AURA_CAST_WHILE_WALKING_BY_SPELL_LABEL, label)) +            return true; + +    return false; +} +  bool Unit::isInFrontInMap(Unit const* target, float distance,  float arc) const  {      return IsWithinDistInMap(target, distance) && HasInArc(arc, target); @@ -3874,7 +3893,7 @@ bool IsInterruptFlagIgnoredForSpell(InterruptFlag /*flag*/, Unit const* /*unit*/  template<>  bool IsInterruptFlagIgnoredForSpell(SpellAuraInterruptFlags flag, Unit const* unit, SpellInfo const* spellInfo)  { -    return flag == SpellAuraInterruptFlags::Moving && unit->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, spellInfo); +    return flag == SpellAuraInterruptFlags::Moving && unit->CanCastSpellWhileMoving(spellInfo);  }  template <typename InterruptFlags> diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 95efb8fc925..82b94f3b096 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1498,6 +1498,7 @@ class TC_GAME_API Unit : public WorldObject          virtual bool IsFocusing(Spell const* /*focusSpell*/ = nullptr, bool /*withDelay*/ = false) { return false; }          virtual bool IsMovementPreventedByCasting() const; +        bool CanCastSpellWhileMoving(SpellInfo const* spellInfo) const;          SpellHistory* GetSpellHistory() { return _spellHistory; }          SpellHistory const* GetSpellHistory() const { return _spellHistory; } diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 040c7a1df7b..2287a1f772f 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -392,7 +392,7 @@ enum AuraType : uint32      SPELL_AURA_MOD_FAKE_INEBRIATE                           = 304,      SPELL_AURA_MOD_MINIMUM_SPEED                            = 305,      SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER                   = 306, -    SPELL_AURA_CAST_WHILE_WALKING_BY_SPELL_LABEL            = 307,  // NYI +    SPELL_AURA_CAST_WHILE_WALKING_BY_SPELL_LABEL            = 307,      SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_WITH_ABILITIES    = 308,      SPELL_AURA_MOD_RESILIENCE                               = 309,  // NYI      SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE            = 310, @@ -462,7 +462,7 @@ enum AuraType : uint32      SPELL_AURA_MODIFY_FALL_DAMAGE_PCT                       = 374,  // NYI      SPELL_AURA_HIDE_MODEL_AND_EQUIPEMENT_SLOTS              = 375,      SPELL_AURA_MOD_CURRENCY_GAIN_FROM_SOURCE                = 376,  // NYI -    SPELL_AURA_CAST_WHILE_WALKING_2                         = 377,  // NYI +    SPELL_AURA_CAST_WHILE_WALKING_ALL                       = 377,  // Enables casting all spells while moving      SPELL_AURA_MOD_POSSESS_PET                              = 378,      SPELL_AURA_MOD_MANA_REGEN_PCT                           = 379,      SPELL_AURA_380                                          = 380, diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index d1cd0b044fe..ff7ffd5f443 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -375,7 +375,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=      &AuraEffect::HandleAuraModFakeInebriation,                    //304 SPELL_AURA_MOD_DRUNK      &AuraEffect::HandleAuraModIncreaseSpeed,                      //305 SPELL_AURA_MOD_MINIMUM_SPEED      &AuraEffect::HandleNoImmediateEffect,                         //306 SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER implemented in Unit::GetUnitCriticalChance and Unit::GetUnitSpellCriticalChance -    &AuraEffect::HandleNULL,                                      //307 SPELL_AURA_CAST_WHILE_WALKING_BY_SPELL_LABEL +    &AuraEffect::HandleNoImmediateEffect,                         //307 SPELL_AURA_CAST_WHILE_WALKING_BY_SPELL_LABEL implemented in Unit::CanCastSpellWhileMoving      &AuraEffect::HandleNoImmediateEffect,                         //308 SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER_WITH_ABILITIES implemented in Unit::GetUnitSpellCriticalChance      &AuraEffect::HandleNULL,                                      //309 SPELL_AURA_MOD_RESILIENCE      &AuraEffect::HandleNoImmediateEffect,                         //310 SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE implemented in Spell::CalculateDamageDone @@ -398,7 +398,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=      &AuraEffect::HandlePhaseAlwaysVisible,                        //327 SPELL_AURA_PHASE_ALWAYS_VISIBLE      &AuraEffect::HandleTriggerSpellOnPowerPercent,                //328 SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT      &AuraEffect::HandleNULL,                                      //329 SPELL_AURA_MOD_POWER_GAIN_PCT -    &AuraEffect::HandleNoImmediateEffect,                         //330 SPELL_AURA_CAST_WHILE_WALKING +    &AuraEffect::HandleNoImmediateEffect,                         //330 SPELL_AURA_CAST_WHILE_WALKING implemented in Unit::CanCastSpellWhileMoving      &AuraEffect::HandleAuraForceWeather,                          //331 SPELL_AURA_FORCE_WEATHER      &AuraEffect::HandleNoImmediateEffect,                         //332 SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS implemented in Unit::GetCastSpellInfo      &AuraEffect::HandleNoImmediateEffect,                         //333 SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_TRIGGERED implemented in Unit::GetCastSpellInfo @@ -445,7 +445,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=      &AuraEffect::HandleNULL,                                      //374 SPELL_AURA_MODIFY_FALL_DAMAGE_PCT      &AuraEffect::HandleNULL,                                      //375 SPELL_AURA_HIDE_MODEL_AND_EQUIPEMENT_SLOTS implemented clientside      &AuraEffect::HandleNULL,                                      //376 SPELL_AURA_MOD_CURRENCY_GAIN_FROM_SOURCE -    &AuraEffect::HandleNULL,                                      //377 SPELL_AURA_CAST_WHILE_WALKING_2 +    &AuraEffect::HandleNoImmediateEffect,                         //377 SPELL_AURA_CAST_WHILE_WALKING_ALL implemented in Unit::CanCastSpellWhileMoving      &AuraEffect::HandleModPossessPet,                             //378 SPELL_AURA_MOD_POSSESS_PET      &AuraEffect::HandleModManaRegenPct,                           //379 SPELL_AURA_MOD_MANA_REGEN_PCT implemented in Player::UpdateManaRegen      &AuraEffect::HandleNULL,                                      //380 diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 90efc980ffb..90d342e1b3d 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3153,8 +3153,8 @@ void Spell::prepare(SpellCastTargets const& targets, AuraEffect const* triggered      // 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->ToPlayer()->IsCharmed() && m_caster->ToPlayer()->GetCharmerGUID().IsCreature()) && m_caster->ToPlayer()->isMoving() && -        m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::Movement)) && !m_caster->ToPlayer()->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo)) +    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))      {          // 1. Has casttime, 2. Or doesn't have flag to allow movement during channel          if (m_casttime || !m_spellInfo->IsMoveAllowedChannel()) @@ -3843,9 +3843,9 @@ 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->ToPlayer()->isMoving() && (m_spellInfo->InterruptFlags.HasFlag(SpellInterruptFlags::Movement)) && -        (!m_spellInfo->HasEffect(SPELL_EFFECT_STUCK) || !m_caster->ToPlayer()->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) && -        !m_caster->ToPlayer()->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo)) +        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))      {          // don't cancel for melee, autorepeat, triggered and instant spells          if (!m_spellInfo->IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered() && !(IsChannelActive() && m_spellInfo->IsMoveAllowedChannel())) @@ -3853,7 +3853,7 @@ void Spell::update(uint32 difftime)              // 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->ToPlayer()->GetCharmerGUID().IsCreature()) +            if (!m_caster->ToUnit()->GetCharmerGUID().IsCreature())                  cancel();          }      } @@ -5268,7 +5268,9 @@ SpellCastResult Spell::CheckCast(bool strict, int32* param1 /*= nullptr*/, int32          // 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->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo)) +        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)) &&  | 
