rendered paste bodyIndex: game/Spell.cpp
===================================================================
--- game/Spell.cpp (revision 6055)
+++ game/Spell.cpp (working copy)
@@ -328,7 +328,7 @@
m_triggeredByAuraSpell = NULL;
m_autoRepeat = false;
- if( m_spellInfo->AttributesEx2 == 0x000020 ) //Auto Shot & Shoot
+ if( m_spellInfo->AttributesEx2 == 0x000020 && !triggered ) //Auto Shot & Shoot
m_autoRepeat = true;
m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
@@ -339,7 +339,7 @@
m_meleeSpell = false;
- m_rangedShoot = ((m_spellInfo->Attributes & 18) == 18);
+ m_rangedShoot = (m_spellInfo->Attributes & 2);
if( m_spellInfo->StartRecoveryTime == 0 && !m_autoRepeat && !m_rangedShoot )
{
for (int i = 0; i < 3; i++)
@@ -1835,10 +1835,6 @@
m_caster->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
}
- // do first cast of autorepeat spell with recovery time delay (like after any autocast)
- if(IsAutoRepeat())
- m_spellState = SPELL_STATE_FINISHED;
-
if(m_IsTriggeredSpell)
cast(true);
else
@@ -1971,6 +1967,20 @@
UpdatePointers(); // pointers can be invalidate at triggered spell casting
}
+ if (IsMeleeAttackResetSpell())
+ {
+ if ( m_rangedShoot )
+ {
+ m_caster->resetAttackTimer(RANGED_ATTACK);
+ }
+ else
+ {
+ m_caster->resetAttackTimer(BASE_ATTACK);
+ if(m_caster->haveOffhandWeapon())
+ m_caster->resetAttackTimer(OFF_ATTACK);
+ }
+ }
+
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
if (m_spellInfo->speed > 0.0f)
{
@@ -2275,7 +2285,7 @@
m_timer -= difftime;
}
- if(m_timer == 0 && !m_meleeSpell)
+ if(m_timer == 0 && !m_meleeSpell && !m_autoRepeat)
cast();
} break;
case SPELL_STATE_CASTING:
@@ -2395,13 +2405,6 @@
}
}
- if (IsMeleeAttackResetSpell())
- {
- m_caster->resetAttackTimer(BASE_ATTACK);
- if(m_caster->haveOffhandWeapon())
- m_caster->resetAttackTimer(OFF_ATTACK);
- }
-
// Clear combo at finish state
if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo))
((Player*)m_caster)->ClearComboPoints();
Index: game/Unit.cpp
===================================================================
--- game/Unit.cpp (revision 6055)
+++ game/Unit.cpp (working copy)
@@ -3059,96 +3059,65 @@
void Unit::_UpdateAutoRepeatSpell()
{
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_FINISHED)
+ if ( m_AutoRepeatFirstCast )
{
- //Auto Shot & Shoot
- if( m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->AttributesEx2 == 0x000020 && GetTypeId() == TYPEID_PLAYER )
- {
- // Auto Shot don't require ranged weapon cooldown at first cast, wand shoot does, so the 'FINISHED' state
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
- {
- // Shoot
- resetAttackTimer( RANGED_ATTACK );
- }
- else
- {
- // Auto Shoot
- if (m_AutoRepeatFirstCast)
- {
- // first cast only with recovery time (not less)
- if (getAttackTimer( RANGED_ATTACK ) < m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime)
- setAttackTimer( RANGED_ATTACK, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime);
- m_AutoRepeatFirstCast = false;
- }
- else
- {
- // second or further casts
- resetAttackTimer( RANGED_ATTACK );
- }
- }
- }
- else
- {
- setAttackTimer( RANGED_ATTACK, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime);
- }
+ if ( getAttackTimer(RANGED_ATTACK) < m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime() )
+ setAttackTimer(RANGED_ATTACK,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime());
+
+ m_AutoRepeatFirstCast = false;
+ return;
+ }
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_IDLE);
- }
- else if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_IDLE && isAttackReady(RANGED_ATTACK) )
+ if (isAttackReady(RANGED_ATTACK))
{
- // check if we can cast
- if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true) == 0)
- {
- // check movement in player case
+ if(!IsNonMeleeSpellCasted(false,false,true))
if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving())
{
// cancel wand shooting
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
// ELSE delay auto-repeat ranged weapon until player movement stop
+ // this will setup 0.5s cast time
+ setAttackTimer(RANGED_ATTACK,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime());
+ return;
}
- else
- // recheck range and req. items (ammo and gun, etc)
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckRange(true) == 0 && m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckItems() == 0 )
- {
- // check, if we are casting melee spell (it blocks autorepeat)
- if ( ! (m_currentSpells[CURRENT_MELEE_SPELL] &&
- (m_currentSpells[CURRENT_MELEE_SPELL]->getState() != SPELL_STATE_FINISHED) &&
- (m_currentSpells[CURRENT_MELEE_SPELL]->getState() != SPELL_STATE_DELAYED)) )
- {
- // check, if we are casting something else, if no then run autorepeat spell
- if (!IsNonMeleeSpellCasted(false, false, true))
- {
- // wee need clear target list before recasting
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CleanupTargetList();
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_PREPARING);
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->ReSetTimer();
- }
- }
- }
- else
- {
+
+ // Check if able to cast
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckRange(true) != 0 ||
+ m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckItems() != 0 ||
+ m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true) != 0)
+ {
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
- }
- }
- else
- {
- InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
- }
- }
- else if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_PREPARING)
- {
- // check, if some other incomplete spell exists (including melee) or ranged attack is not ready
- if ( m_currentSpells[CURRENT_MELEE_SPELL] ||
- m_currentSpells[CURRENT_GENERIC_SPELL] ||
- m_currentSpells[CURRENT_CHANNELED_SPELL] ||
- !isAttackReady(RANGED_ATTACK) )
- {
- // some other spell is here or ranged attack is not ready, break us to idle state
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->finish(false);
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_IDLE);
- }
- }
+ return;
+ }
+
+ // we want to shoot
+ Spell* spell = new Spell(this, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo, true, 0);
+ spell->prepare(&(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets));
+ // all went good, reset attack
+ resetAttackTimer(RANGED_ATTACK);
+ }
+ // Attack Ready, but something prevents us from castubg
+ else
+ {
+ // this will setup 0.5s cast time
+ setAttackTimer(RANGED_ATTACK,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime());
+ }
+ }
+ // Ranged Attack not ready yet
+ else
+ {
+ // moving, cancel wand shoot
+ if ( GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving() )
+ {
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
+ InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
+
+ if ( getAttackTimer(RANGED_ATTACK) < m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime() )
+ setAttackTimer(RANGED_ATTACK,m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->GetCastTime());
+ }
+ }
+
}
void Unit::SetCurrentCastedSpell( Spell * pSpell )
Index: game/Spell.cpp
===================================================================
--- game/Spell.cpp (revision 6055)
+++ game/Spell.cpp (working copy)
@@ -328,7 +328,7 @@
m_triggeredByAuraSpell = NULL;
m_autoRepeat = false;
- if( m_spellInfo->AttributesEx2 == 0x000020 ) //Auto Shot & Shoot
+ if( m_spellInfo->AttributesEx2 == 0x000020 && !triggered ) //Auto Shot & Shoot
m_autoRepeat = true;
m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
@@ -339,7 +339,7 @@
m_meleeSpell = false;
- m_rangedShoot = ((m_spellInfo->Attributes & 18) == 18);
+ m_rangedShoot = (m_spellInfo->Attributes & 2);
if( m_spellInfo->StartRecoveryTime == 0 && !m_autoRepeat && !m_rangedShoot )
{
for (int i = 0; i < 3; i++)
@@ -1835,10 +1835,6 @@
m_caster->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
}
- // do first cast of autorepeat spell with recovery time delay (like after any autocast)
- if(IsAutoRepeat())
- m_spellState = SPELL_STATE_FINISHED;
-
if(m_IsTriggeredSpell)
cast(true);
else
@@ -1971,6 +1967,20 @@
UpdatePointers(); // pointers can be invalidate at triggered spell casting
}
+ if (IsMeleeAttackResetSpell())
+ {
+ if ( m_rangedShoot )
+ {
+ m_caster->resetAttackTimer(RANGED_ATTACK);
+ }
+ else
+ {
+ m_caster->resetAttackTimer(BASE_ATTACK);
+ if(m_caster->haveOffhandWeapon())
+ m_caster->resetAttackTimer(OFF_ATTACK);
+ }
+ }
+
// Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
if (m_spellInfo->speed > 0.0f)
{
@@ -2275,7 +2285,7 @@
m_timer -= difftime;
}
- if(m_timer == 0 && !m_meleeSpell)
+ if(m_timer == 0 && !m_meleeSpell && !m_autoRepeat)
cast();
} break;
case SPELL_STATE_CASTING:
@@ -2395,13 +2405,6 @@
}
}
- if (IsMeleeAttackResetSpell())
- {
- m_caster->resetAttackTimer(BASE_ATTACK);
- if(m_caster->haveOffhandWeapon())
- m_caster->resetAttackTimer(OFF_ATTACK);
- }
-
// Clear combo at finish state
if(m_caster->GetTypeId() == TYPEID_PLAYER && NeedsComboPoints(m_spellInfo))
((Player*)m_caster)->ClearComboPoints();
Index: game/Unit.cpp
===================================================================
--- game/Unit.cpp (revision 6055)
+++ game/Unit.cpp (working copy)
@@ -3059,96 +3059,66 @@
void Unit::_UpdateAutoRepeatSpell()
{
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_FINISHED)
+ if ( m_AutoRepeatFirstCast )
{
- //Auto Shot & Shoot
- if( m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->AttributesEx2 == 0x000020 && GetTypeId() == TYPEID_PLAYER )
- {
- // Auto Shot don't require ranged weapon cooldown at first cast, wand shoot does, so the 'FINISHED' state
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
- {
- // Shoot
- resetAttackTimer( RANGED_ATTACK );
- }
- else
- {
- // Auto Shoot
- if (m_AutoRepeatFirstCast)
- {
- // first cast only with recovery time (not less)
- if (getAttackTimer( RANGED_ATTACK ) < m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime)
- setAttackTimer( RANGED_ATTACK, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime);
- m_AutoRepeatFirstCast = false;
- }
- else
- {
- // second or further casts
- resetAttackTimer( RANGED_ATTACK );
- }
- }
- }
- else
- {
- setAttackTimer( RANGED_ATTACK, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->RecoveryTime);
- }
+ if ( getAttackTimer(RANGED_ATTACK) < 500 )
+ setAttackTimer(RANGED_ATTACK,500);
+
+ m_AutoRepeatFirstCast = false;
+ return;
+ }
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_IDLE);
- }
- else if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_IDLE && isAttackReady(RANGED_ATTACK) )
+ if (isAttackReady(RANGED_ATTACK))
{
- // check if we can cast
- if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true) == 0)
+ if(!IsNonMeleeSpellCasted(false,false,true))
{
- // check movement in player case
if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving())
{
// cancel wand shooting
if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
// ELSE delay auto-repeat ranged weapon until player movement stop
+ // this will setup 0.5s cast time
+ setAttackTimer(RANGED_ATTACK,500);
+ return;
}
- else
- // recheck range and req. items (ammo and gun, etc)
- if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckRange(true) == 0 && m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckItems() == 0 )
- {
- // check, if we are casting melee spell (it blocks autorepeat)
- if ( ! (m_currentSpells[CURRENT_MELEE_SPELL] &&
- (m_currentSpells[CURRENT_MELEE_SPELL]->getState() != SPELL_STATE_FINISHED) &&
- (m_currentSpells[CURRENT_MELEE_SPELL]->getState() != SPELL_STATE_DELAYED)) )
- {
- // check, if we are casting something else, if no then run autorepeat spell
- if (!IsNonMeleeSpellCasted(false, false, true))
- {
- // wee need clear target list before recasting
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CleanupTargetList();
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_PREPARING);
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->ReSetTimer();
- }
- }
- }
- else
- {
+
+ // Check if able to cast
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckRange(true) != 0 ||
+ m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CheckItems() != 0 ||
+ m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->CanCast(true) != 0)
+ {
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
- }
- }
- else
- {
- InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
- }
- }
- else if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_PREPARING)
- {
- // check, if some other incomplete spell exists (including melee) or ranged attack is not ready
- if ( m_currentSpells[CURRENT_MELEE_SPELL] ||
- m_currentSpells[CURRENT_GENERIC_SPELL] ||
- m_currentSpells[CURRENT_CHANNELED_SPELL] ||
- !isAttackReady(RANGED_ATTACK) )
- {
- // some other spell is here or ranged attack is not ready, break us to idle state
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->finish(false);
- m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->setState(SPELL_STATE_IDLE);
- }
- }
+ return;
+ }
+
+ // we want to shoot
+ Spell* spell = new Spell(this, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo, true, 0);
+ spell->prepare(&(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_targets));
+ // all went good, reset attack
+ resetAttackTimer(RANGED_ATTACK);
+ }
+ // Attack Ready, but something prevents us from castubg
+ else
+ {
+ // this will setup 0.5s cast time
+ setAttackTimer(RANGED_ATTACK,500);
+ }
+ }
+ // Ranged Attack not ready yet
+ else
+ {
+ // moving, cancel wand shoot
+ if ( GetTypeId() == TYPEID_PLAYER && ((Player*)this)->isMoving() )
+ {
+ if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Category == 351)
+ InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
+
+ if ( getAttackTimer(RANGED_ATTACK) < 500 )
+ setAttackTimer(RANGED_ATTACK,500);
+ }
+ }
+
}
void Unit::SetCurrentCastedSpell( Spell * pSpell )