rendered paste bodyIndex: 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);