Jump to content

[update][9503] autot repeating spells behaviour


Auntie Mangos

Recommended Posts

This patch updates the behavior of the "auto shot" according to the changes in/with client version 3.0.2. I checked the behavior myself at an official server (some time ago, mostly auto shot) and with the help of przemratajczak (wand shoot, thanks :), see first bug report).

More information (bug reports):

http://getmangos.eu/community/showthread.php?11893 <-- most informations

http://getmangos.eu/community/showthread.php?9226

http://getmangos.eu/community/showthread.php?9605

http://getmangos.eu/community/showthread.php?1279

http://getmangos.eu/community/showthread.php?2846

... and some more

From 6e6aced55311cc74dc5f42c1dab9ae833250f17a Mon Sep 17 00:00:00 2001
From: [email][email protected][/email]
Date: Tue, 16 Feb 2010 13:25:16 +0100
Subject: Updated auto reapeating spells behavior

* "auto shot" won't be delayed anymore by ranged,non-channeled spells
* removed "auto shot" 0.5s pre cast time
* additionally fixed a server-client opcode sending loop
---
src/game/SpellHandler.cpp |    4 ++--
src/game/Unit.cpp         |   37 ++++++++++++++++++++++++-------------
src/game/Unit.h           |    4 +---
3 files changed, 27 insertions(+), 18 deletions(-)

diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index 4f0929b..790d1ba 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -487,9 +487,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 f1b3058..0fac1ea 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -3282,20 +3282,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))
@@ -3341,7 +3352,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;

@@ -3365,9 +3375,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:
@@ -3387,14 +3398,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 dff9adc..12ae2a1 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -1505,7 +1505,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
@@ -1784,9 +1784,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
        explicit Unit ();

        void _UpdateSpells(uint32 time);
-
        void _UpdateAutoRepeatSpell();
-        bool m_AutoRepeatFirstCast;

        uint32 m_attackTimer[MAX_ATTACK];

-- 
1.6.5.1.1367.gcd48


This patch also fixes an annoying behavior, when autoshot got stuck in loop between server and client opcode sending, when chaning the target, while autoshot is active already /I think I posted such a fix already, but did not find it anymore^^).

Edit: Hmm, typo in the topic. I can't change that.. :-(

Link to comment
Share on other sites

  • 40 years later...

patched my core, testes few minutes and form time to time, when clicked many times on steady shot and because of this autoshot delay was pretty long it started to shot with speed 0.5 few times at row (3-5) like machine gun xD, without dependence of weapon speed. when i will fogure out what i've done to cause that reacton i will post :P

Link to comment
Share on other sites

Thanks for trying,

but are you sure about that? I tried it one more time with spamming steady shot and also other shots in between. Could not find such a behavior :-/ Maybe you skilled 'Wild Quiver'... In combination with some client lags it will look like a machine gun^^ ...no idea. Keep me up to date if you found out something more.

btw.:

autoshot delay was pretty long

What do you mean by that?

Link to comment
Share on other sites

  • 7 months later...
Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use