Core/Auras: Use existing aura object on aura reapply/stack increase instead of creating a new one.
You can hook on reapply/stack event by checking for AURA_EFFECT_HANDLE_REAPPLY aura handler mode, AURA_EFFECT_HANDLE_REAL is now not triggered on aura refresh/stack.
This commit is contained in:
@@ -3143,35 +3143,62 @@ void Unit::DeMorph()
|
||||
SetDisplayId(GetNativeDisplayId());
|
||||
}
|
||||
|
||||
Aura * Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const * newAura, uint8 effMask, int32 *baseAmount, Item * castItem, uint64 casterGUID)
|
||||
{
|
||||
ASSERT(casterGUID);
|
||||
// passive and Incanter's Absorption and auras with different type can stack with themselves any number of times
|
||||
if (!IsPassiveSpell(newAura) && newAura->Id != 44413)
|
||||
{
|
||||
// check if cast item changed
|
||||
uint64 castItemGUID = 0;
|
||||
if (castItem)
|
||||
castItemGUID = castItem->GetGUID();
|
||||
|
||||
// find current aura from spell and change it's stackamount, or refresh it's duration
|
||||
if (Aura * foundAura = GetOwnedAura(newAura->Id, casterGUID, (sSpellMgr->GetSpellCustomAttr(newAura->Id) & SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : 0, 0))
|
||||
{
|
||||
// effect masks do not match
|
||||
// extremely rare case
|
||||
// let's just recreate aura
|
||||
if (effMask != foundAura->GetEffectMask())
|
||||
return false;
|
||||
|
||||
// update basepoints with new values - effect amount will be recalculated in ModStackAmount
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (!foundAura->m_effects[i])
|
||||
continue;
|
||||
int bp;
|
||||
if (baseAmount)
|
||||
bp = *(baseAmount + i);
|
||||
else
|
||||
bp = foundAura->GetSpellProto()->EffectBasePoints[i];
|
||||
|
||||
int32 *oldBP = const_cast<int32 *>(&(foundAura->m_effects[i]->m_baseAmount));
|
||||
*oldBP = bp;
|
||||
}
|
||||
|
||||
// correct cast item guid if needed
|
||||
if (castItemGUID != foundAura->GetCastItemGUID())
|
||||
{
|
||||
uint64 *oldGUID = const_cast<uint64 *>(&foundAura->m_castItemGuid);
|
||||
*oldGUID = castItemGUID;
|
||||
}
|
||||
|
||||
// try to increase stack amount
|
||||
foundAura->ModStackAmount(1);
|
||||
|
||||
return foundAura;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Unit::_AddAura(UnitAura * aura, Unit * caster)
|
||||
{
|
||||
ASSERT(!m_cleanupDone);
|
||||
m_ownedAuras.insert(AuraMap::value_type(aura->GetId(), aura));
|
||||
|
||||
// passive and Incanter's Absorption and auras with different type can stack with themselves any number of times
|
||||
if (!aura->IsPassive() && aura->GetId() != 44413)
|
||||
{
|
||||
// find current aura from spell and change it's stackamount
|
||||
if (Aura * foundAura = GetOwnedAura(aura->GetId(), aura->GetCasterGUID(), (sSpellMgr->GetSpellCustomAttr(aura->GetId()) & SPELL_ATTR0_CU_ENCHANT_PROC) ? aura->GetCastItemGUID() : 0, 0, aura))
|
||||
{
|
||||
if (aura->GetSpellProto()->StackAmount)
|
||||
aura->ModStackAmount(foundAura->GetStackAmount());
|
||||
|
||||
// Update periodic timers from the previous aura
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
AuraEffect *existingEff = foundAura->GetEffect(i);
|
||||
AuraEffect *newEff = aura->GetEffect(i);
|
||||
if (!existingEff || !newEff)
|
||||
continue;
|
||||
newEff->SetPeriodicTimer(existingEff->GetPeriodicTimer());
|
||||
}
|
||||
|
||||
// Use the new one to replace the old one
|
||||
// This is the only place where AURA_REMOVE_BY_STACK should be used
|
||||
RemoveOwnedAura(foundAura, AURA_REMOVE_BY_STACK);
|
||||
}
|
||||
}
|
||||
_RemoveNoStackAurasDueToAura(aura);
|
||||
|
||||
if (aura->IsRemoved())
|
||||
@@ -3648,11 +3675,11 @@ void Unit::RemoveAuraFromStack(uint32 spellId, uint64 caster, AuraRemoveMode rem
|
||||
{
|
||||
for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
|
||||
{
|
||||
Aura const * aura = iter->second;
|
||||
Aura * aura = iter->second;
|
||||
if ((aura->GetType() == UNIT_AURA_TYPE)
|
||||
&& (!caster || aura->GetCasterGUID() == caster))
|
||||
{
|
||||
RemoveAuraFromStack(iter, removeMode);
|
||||
aura->ModStackAmount(-1,removeMode);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -3660,12 +3687,6 @@ void Unit::RemoveAuraFromStack(uint32 spellId, uint64 caster, AuraRemoveMode rem
|
||||
}
|
||||
}
|
||||
|
||||
inline void Unit::RemoveAuraFromStack(AuraMap::iterator &iter, AuraRemoveMode removeMode, uint8 chargesRemoved/*= 1*/)
|
||||
{
|
||||
if (iter->second->ModStackAmount(-chargesRemoved))
|
||||
RemoveOwnedAura(iter, removeMode);
|
||||
}
|
||||
|
||||
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit* dispeller, uint8 chargesRemoved/*= 1*/)
|
||||
{
|
||||
for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
|
||||
@@ -3679,7 +3700,7 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit
|
||||
aura->DropCharge();
|
||||
}
|
||||
else
|
||||
RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL, chargesRemoved);
|
||||
aura->ModStackAmount(-chargesRemoved, AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
|
||||
switch (aura->GetSpellProto()->SpellFamilyName)
|
||||
{
|
||||
@@ -3837,7 +3858,7 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit
|
||||
if (stealCharge)
|
||||
aura->DropCharge();
|
||||
else
|
||||
RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user