diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index e42e5237b..6819c0b48 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -494,9 +494,9 @@ void WorldSession::HandleCancelGrowthAuraOpcode( WorldPacket& /*recvPacket*/) void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket*/) { - // may be better send SMSG_CANCEL_AUTO_REPEAT? // cancel and prepare for deleting - _player->m_mover->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); + // do not send SMSG_CANCEL_AUTO_REPEAT! client will send this Opcode again (loop) + _player->m_mover->InterruptSpell(CURRENT_AUTOREPEAT_SPELL, true, false); } void WorldSession::HandleCancelChanneling( WorldPacket & recv_data) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 885b9f0b8..b6a727233 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -3310,20 +3310,31 @@ void Unit::_UpdateSpells( uint32 time ) void Unit::_UpdateAutoRepeatSpell() { - //check "realtime" interrupts - if ( (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving()) || IsNonMeleeSpellCasted(false,false,true) ) + bool isAutoShot = m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id == SPELL_ID_AUTOSHOT; + + //check movement + if (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving()) { // cancel wand shoot - if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT) + if(!isAutoShot) InterruptSpell(CURRENT_AUTOREPEAT_SPELL); - m_AutoRepeatFirstCast = true; + // auto shot just waits return; } - //apply delay - if ( m_AutoRepeatFirstCast && getAttackTimer(RANGED_ATTACK) < 500 ) - setAttackTimer(RANGED_ATTACK,500); - m_AutoRepeatFirstCast = false; + // check spell casts + if (IsNonMeleeSpellCasted(false, false, true)) + { + // cancel wand shoot + if(!isAutoShot) + { + InterruptSpell(CURRENT_AUTOREPEAT_SPELL); + return; + } + // auto shot is delayed by everythihng, except ranged(!) CURRENT_GENERIC_SPELL's -> recheck that + else if (!(m_currentSpells[CURRENT_GENERIC_SPELL] && m_currentSpells[CURRENT_GENERIC_SPELL]->IsRangedSpell())) + return; + } //castroutine if (isAttackReady(RANGED_ATTACK)) @@ -3369,7 +3380,6 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell ) // break autorepeat if not Auto Shot if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT) InterruptSpell(CURRENT_AUTOREPEAT_SPELL); - m_AutoRepeatFirstCast = true; } } break; @@ -3393,9 +3403,10 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell ) // generic autorepeats break generic non-delayed and channeled non-delayed spells InterruptSpell(CURRENT_GENERIC_SPELL,false); InterruptSpell(CURRENT_CHANNELED_SPELL,false); + // special action: first cast delay + if ( getAttackTimer(RANGED_ATTACK) < 500 ) + setAttackTimer(RANGED_ATTACK,500); } - // special action: set first cast flag - m_AutoRepeatFirstCast = true; } break; default: @@ -3415,14 +3426,14 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell ) pSpell->m_selfContainer = &(m_currentSpells[pSpell->GetCurrentContainer()]); } -void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed) +void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool sendAutoRepeatCancelToClient) { assert(spellType < CURRENT_MAX_SPELL); if (m_currentSpells[spellType] && (withDelayed || m_currentSpells[spellType]->getState() != SPELL_STATE_DELAYED) ) { // send autorepeat cancel message for autorepeat spells - if (spellType == CURRENT_AUTOREPEAT_SPELL) + if (spellType == CURRENT_AUTOREPEAT_SPELL && sendAutoRepeatCancelToClient) { if(GetTypeId() == TYPEID_PLAYER) ((Player*)this)->SendAutoRepeatCancel(this); diff --git a/src/game/Unit.h b/src/game/Unit.h index 0cf35b7df..545510b5f 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1518,7 +1518,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void SetCurrentCastedSpell(Spell * pSpell); virtual void ProhibitSpellSchool(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { } - void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed = true); + void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed = true, bool sendAutoRepeatCancelToClient = true); void FinishSpell(CurrentSpellTypes spellType, bool ok = true); // set withDelayed to true to account delayed spells as casted @@ -1796,9 +1796,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject explicit Unit (); void _UpdateSpells(uint32 time); - void _UpdateAutoRepeatSpell(); - bool m_AutoRepeatFirstCast; uint32 m_attackTimer[MAX_ATTACK]; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index af11d5604..1543359fe 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9502" + #define REVISION_NR "9503" #endif // __REVISION_NR_H__