All pastes #917793 Raw Edit

Mine

public text v1 · immutable
#917793 ·published 2008-02-25 17:59 UTC
rendered paste body
Index: game/SpellAuras.cpp
===================================================================
--- game/SpellAuras.cpp	(revision 5306)
+++ game/SpellAuras.cpp	(working copy)
@@ -394,6 +394,11 @@
     else
         m_procCharges = -1;
 
+    // count from 1
+    m_stackAmmount = 1;
+	// give it some damage
+	m_stackDamage = damage;
+
     m_isRemovedOnShapeLost = (m_caster_guid==m_target->GetGUID() && m_spellProto->Stances &&
                             !(m_spellProto->AttributesEx2 & 0x80000) && !(m_spellProto->Attributes & 0x10000));
 }
@@ -741,20 +746,8 @@
     if(!m_target)
         return;
 
-    bool samespell = false;
     uint8 slot = 0xFF;
 
-    for(uint8 i = 0; i < 3; i++)
-    {
-        Aura* aura = m_target->GetAura(m_spellId, i);
-        if(aura)
-        {
-            samespell = true;
-            slot = aura->GetAuraSlot();
-            break;
-        }
-    }
-
     //if(m_spellId == 23333 || m_spellId == 23335)            // for BG
     //    m_positive = true;
 
@@ -776,56 +769,49 @@
     // passive auras (except totem auras) do not get placed in the slots
     if(!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem()))
     {
-        if(!samespell)
+        if (IsPositive())
         {
-            if (IsPositive())
+            for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
             {
-                for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++)
+                if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
                 {
-                    if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
-                    {
-                        slot = i;
-                        break;
-                    }
+                    slot = i;
+                    break;
                 }
             }
-            else
+        }
+        else
+        {
+            for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
             {
-                for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++)
+                if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
                 {
-                    if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0)
-                    {
-                        slot = i;
-                        break;
-                    }
+                    slot = i;
+                    break;
                 }
             }
+        }
 
-            if(slot < MAX_AURAS)
-            {
-                m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), GetId());
+        if(slot < MAX_AURAS)
+        {
+            m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), GetId());
 
-                uint8 flagslot = slot >> 2;
-                uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
+            uint8 flagslot = slot >> 2;
+            uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
+            
+            uint8 value1 = (slot & 3) << 3;
 
-                uint8 value1 = (slot & 3) << 3;
+            value &= ~((uint32)AFLAG_MASK << value1);
+            if (IsPositive())
+                value |= ((uint32)AFLAG_POSITIVE << value1);
+            else
+                value |= ((uint32)AFLAG_NEGATIVE << value1);
+            m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
+        }
 
-                value &= ~((uint32)AFLAG_MASK << value1);
-                if (IsPositive())
-                    value |= ((uint32)AFLAG_POSITIVE << value1);
-                else
-                    value |= ((uint32)AFLAG_NEGATIVE << value1);
-                m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
-            }
+        SetAuraSlot( slot );
+        UpdateAuraDuration();
 
-            SetAuraSlot( slot );
-            UpdateAuraDuration();
-        }
-        else
-        {
-            SetAuraSlot( slot );
-            UpdateSlotCounterAndDuration(true);
-        }
 
         // Update Seals information
         if( IsSealSpell(GetId()) )
@@ -878,93 +864,90 @@
     if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0)
         return;
 
-    bool samespell = false;
+    m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), 0);
 
-    for(uint8 i = 0; i < 3; i++)
-    {
-        Aura* aura = m_target->GetAura(m_spellId, i);
-        if(aura)
-        {
-            samespell = true;
-            break;
-        }
-    }
+    uint8 flagslot = slot >> 2;
 
-    // only remove icon when the last aura of the spell is removed (current aura already removed from list)
-    if (!samespell)
-    {
-        m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURA + slot), 0);
+    uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
 
-        uint8 flagslot = slot >> 2;
+    uint8 aurapos = (slot & 3) << 3;
+    value &= ~((uint32)AFLAG_MASK << aurapos );
 
-        uint32 value = m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot));
+    m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
+    if( IsSealSpell(GetId()) )
+        m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
 
-        uint8 aurapos = (slot & 3) << 3;
-        value &= ~((uint32)AFLAG_MASK << aurapos );
+    // Conflagrate aura state
+    if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
+        m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
 
-        m_target->SetUInt32Value((uint16)(UNIT_FIELD_AURAFLAGS + flagslot), value);
-        if( IsSealSpell(GetId()) )
-            m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
-
-        // Conflagrate aura state
-        if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
-            m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
-
-        // Swiftmend aura state
-        if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
-            && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
+    // Swiftmend aura state
+    if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
+         && (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
+    {
+        bool found = false;
+        Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
+        for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
         {
-            bool found = false;
-            Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
-            for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
+            if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
+                && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
             {
-                if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
-                    && ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
-                {
-                    found = true;
-                    break;
-                }
+                found = true;
+                break;
             }
-            if(!found)
-                m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
         }
-
-        // reset cooldown state for spells infinity/long aura (it's all self applied (?))
-        int32 duration = GetDuration(GetSpellProto());
-        if( caster==m_target && ( duration < 0 || uint32(duration) > GetRecoveryTime(GetSpellProto()) ))
-            SendCoolDownEvent();
+        if(!found)
+            m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
     }
-    else                                                    // decrease count for spell
-        UpdateSlotCounterAndDuration(false);
+
+    // reset cooldown state for spells infinity/long aura (it's all self applied (?))
+    int32 duration = GetDuration(GetSpellProto());
+    if( caster==m_target && ( duration < 0 || uint32(duration) > GetRecoveryTime(GetSpellProto()) ))
+        SendCoolDownEvent();
+
 }
 
-void Aura::UpdateSlotCounterAndDuration(bool add)
+void Aura::ModStackAmmount(int32 val)
 {
+	// Already Full
+    if( (m_stackAmmount + val) > m_spellProto->StackAmount )
+	{
+		val = m_spellProto->StackAmount - m_stackAmmount;
+        // nothing to change
+		if ( val == 0 )
+		    return;
+	}
+
+	m_stackAmmount += val;
+
+	// remove if empty
+	if ( m_stackAmmount <= 0 )
+	{
+		m_target->RemoveAura(m_spellId, m_effIndex);
+		return;
+	}
+    // modify damage
+	m_modifier.m_amount += m_stackDamage * val;
+	
+}
+
+void Aura::UpdateStackableAura(Unit* caster)
+{
     uint8 slot = GetAuraSlot();
     if(slot >= MAX_AURAS)
         return;
 
-    // calculate amount of similar auras by same effect index (similar different spells)
-    int8 count = 0;
+	SetAuraDuration(caster->CalculateSpellDuration(m_spellProto));
 
-    // calculate auras and update durations in case aura adding
-    Unit::AuraList const& aura_list = m_target->GetAurasByType(GetModifier()->m_auraname);
-    for(Unit::AuraList::const_iterator i = aura_list.begin();i != aura_list.end(); ++i)
-    {
-        if((*i)->m_spellId==m_spellId && (*i)->m_effIndex==m_effIndex)
-        {
-            ++count;
-
-            if(add)
-                (*i)->SetAuraDuration(GetAuraDuration());
-        }
+	// If not full yet
+	if ( m_stackAmmount < m_spellProto->StackAmount )
+	{
+        m_stackAmmount++;
+		// recalculate damage
+		m_stackDamage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,m_target);
+        m_modifier.m_amount = m_stackDamage*m_stackAmmount;
     }
 
-    // at aura add aura not added yet, at aura remove aura already removed
-    // in field stored (count-1)
-    if(!add)
-        --count;
-
     uint32 index = slot / 4;
     uint32 byte  = slot % 4;
     uint32 val   = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+index);
@@ -972,7 +955,7 @@
     uint32 byte_bitpos  = byte * 8;
     uint32 byte_mask = 0xFF << (byte * 8);
 
-    val = (val & ~byte_mask) | (count << byte_bitpos);
+    val = (val & ~byte_mask) | (m_stackAmmount << byte_bitpos);
 
     m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+index, val);
 
Index: game/SpellAuras.h
===================================================================
--- game/SpellAuras.h	(revision 5306)
+++ game/SpellAuras.h	(working copy)
@@ -259,6 +259,10 @@
         void SetUpdated(bool val) { m_updated = val; }
         void SetRemoveOnDeath(bool rod) { m_removeOnDeath = rod; }
 
+        void UpdateStackableAura(Unit* caster);
+        uint32 GetStackAmmount( void ) { return m_stackAmmount; }
+        void ModStackAmmount(int32 val);
+
         int32 m_procCharges;
 
         // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
@@ -295,8 +299,10 @@
         uint32 m_PeriodicEventId;
         bool m_updated;
         bool m_removeOnDeath;
+
+		uint32 m_stackAmmount;
+		int32 m_stackDamage;
     private:
-        void UpdateSlotCounterAndDuration(bool add);
         void CleanupTriggeredSpells();
 
         float m_fearMoveAngle;
Index: game/SpellEffects.cpp
===================================================================
--- game/SpellEffects.cpp	(revision 5306)
+++ game/SpellEffects.cpp	(working copy)
@@ -342,20 +342,23 @@
 
                         // remove consumed poison doses
                         Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
-                        for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;)
+                        for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end();++itr)
                         {
                             // Deadly poison
                             if((*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) && (*itr)->GetSpellProto()->SpellVisual==5100)
                             {
-                                --combo;
-                                ++doses;
 
-                                unitTarget->RemoveSingleAuraFromStack((*itr)->GetId(), (*itr)->GetEffIndex());
+								if ( combo > (*itr)->GetStackAmmount())
+									combo = (*itr)->GetStackAmmount();
 
-                                itr = auras.begin();
+								doses = (*itr)->GetStackAmmount();
+
+								if ( doses > combo)
+									doses = combo;
+
+								(*itr)->ModStackAmmount(combo*(-1));
+								break;
                             }
-                            else
-                                ++itr;
                         }
 
                         damage *= doses;
@@ -421,8 +424,13 @@
                     uint32 stacks = 0;
                     Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
                     for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
+					{
                         if((*itr)->GetId() == 31803)
-                            stacks++;
+						{
+                            stacks=(*itr)->GetStackAmmount();
+							break;
+						}
+					}
                     if(!stacks)
                         //No damage if the target isn't affected by this
                         damage = -1;
@@ -3229,7 +3237,8 @@
                 int32 duration = GetDuration(proto);
                 (*itr)->SetAuraDuration(duration);
                 (*itr)->UpdateAuraDuration();
-                sunder_stacks++;
+				sunder_stacks=(*itr)->GetStackAmmount();
+				break;
             }
         }
 
Index: game/Unit.cpp
===================================================================
--- game/Unit.cpp	(revision 5306)
+++ game/Unit.cpp	(working copy)
@@ -3435,14 +3435,14 @@
     // take out same spell
     if (i != m_Auras.end())
     {
-        /*(*i).second->SetAuraDuration(Aur->GetAuraDuration());
-        if ((*i).second->GetTarget())
-        if ((*i).second->GetTarget()->GetTypeId() == TYPEID_PLAYER )
-        (*i).second->UpdateAuraDuration();
-        delete Aur;
-        return false;*/
+        if ( Aur->GetSpellProto()->StackAmount)
+		{
+            Aur->UpdateStackableAura(this);
+		    delete Aur;
+			return false;
+		}
         // passive and persistent auras can stack with themselves any number of times
-        if (!Aur->IsPassive() && !Aur->IsPersistent() && m_Auras.count(spellEffectPair(Aur->GetId(), Aur->GetEffIndex())) >= Aur->GetSpellProto()->StackAmount)
+        if (!Aur->IsPassive() && !Aur->IsPersistent())
             RemoveAura(i);
     }
 
@@ -3739,13 +3739,6 @@
         RemoveAura(iter);
 }
 
-void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex)
-{
-    AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex));
-    if(iter != m_Auras.end())
-        RemoveAura(iter);
-}
-
 void Unit::RemoveAurasDueToSpell(uint32 spellId)
 {
     for (int i = 0; i < 3; ++i)
Index: game/Unit.h
===================================================================
--- game/Unit.h	(revision 5306)
+++ game/Unit.h	(working copy)
@@ -810,7 +810,6 @@
         bool RemoveFirstAuraByDispel(uint32 dispel_type, Unit *pCaster);
         void RemoveAura(AuraMap::iterator &i, bool onDeath = false);
         void RemoveAura(uint32 spellId, uint32 effindex);
-        void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex);
         void RemoveAurasDueToSpell(uint32 spellId);
         void RemoveAurasDueToItem(Item* castItem);
         void RemoveSpellsCausingAura(AuraType auraType);