Jump to content

Prevent Spell Stacking


Recommended Posts

               // prevent fire resistance totem from stacking
       if( spellInfo_1->SpellIconID==1712 && spellInfo_2->SpellIconID==1712 )
           return false;

If you don't want them to stack, IsNoStackSpellDueToSpell is supposed to return true. :)

That said, there are perhaps other alternatives you might try before adding to the growing number of IsNoStack SpellIcon hacks.

You could add spell_chain data for ranks of spells you don't want to be able to stack on a case-by-case basis, and let the IsRankSpellDueToSpell check return true. Of course, we can't assume that the spell_chain table is ever complete; which is the whole point of having more generic checks.

So better yet, you could try adding a SpellFamilyFlags check that returns true when SpellFamilyFlags are identical after the

    if (spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
        return false;

to ensure the spells are from the same class. This would make far more sense as a "generic" check, as it would prevent raid versions of normal buffs from stacking when the SpellIcons are different (like Gift of the Wild to Mark of the Wild, Prayer of Fortitude to PW: Fortitude, etc.) without relying on data in spell_chain or SpellSpecific checks.

Currently, I am working on a patch to remove all the hack checks from IsNoStackSpellDueToSpell anyway - or at least the hacks that return false. However, I am still working on the logic for the patch (many food buffs are stacking where they shouldn't), and there are many more cases that still need to be checked.

Link to comment
Share on other sites

  • 39 years later...

I was working on a fix for the shaman spell "Fire Resistance Totem" (Example: http://www.wowhead.com/?spell=8184 http://www.wowhead.com/?spell=8185). I am trying to prevent multiple ranks of the spell from stacking with each other. Basically, I have set-up a section of SpellMgr.cpp (SpellMgr::IsNoStackSpellDueToSpell() lines 1410-1428) to look like this:

       case SPELLFAMILY_SHAMAN:
           if( spellInfo_2->SpellFamilyName == SPELLFAMILY_SHAMAN )
           {
               // shaman shields
               if( IsElementalShield(spellInfo_1) && IsElementalShield(spellInfo_2) )
                   return true;

               // Windfury weapon
               if( spellInfo_1->SpellIconID==220 && spellInfo_2->SpellIconID==220 &&
                   spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags )
                   return false;

               // prevent fire resistance totem from stacking
       if( spellInfo_1->SpellIconID==1712 && spellInfo_2->SpellIconID==1712 )
           return false;
           }
           // Bloodlust and Bloodthirst (multi-family check)
           if( spellInfo_1->Id == 2825 && spellInfo_2->SpellIconID == 38 && spellInfo_2->SpellVisual == 0 )
               return false;
           break;

I have added the extra lines after the Windfury check, where 1712 is it's icon (I've checked Spell.DBC and I've also made sure that they are both SPELLFAMILY_SHAMAN spells)

However, they still stack without a problem. Does anyone know what might be incorrect or what might need checking as well to keep them from stacking?

Link to comment
Share on other sites

:o It's because totem buffs use SPELL_ATTR_PASSIVE, so they don't call IsNoStackSpellDueToSpell at all. My apologies for not checking this more carefully. I would add a more generic check in IsRankSpellDueToSpell in that patch, but that'd require a bit more restructuring, because IsHighRankOfSpell assumes that both spells have spell_chain data after IsRankSpellDueToSpell returns true. So the only alternative for now is just to add the spell_chain data, I think.

Since you are here, do you have any ideas on how I would keep Curse of Tongues from applying on bosses?

I'm not certain about this. Most debuffs are checked in the ImmuneMechanicMask, but I see CoT doesn't have a mechanic.

On a whim, I think it might have something to do with SPELL_ATTR_EX4_UNK29. It looks like that is shared with many debuffs, with or without mechanics, that should be "partly" effective against bosses. In addition to CoT, Frostbrand Attack has it (slow not always effective, but Aura applied anyway for Frozen Power talent) and Disarm has it (disarm not always effective, but damage increase (for when the warrior has Improved Disarm Talent) should be applied).

Edit: nvm, don't think it'll work; rank 9 Frostbrand Attack doesn't have it (unless it's related to the SP bug that Frostbrand had in 3.1.x?)

If you want to know what creatures are considered raid bosses, it's in the Rank column of creature_template (I think it's set to 4).

Link to comment
Share on other sites

As 1 shaman can have only one totem at a time, the real problem is that totem effects stack _from different casters_. This could probably be solved usin the check in Unit::RemoveNoStackAurasDueToAura. Try to find an attribute or something in the dbc files that could properly identify those spells and try to add it to the spellspecific defines, and to GetSpellSpecific. If you were successful you have a good chance to make them don't stack using IsSingleFromSpellSpecificRanksPerTarget. I hope it solves it, at least it should.

Link to comment
Share on other sites

I tried adding this into Unit::RemoveNoStackAurasDueToAura

        if( is_sspt && spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && i_spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellIconID == 1712 && i_spellProto->SpellIconID == 1712 )
       {
           // cannot remove higher rank
           if (spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
               if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0)
                   return false;

           // Its a parent aura (create this aura in ApplyModifier)
           if ((*i).second->IsInUse())
           {
               sLog.outError("Aura (Spell %u Effect %u) is in process but attempt removed at aura (Spell %u Effect %u) adding, need add stack rule for Unit::RemoveNoStackAurasDueToAura", i->second->GetId(), i->second->GetEffIndex(),Aur->GetId(), Aur->GetEffIndex());
               continue;
           }
           RemoveAurasDueToSpell(i_spellId);

           if( m_Auras.empty() )
               break;
           else
               next =  m_Auras.begin();
       }

But no success, it still stacks without a problem.

Link to comment
Share on other sites

No, no, it looks i wasn't clear enough. Look at the declaraion of bool is_sspt. You'll see that it is done by the function called IsSingleFromSpellSpecificRanksPerTarget and the 2 arguments are spellspec and i_spellspec which are defined by the function GetSpellSpecific. You'll have to somewhat modify these functions, i'll explain it with an example. Paladin Greater Blessing don't stack as u can see in the latest core. In RemoveNoStackAurasDueToAura the server has an aura (that we check stacking for) and the auramap of the aura's target. While iterating through th auramap it compares the araus to each other in many ways. The one you'll need is sspt. For both spells it determines their spellspecific in spellspecific and i_spellspecific (you'll see both clearly declared) by calling GetSpellSpecific for both the aura we check and the current aura in the iterator. In GetSpellSpecific there is a simple check that returns SpellSpecific that is from enum SpellSpecific. In thi enum you'll see many spells besides the paladin blessing well as a first step you should add totems here with something like SPELL_TOTEM. If you did that let's get back to GetSpellSpecific. In this funciton you'll have to create a case for totem spells. For this you'll have to find something that clearly and exactly identifies totem spells and do not affect more than required. It is clear what it does if you look at the code (SpellMgr.cpp). If that's done go back to is_sspt bool which will do the real work. In IsSingleFromSpellSpecificRanksPerTarget happens the real decision that spels _that have spellspecific_ can stack or not. Here you'll just have to declare that if both spells are SPELL_TOTEM, then it should return true, this way preventing stacking.

I hope this'll be clear and detailed enough;)

Link to comment
Share on other sites

If this affects of _single_ spell then why not just declarate its in spel_chain and assign ranks and then it will not stascked as same spells ranks from same caster

Tried that. Had absolutely no effect. Added the spells in the spellbook, and the spells the totems themselves use.

I'm going to look into what Lightguard is saying. I'll get back to you with a patch if it works at all.

Link to comment
Share on other sites

Ah, is there a RemoveTotemByCaster function or something that would fix it?

I'm going to check how it is handled casting different spell ranks by same caster right now and try and duplicate it. Would you mind posting the fix that actually worked?

As far as I can tell, here is code to unsummon existing totems from the same rank: in SpellEffects.cpp lines 5071-5080 Spell::EffectSummonTotem()

    if(slot < MAX_TOTEM)
   {
       uint64 guid = m_caster->m_TotemSlot[slot];
       if(guid != 0)
       {
           Creature *OldTotem = m_caster->GetMap()->GetCreature(guid);
           if(OldTotem && OldTotem->isTotem())
               ((Totem*)OldTotem)->UnSummon();
       }
   }

I guess, water spells have a certain totem slot they share, and that prevents using different ranks of the spell. Unfortunately, that does not solve the group problem. Perhaps should do checks against if there are any totems of the same ID in the given area, if the caster is in the same group, and if the spell has the same icon?

Link to comment
Share on other sites

The problem is that totem spells are passive. Passive spells are checked like 3 times before reaching sspt, so no real chance to get this correctly working.

At least, not easily.

The only thing I can think of would be, when summoning a new totem, check if there are any totems in the area with the same displayID. If there are, check if they are from someone in the same group as the owner. If they are, check if their spell has the same icon ID as the spell the new totem casts. If so, unsummon totem (remove auras from it as well? not sure if it's needed...)

If that's even possible.

Link to comment
Share on other sites

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