aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells
diff options
context:
space:
mode:
authorQAston <qaston@gmail.com>2011-05-29 13:18:47 +0200
committerQAston <qaston@gmail.com>2011-05-29 13:18:47 +0200
commit42a20f14efd4ceede6839d7baa5ab268a06b49d4 (patch)
treeda4e9b39c78638f508e4de88e568423702ee7e9e /src/server/game/Spells
parentb2096c711ee0440c957b1fe7d12ccf2550725c98 (diff)
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.
Diffstat (limited to 'src/server/game/Spells')
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraDefines.h16
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp46
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h3
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.cpp56
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.h5
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp2
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp8
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h4
8 files changed, 75 insertions, 65 deletions
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index 9e9f965d96c..b4150fdc9e8 100755
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -33,16 +33,20 @@ enum AURA_FLAGS
AFLAG_NEGATIVE = 0x80
};
+// these are modes, in which aura effect handler may be called
+
enum AuraEffectHandleModes
{
AURA_EFFECT_HANDLE_DEFAULT = 0x0,
- AURA_EFFECT_HANDLE_REAL = 0x01,
- AURA_EFFECT_HANDLE_SEND_FOR_CLIENT = 0x02,
- AURA_EFFECT_HANDLE_CHANGE_AMOUNT = 0x04,
- AURA_EFFECT_HANDLE_STAT = 0x08,
- AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK = (AURA_EFFECT_HANDLE_SEND_FOR_CLIENT | AURA_EFFECT_HANDLE_REAL),
- AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK = (AURA_EFFECT_HANDLE_CHANGE_AMOUNT | AURA_EFFECT_HANDLE_REAL),
+ AURA_EFFECT_HANDLE_REAL = 0x01, // handler applies/removes effect from unit
+ AURA_EFFECT_HANDLE_SEND_FOR_CLIENT = 0x02, // handler sends apply/remove packet to unit
+ AURA_EFFECT_HANDLE_CHANGE_AMOUNT = 0x04, // handler updates effect on target after effect amount change
+ AURA_EFFECT_HANDLE_REAPPLY = 0x08, // handler updates effect on target after aura is reapplied on target
+ AURA_EFFECT_HANDLE_STAT = 0x10, // handler updates effect on target when stat removal/apply is needed for calculations by core
+ AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK = (AURA_EFFECT_HANDLE_SEND_FOR_CLIENT | AURA_EFFECT_HANDLE_REAL), // any case handler need to send packet
+ AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK = (AURA_EFFECT_HANDLE_CHANGE_AMOUNT | AURA_EFFECT_HANDLE_REAL), // any case handler applies effect depending on amount
AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK = (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK),
+ AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK = (AURA_EFFECT_HANDLE_REAPPLY | AURA_EFFECT_HANDLE_REAL),
};
//m_schoolAbsorb
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index e402a335985..cd981074c28 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -41,8 +41,8 @@ class Aura;
// EFFECT HANDLER NOTES
//
// in aura handler there should be check for modes:
-// AURA_EFFECT_HANDLE_REAL set - aura mod is just applied/removed on the target
-// AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK set - aura is just applied/removed, or aura packet request is made
+// AURA_EFFECT_HANDLE_REAL set
+// AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK set
// AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK set - aura is recalculated or is just applied/removed - need to redo all things related to m_amount
// AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK - logical or of above conditions
// AURA_EFFECT_HANDLE_STAT - set when stats are reapplied
@@ -940,38 +940,46 @@ void AuraEffect::CalculateSpellMod()
GetBase()->CallScriptEffectCalcSpellModHandlers(const_cast<AuraEffect const *>(this), m_spellmod);
}
-void AuraEffect::ChangeAmount(int32 newAmount, bool mark)
+void AuraEffect::ChangeAmount(int32 newAmount, bool mark, bool onStackOrReapply)
{
- //Unit * caster = GetCaster();
// Reapply if amount change
+ uint8 handleMask = 0;
if (newAmount != GetAmount())
+ handleMask |= AURA_EFFECT_HANDLE_CHANGE_AMOUNT;
+ if (onStackOrReapply)
+ handleMask |= AURA_EFFECT_HANDLE_REAPPLY;
+ if (!handleMask)
+ return;
+ UnitList targetList;
+ GetTargetList(targetList);
+ for (UnitList::iterator aurEffTarget = targetList.begin(); aurEffTarget != targetList.end(); ++aurEffTarget)
+ {
+ HandleEffect(*aurEffTarget, handleMask, false);
+ }
+ if (handleMask & AURA_EFFECT_HANDLE_REAPPLY)
{
- UnitList targetList;
- GetTargetList(targetList);
- for (UnitList::iterator aurEffTarget = targetList.begin(); aurEffTarget != targetList.end(); ++aurEffTarget)
- {
- HandleEffect(*aurEffTarget, AURA_EFFECT_HANDLE_CHANGE_AMOUNT, false);
- }
if (!mark)
m_amount = newAmount;
else
SetAmount(newAmount);
CalculateSpellMod();
- for (UnitList::iterator aurEffTarget = targetList.begin(); aurEffTarget != targetList.end(); ++aurEffTarget)
- {
- HandleEffect(*aurEffTarget, AURA_EFFECT_HANDLE_CHANGE_AMOUNT, true);
- }
+ }
+ for (UnitList::iterator aurEffTarget = targetList.begin(); aurEffTarget != targetList.end(); ++aurEffTarget)
+ {
+ HandleEffect(*aurEffTarget, handleMask, true);
}
}
void AuraEffect::HandleEffect(AuraApplication const * aurApp, uint8 mode, bool apply)
{
- // check if call is correct
+ // check if call is correct, we really don't want using bitmasks here (with 1 exception)
ASSERT(!mode
|| mode == AURA_EFFECT_HANDLE_REAL
|| mode == AURA_EFFECT_HANDLE_SEND_FOR_CLIENT
|| mode == AURA_EFFECT_HANDLE_CHANGE_AMOUNT
- || mode == AURA_EFFECT_HANDLE_STAT);
+ || mode == AURA_EFFECT_HANDLE_STAT
+ || mode == AURA_EFFECT_HANDLE_REAPPLY
+ || mode == (AURA_EFFECT_HANDLE_CHANGE_AMOUNT | AURA_EFFECT_HANDLE_REAPPLY));
// register/unregister effect in lists in case of real AuraEffect apply/remove
// registration/unregistration is done always before real effect handling (some effect handlers code is depending on this)
@@ -5748,7 +5756,7 @@ void AuraEffect::HandleAuraRetainComboPoints(AuraApplication const * aurApp, uin
void AuraEffect::HandleAuraDummy(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
- if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_REAPPLY)))
return;
Unit * target = aurApp->GetTarget();
@@ -5767,7 +5775,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const * aurApp, uint8 mode, boo
}
}
- if (mode & AURA_EFFECT_HANDLE_REAL)
+ if (mode & AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY)
{
// AT APPLY
if (apply)
@@ -6546,7 +6554,7 @@ void AuraEffect::HandleAuraConvertRune(AuraApplication const * aurApp, uint8 mod
void AuraEffect::HandleAuraLinked(AuraApplication const * aurApp, uint8 mode, bool apply) const
{
- if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ if (!(mode & (AURA_EFFECT_HANDLE_REAL | AURA_EFFECT_HANDLE_REAPPLY)))
return;
Unit * target = aurApp->GetTarget();
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index f8da99a4805..b03315b4ea2 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -14,6 +14,7 @@ typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const * aurApp, ui
class AuraEffect
{
friend void Aura::_InitEffects(uint8 effMask, Unit * caster, int32 *baseAmount);
+ friend Aura * Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const * newAura, uint8 effMask, int32 *baseAmount, Item * castItem, uint64 casterGUID);
friend Aura::~Aura();
private:
~AuraEffect();
@@ -43,7 +44,7 @@ class AuraEffect
int32 CalculateAmount(Unit * caster);
void CalculatePeriodic(Unit * caster, bool create = false);
void CalculateSpellMod();
- void ChangeAmount(int32 newAmount, bool mark = true);
+ void ChangeAmount(int32 newAmount, bool mark = true, bool onStackOrReapply = false);
void RecalculateAmount() { if (!CanBeRecalculated()) return; ChangeAmount(CalculateAmount(GetCaster()), false); }
void RecalculateAmount(Unit * caster) { if (!CanBeRecalculated()) return; ChangeAmount(CalculateAmount(caster), false); }
bool CanBeRecalculated() const { return m_canBeRecalculated; }
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index e41b5385619..e3371cf5ea3 100755
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -311,6 +311,8 @@ Aura * Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * o
{
case TYPEID_UNIT:
case TYPEID_PLAYER:
+ if (aura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, baseAmount, castItem, casterGUID))
+ return aura;
aura = new UnitAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
break;
case TYPEID_DYNAMICOBJECT:
@@ -717,9 +719,6 @@ void Aura::SetDuration(int32 duration, bool withMods)
void Aura::RefreshDuration()
{
SetDuration(GetMaxDuration());
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_effects[i])
- m_effects[i]->ResetPeriodic();
if (m_spellProto->manaPerSecond || m_spellProto->manaPerSecondPerLevel)
m_timeCla = 1 * IN_MILLISECONDS;
@@ -748,31 +747,36 @@ bool Aura::DropCharge()
return false;
}
-void Aura::SetStackAmount(uint8 stackAmount, bool /*applied*/)
+void Aura::SetStackAmount(uint8 stackAmount)
{
- if (stackAmount != m_stackAmount)
- {
- m_stackAmount = stackAmount;
- RecalculateAmountOfEffects();
- }
+ m_stackAmount = stackAmount;
+ Unit * caster = GetCaster();
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (HasEffect(i))
+ m_effects[i]->ChangeAmount(m_effects[i]->CalculateAmount(caster), false, true);
SetNeedClientUpdateForTargets();
}
-bool Aura::ModStackAmount(int32 num)
+void Aura::ModStackAmount(int32 num, AuraRemoveMode removeMode)
{
- // Can`t mod
- if (!m_spellProto->StackAmount || !GetStackAmount())
- return true;
-
- // Modify stack but limit it
int32 stackAmount = m_stackAmount + num;
+
+ // limit the stack amount
if (stackAmount > int32(m_spellProto->StackAmount))
- stackAmount = m_spellProto->StackAmount;
- else if (stackAmount <= 0) // Last aura from stack removed
{
- m_stackAmount = 0;
- return true; // need remove aura
+ // not stackable aura - set stack amount to 1
+ if(!m_spellProto->StackAmount)
+ stackAmount = 1;
+ else
+ stackAmount = m_spellProto->StackAmount;
+ }
+ // we're out of stacks, remove
+ else if (stackAmount <= 0)
+ {
+ Remove(removeMode);
+ return;
}
+
bool refresh = stackAmount >= GetStackAmount();
// Update stack amount
@@ -781,8 +785,6 @@ bool Aura::ModStackAmount(int32 num)
if (refresh)
RefreshDuration();
SetNeedClientUpdateForTargets();
-
- return false;
}
bool Aura::IsPassive() const
@@ -859,7 +861,7 @@ bool Aura::HasEffectType(AuraType type) const
{
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (m_effects[i] && m_effects[i]->GetAuraType() == type)
+ if (HasEffect(i) && m_effects[i]->GetAuraType() == type)
return true;
}
return false;
@@ -870,7 +872,7 @@ void Aura::RecalculateAmountOfEffects()
ASSERT (!IsRemoved());
Unit * caster = GetCaster();
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_effects[i])
+ if (HasEffect(i))
m_effects[i]->RecalculateAmount(caster);
}
@@ -1135,7 +1137,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster,
else
{
// Remove Linked Auras
- if (removeMode != AURA_REMOVE_BY_STACK && removeMode != AURA_REMOVE_BY_DEATH)
+ if (removeMode != AURA_REMOVE_BY_DEATH)
{
if (uint32 customAttr = sSpellMgr->GetSpellCustomAttr(GetId()))
{
@@ -1275,11 +1277,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster,
switch(GetId())
{
case 48018: // Demonic Circle
- // Do not remove GO when aura is removed by stack
- // to prevent remove GO added by new spell
- // old one is already removed
- if (removeMode != AURA_REMOVE_BY_STACK)
- target->RemoveGameObject(GetId(), true);
+ target->RemoveGameObject(GetId(), true);
target->RemoveAura(62388);
break;
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 6c42e94be55..396cefcf976 100755
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -79,6 +79,7 @@ class AuraApplication
class Aura
{
+ friend Aura * Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const * newAura, uint8 effMask, int32 *baseAmount, Item * castItem, uint64 casterGUID);
public:
typedef std::map<uint64, AuraApplication *> ApplicationMap;
@@ -130,8 +131,8 @@ class Aura
bool DropCharge();
uint8 GetStackAmount() const { return m_stackAmount; }
- void SetStackAmount(uint8 num, bool applied = true);
- bool ModStackAmount(int32 num); // return true if last charge dropped
+ void SetStackAmount(uint8 num);
+ void ModStackAmount(int32 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
uint8 GetCasterLevel() const { return m_casterLevel; }
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index cf7f10d9bdc..c852e2d133c 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3118,8 +3118,6 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
return true;
}
-//-----------TRINITY-------------
-
bool SpellMgr::CanAurasStack(Aura const *aura1, Aura const *aura2, bool sameCaster) const
{
SpellEntry const *spellInfo_1 = aura1->GetSpellProto();
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 752271f726b..35c05c87a44 100755
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -793,14 +793,14 @@ uint8 AuraScript::GetStackAmount() const
return m_aura->GetStackAmount();
}
-void AuraScript::SetStackAmount(uint8 num, bool applied)
+void AuraScript::SetStackAmount(uint8 num)
{
- m_aura->SetStackAmount(num, applied);
+ m_aura->SetStackAmount(num);
}
-bool AuraScript::ModStackAmount(int32 num)
+void AuraScript::ModStackAmount(int32 num, AuraRemoveMode removeMode)
{
- return m_aura->ModStackAmount(num);
+ return m_aura->ModStackAmount(num, removeMode);
}
bool AuraScript::IsPassive() const
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 64dc4282ad5..068673eb543 100755
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -606,8 +606,8 @@ class AuraScript : public _SpellScript
// stack amount manipulation
uint8 GetStackAmount() const;
- void SetStackAmount(uint8 num, bool applied = true);
- bool ModStackAmount(int32 num);
+ void SetStackAmount(uint8 num);
+ void ModStackAmount(int32 num, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
// passive - "working in background", not saved, not removed by immonities, not seen by player
bool IsPassive() const;