Jump to content

[11144][fix] Usable while stunned abilities


darkstalker

Recommended Posts

* What bug does the patch fix? What features does the patch add?

Prevents abilities that are "usable while stunned" being usable while in non-stun effects like Cyclone or Sap. With this patch the usability while stunned is restricted only to stun auras with mechanic stun.

* For which repository revision was the patch created?

11044

* Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread.

no

* Who has been writing this patch? Please include either forum user names or email addresses.

darkstalker

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index ab4b0fc..267c104 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -5575,8 +5575,25 @@ SpellCastResult Spell::CheckCasterAuras() const
    SpellCastResult prevented_reason = SPELL_CAST_OK;
    // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
    uint32 unitflag = m_caster->GetUInt32Value(UNIT_FIELD_FLAGS);     // Get unit state
-    if (unitflag & UNIT_FLAG_STUNNED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
-        prevented_reason = SPELL_FAILED_STUNNED;
+    if (unitflag & UNIT_FLAG_STUNNED)
+    {
+        // spell is usable while stunned, check if aura has mechanic stun
+        if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)
+        {
+            bool is_stun_mechanic = true;
+            Unit::AuraList const& stunAuras = m_caster->GetAurasByType(SPELL_AURA_MOD_STUN);
+            for (Unit::AuraList::const_iterator itr = stunAuras.begin(); itr != stunAuras.end(); ++itr)
+                if (!(*itr)->HasMechanic(MECHANIC_STUN))
+                {
+                    is_stun_mechanic = false;
+                    break;
+                }
+            if (!is_stun_mechanic)
+                prevented_reason = SPELL_FAILED_STUNNED;
+        }
+        else
+            prevented_reason = SPELL_FAILED_STUNNED;
+    }
    else if (unitflag & UNIT_FLAG_CONFUSED && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
        prevented_reason = SPELL_FAILED_CONFUSED;
    else if (unitflag & UNIT_FLAG_FLEEING && !(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
@@ -5625,7 +5642,7 @@ SpellCastResult Spell::CheckCasterAuras() const
                        switch(aura->GetModifier()->m_auraname)
                        {
                            case SPELL_AURA_MOD_STUN:
-                                if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
+                                if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED) || !aura->HasMechanic(MECHANIC_STUN))
                                    return SPELL_FAILED_STUNNED;
                                break;
                            case SPELL_AURA_MOD_CONFUSE:
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 3e9151f..b8edc90 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -8014,6 +8014,12 @@ bool Aura::IsLastAuraOnHolder()
    return true;
}

+bool Aura::HasMechanic(uint32 mechanic) const
+{
+    return GetSpellProto()->Mechanic == mechanic ||
+        GetSpellProto()->EffectMechanic[m_effIndex] == mechanic;
+}
+
SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit *target, WorldObject *caster, Item *castItem) :
m_target(target), m_castItemGuid(castItem ? castItem->GetObjectGuid() : ObjectGuid()),
m_auraSlot(MAX_AURAS), m_auraFlags(AFLAG_NONE), m_auraLevel(1), m_procCharges(0),
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index 9812dd2..5147d1c 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -436,6 +436,8 @@ class MANGOS_DLL_SPEC Aura
        SpellAuraHolder* const GetHolder() const { return m_spellAuraHolder; }

        bool IsLastAuraOnHolder();
+
+        bool HasMechanic(uint32 mechanic) const;
    protected:
        Aura(SpellEntry const* spellproto, SpellEffectIndex eff, int32 *currentBasePoints, SpellAuraHolder *holder, Unit *target, Unit *caster = NULL, Item* castItem = NULL);

Link to comment
Share on other sites

well You get auras by SPELL_AURA_MOD_STUN... and then if some has no mechanic means we need to stop cause aura with different mechanci should not allow us casting such spell (like he said for example if we have stun and cyclone, we shouldnt be able to cast some spells therefore if we find Cyclone first we break code instantly and return)

Link to comment
Share on other sites

  • 2 weeks later...
  • 1 month later...

I see it have

#define SPELL_ATTR_EX5_USABLE_WHILE_STUNNED 0x00000008 // 3 usable while stunned

#define SPELL_ATTR_EX5_USABLE_WHILE_FEARED 0x00020000 // 17 usable while feared

#define SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED 0x00040000 // 18 usable while confused

in same time

I not sure in reasons apply original patch, but look like spells that have all 3 set interpret stun in wide way as done old code.

Link to comment
Share on other sites

Hm, I think this commit is wrong in some cases :|

spell http://www.wowhead.com/spell=51209 has:

Mechanic = 13 (MECHANIC_FREEZE)
Aura Id 12 (SPELL_AURA_MOD_STUN)

spell http://www.wowhead.com/spell=33786 has:

Mechanic = 18 (MECHANIC_BANISH)
Aura Id 12 (SPELL_AURA_MOD_STUN)

spell http://www.wowhead.com/spell=20066 has:

Mechanic = 14 (MECHANIC_KNOCKOUT)
Aura Id 12 (SPELL_AURA_MOD_STUN)

spell http://www.wowhead.com/spell=20511 has:

Mechanic = 5 (MECHANIC_FEAR)
Aura Id 12 (SPELL_AURA_MOD_STUN)

So in code "is_stun_mechanic = false;" will be set and using spells like http://www.wowhead.com/spell=59752 will be prevented

I do not know all special cases, but maybe we should only exclude spells 59752 and 42292 here.

if (!(*itr)->HasMechanic(MECHANIC_STUN) && spellInfo->Id != 59752 && spellInfo->Id != 42292)

or we should check more mechanics here (probably better):

rewritten code part of code in first post:

    if (unitflag & UNIT_FLAG_STUNNED)
   {
       // spell is usable while stunned
       if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED)
       {
           bool is_stun_mechanic = true;
           Unit::AuraList const& stunAuras = m_caster->GetAurasByType(SPELL_AURA_MOD_STUN);
           for (Unit::AuraList::const_iterator itr = stunAuras.begin(); itr != stunAuras.end(); ++itr)
           // check spell mechanics
           if (!((*itr)->HasMechanic(MECHANIC_STUN)
              || (*itr)->HasMechanic(MECHANIC_FREEZE) 
              || (*itr)->HasMechanic(MECHANIC_BANISH)
              || (*itr)->HasMechanic(MECHANIC_KNOCKOUT)
              || (*itr)->HasMechanic(MECHANIC_FEAR)))
               {
                   is_stun_mechanic = false;
                   break;
               }
           if (!is_stun_mechanic)
               prevented_reason = SPELL_FAILED_STUNNED;
       }
       else
           prevented_reason = SPELL_FAILED_STUNNED;
   }

Link to comment
Share on other sites

I think this just special spell case:

"The warrior shouts, causing up to 5 enemies within 8 yards to cower in fear. The targeted enemy will be unable to move while cowering. Lasts 8 sec."

It is fear effect, but applies stun aura

Link to comment
Share on other sites

* What bug does the patch fix? What features does the patch add?

Prevents abilities that are "usable while stunned" being usable while in non-stun effects like Cyclone or Sap. With this patch the usability while stunned is restricted only to stun auras with mechanic stun.

Ah, I see :) And you are right, patch is wrong and needs revert.

Link to comment
Share on other sites

Every Man for Himself has wrong data on dbc:

AttributesEx 163840 SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY | SPELL_ATTR_EX_UNK17

AttributesEx5 393224 SPELL_ATTR_EX5_USABLE_WHILE_STUNNED | SPELL_ATTR_EX5_USABLE_WHILE_FEARED | SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED

Effect0 6 SPELL_EFFECT_APPLY_AURA

EffectApplyAuraName0 77 SPELL_AURA_MECHANIC_IMMUNITY

EffectMiscValue0 1 MECHANIC_CHARM

it just removes mechanic charm, not whats listed in the tooltip (same as 42292 "PvP Trinket").

So a better "fix" would be:

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 57d689d..b97b762 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -5660,7 +5660,8 @@ SpellCastResult Spell::CheckCasterAuras() const
                dispel_immune |= GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i]));
        }
        // immune movement impairment and loss of control
-        if (m_spellInfo->Id == 42292)                       // PvP Trinket
+        if (m_spellInfo->Id == 42292 ||                     // PvP Trinket
+            m_spellInfo->Id == 59752)                       // Every Man for Himself
            mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
    }

Link to comment
Share on other sites

No, I have no custom patches concerning this.

But in your last posted code the only thing affected is:

mechanic_immune = IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;

Isn't this only to prevent stunning a player who already has aura of this spell?

And not for getting out of stun with using this spell?

Link to comment
Share on other sites

  • 1 month later...
Every Man for Himself has wrong data on dbc:

In fact not exactly meaning "wrong" but spell dbc not have way cleary describe like "total" case

so used special format coding this: aura = 77 misc = 1 (other effects empty) + SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY

Also for all like spells set

SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED

SPELL_ATTR_EX5_USABLE_WHILE_FEARED

SPELL_ATTR_EX5_USABLE_WHILE_STUNNED

But for selection spell its not need included in checked.

So your way look like must work but need more generic selection special spells as i describe.

Fix added in [11540]. :)

Link to comment
Share on other sites

×
×
  • 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