[9503] Updated behavior of auto shot according to the client changes.

Signed-off-by: ApoC <apoc@nymfe.net>
This commit is contained in:
pasdVn 2010-03-02 22:09:00 +01:00 committed by ApoC
parent ab74b20006
commit 53623696cc
4 changed files with 28 additions and 19 deletions

View file

@ -494,9 +494,9 @@ void WorldSession::HandleCancelGrowthAuraOpcode( WorldPacket& /*recvPacket*/)
void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket*/) void WorldSession::HandleCancelAutoRepeatSpellOpcode( WorldPacket& /*recvPacket*/)
{ {
// may be better send SMSG_CANCEL_AUTO_REPEAT?
// cancel and prepare for deleting // 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) void WorldSession::HandleCancelChanneling( WorldPacket & recv_data)

View file

@ -3310,20 +3310,31 @@ void Unit::_UpdateSpells( uint32 time )
void Unit::_UpdateAutoRepeatSpell() void Unit::_UpdateAutoRepeatSpell()
{ {
//check "realtime" interrupts bool isAutoShot = m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id == SPELL_ID_AUTOSHOT;
if ( (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving()) || IsNonMeleeSpellCasted(false,false,true) )
//check movement
if (GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving())
{ {
// cancel wand shoot // cancel wand shoot
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT) if(!isAutoShot)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL); InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true; // auto shot just waits
return; return;
} }
//apply delay // check spell casts
if ( m_AutoRepeatFirstCast && getAttackTimer(RANGED_ATTACK) < 500 ) if (IsNonMeleeSpellCasted(false, false, true))
setAttackTimer(RANGED_ATTACK,500); {
m_AutoRepeatFirstCast = false; // 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 //castroutine
if (isAttackReady(RANGED_ATTACK)) if (isAttackReady(RANGED_ATTACK))
@ -3369,7 +3380,6 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
// break autorepeat if not Auto Shot // break autorepeat if not Auto Shot
if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT) if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != SPELL_ID_AUTOSHOT)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL); InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true;
} }
} break; } break;
@ -3393,9 +3403,10 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
// generic autorepeats break generic non-delayed and channeled non-delayed spells // generic autorepeats break generic non-delayed and channeled non-delayed spells
InterruptSpell(CURRENT_GENERIC_SPELL,false); InterruptSpell(CURRENT_GENERIC_SPELL,false);
InterruptSpell(CURRENT_CHANNELED_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; } break;
default: default:
@ -3415,14 +3426,14 @@ void Unit::SetCurrentCastedSpell( Spell * pSpell )
pSpell->m_selfContainer = &(m_currentSpells[pSpell->GetCurrentContainer()]); 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); assert(spellType < CURRENT_MAX_SPELL);
if (m_currentSpells[spellType] && (withDelayed || m_currentSpells[spellType]->getState() != SPELL_STATE_DELAYED) ) if (m_currentSpells[spellType] && (withDelayed || m_currentSpells[spellType]->getState() != SPELL_STATE_DELAYED) )
{ {
// send autorepeat cancel message for autorepeat spells // send autorepeat cancel message for autorepeat spells
if (spellType == CURRENT_AUTOREPEAT_SPELL) if (spellType == CURRENT_AUTOREPEAT_SPELL && sendAutoRepeatCancelToClient)
{ {
if(GetTypeId() == TYPEID_PLAYER) if(GetTypeId() == TYPEID_PLAYER)
((Player*)this)->SendAutoRepeatCancel(this); ((Player*)this)->SendAutoRepeatCancel(this);

View file

@ -1518,7 +1518,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void SetCurrentCastedSpell(Spell * pSpell); void SetCurrentCastedSpell(Spell * pSpell);
virtual void ProhibitSpellSchool(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/ ) { } 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); void FinishSpell(CurrentSpellTypes spellType, bool ok = true);
// set withDelayed to true to account delayed spells as casted // set withDelayed to true to account delayed spells as casted
@ -1796,9 +1796,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
explicit Unit (); explicit Unit ();
void _UpdateSpells(uint32 time); void _UpdateSpells(uint32 time);
void _UpdateAutoRepeatSpell(); void _UpdateAutoRepeatSpell();
bool m_AutoRepeatFirstCast;
uint32 m_attackTimer[MAX_ATTACK]; uint32 m_attackTimer[MAX_ATTACK];

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "9502" #define REVISION_NR "9503"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__