aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Unit
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2018-01-27 03:45:40 -0300
committerAriel Silva <ariel-@users.noreply.github.com>2018-03-09 14:41:28 -0300
commite8d5aa56cc48572d81e1898b7b4ff10cfa6d1957 (patch)
treeb21b5dff1cdb693074e23eb57906f6a2a2182a76 /src/server/game/Entities/Unit
parent9b38a6352c0fe2499de54fd769aa1c721a410bda (diff)
Core/Spells: rework part 3: spells only handle at most one UnitAura and one DynObjAura during its lifetime
Closes #15088
Diffstat (limited to 'src/server/game/Entities/Unit')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp84
-rw-r--r--src/server/game/Entities/Unit/Unit.h14
2 files changed, 61 insertions, 37 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 1538c5ffac6..96fc1caf649 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3409,29 +3409,29 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId());
}
-Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool resetPeriodicTimer /*= true*/)
+Aura* Unit::_TryStackingOrRefreshingExistingAura(AuraCreateInfo& createInfo)
{
- ASSERT(casterGUID || caster);
+ ASSERT(createInfo.CasterGUID || createInfo.Caster);
// Check if these can stack anyway
- if (!casterGUID && !newAura->IsStackableOnOneSlotWithDifferentCasters())
- casterGUID = caster->GetGUID();
+ if (!createInfo.CasterGUID && !createInfo.GetSpellInfo()->IsStackableOnOneSlotWithDifferentCasters())
+ createInfo.CasterGUID = createInfo.Caster->GetGUID();
// passive and Incanter's Absorption and auras with different type can stack with themselves any number of times
- if (!newAura->IsMultiSlotAura())
+ if (!createInfo.GetSpellInfo()->IsMultiSlotAura())
{
// check if cast item changed
ObjectGuid castItemGUID;
- if (castItem)
- castItemGUID = castItem->GetGUID();
+ if (createInfo.CastItem)
+ castItemGUID = createInfo.CastItem->GetGUID();
// find current aura from spell and change it's stackamount, or refresh it's duration
- if (Aura* foundAura = GetOwnedAura(newAura->Id, casterGUID, newAura->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : ObjectGuid::Empty, 0))
+ if (Aura* foundAura = GetOwnedAura(createInfo.GetSpellInfo()->Id, createInfo.CasterGUID, createInfo.GetSpellInfo()->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : ObjectGuid::Empty))
{
// effect masks do not match
// extremely rare case
// let's just recreate aura
- if (effMask != foundAura->GetEffectMask())
+ if (createInfo.GetAuraEffectMask() != foundAura->GetEffectMask())
return nullptr;
// update basepoints with new values - effect amount will be recalculated in ModStackAmount
@@ -3440,11 +3440,9 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8
if (!foundAura->HasEffect(i))
continue;
- int bp;
- if (baseAmount)
- bp = *(baseAmount + i);
- else
- bp = foundAura->GetSpellInfo()->Effects[i].BasePoints;
+ int32 bp = foundAura->GetSpellInfo()->Effects[i].BasePoints;
+ if (createInfo.BaseAmount)
+ bp = *(createInfo.BaseAmount + i);
int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(i)->m_baseAmount));
*oldBP = bp;
@@ -3458,7 +3456,7 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8
}
// try to increase stack amount
- foundAura->ModStackAmount(1, AURA_REMOVE_BY_DEFAULT, resetPeriodicTimer);
+ foundAura->ModStackAmount(1, AURA_REMOVE_BY_DEFAULT, createInfo.ResetPeriodicTimer);
return foundAura;
}
}
@@ -3469,7 +3467,7 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8
void Unit::_AddAura(UnitAura* aura, Unit* caster)
{
ASSERT(!m_cleanupDone);
- m_ownedAuras.insert(AuraMap::value_type(aura->GetId(), aura));
+ m_ownedAuras.emplace(aura->GetId(), aura);
_RemoveNoStackAurasDueToAura(aura);
@@ -3506,7 +3504,7 @@ void Unit::_AddAura(UnitAura* aura, Unit* caster)
// creates aura application instance and registers it in lists
// aura application effects are handled separately to prevent aura list corruption
-AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint8 effMask)
+AuraApplication* Unit::_CreateAuraApplication(Aura* aura, uint8 effMask)
{
// can't apply aura on unit which is going to be deleted - to not create a memory leak
ASSERT(!m_cleanupDone);
@@ -3556,7 +3554,7 @@ void Unit::_ApplyAuraEffect(Aura* aura, uint8 effIndex)
// handles effects of aura application
// should be done after registering aura in lists
-void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask)
+void Unit::_ApplyAura(AuraApplication* aurApp, uint8 effMask)
{
Aura* aura = aurApp->GetBase();
@@ -3599,7 +3597,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask)
}
// removes aura application from lists and unapplies effects
-void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode)
+void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMode)
{
AuraApplication * aurApp = i->second;
ASSERT(aurApp);
@@ -3687,7 +3685,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo
i = m_appliedAuras.begin();
}
-void Unit::_UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode)
+void Unit::_UnapplyAura(AuraApplication* aurApp, AuraRemoveMode removeMode)
{
// aura can be removed from unit only if it's applied on it, shouldn't happen
ASSERT(aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) == aurApp);
@@ -3756,8 +3754,8 @@ void Unit::_RegisterAuraEffect(AuraEffect* aurEff, bool apply)
m_modAuras[aurEff->GetAuraType()].remove(aurEff);
}
-// All aura base removes should go threw this function!
-void Unit::RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode)
+// All aura base removes should go through this function!
+void Unit::RemoveOwnedAura(AuraMap::iterator& i, AuraRemoveMode removeMode)
{
Aura* aura = i->second;
ASSERT(!aura->IsRemoved());
@@ -4087,7 +4085,12 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, U
if (aura->IsSingleTarget())
aura->UnregisterSingleTarget();
- if (Aura* newAura = Aura::TryRefreshStackOrCreate(aura->GetSpellInfo(), effMask, stealer, nullptr, &baseDamage[0], nullptr, aura->GetCasterGUID()))
+ AuraCreateInfo createInfo(aura->GetSpellInfo(), effMask, stealer);
+ createInfo
+ .SetCasterGUID(aura->GetCasterGUID())
+ .SetBaseAmount(baseDamage);
+
+ if (Aura* newAura = Aura::TryRefreshStackOrCreate(createInfo))
{
// created aura must not be single target aura,, so stealer won't loose it on recast
if (newAura->IsSingleTarget())
@@ -12738,11 +12741,18 @@ Aura* Unit::AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target)
{
if (!(effMask & (1 << i)))
continue;
+
if (target->IsImmunedToSpellEffect(spellInfo, i, this))
effMask &= ~(1 << i);
}
- if (Aura* aura = Aura::TryRefreshStackOrCreate(spellInfo, effMask, target, this))
+ if (!effMask)
+ return nullptr;
+
+ AuraCreateInfo createInfo(spellInfo, effMask, target);
+ createInfo.SetCaster(this);
+
+ if (Aura* aura = Aura::TryRefreshStackOrCreate(createInfo))
{
aura->ApplyForTargets();
return aura;
@@ -13365,17 +13375,24 @@ void Unit::HandleSpellClick(Unit* clicker, int8 seatId /*= -1*/)
{
CastSpellExtraArgs args(flags);
args.OriginalCaster = origCasterGUID;
- args.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1);
+ args.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), seatId + 1);
caster->CastSpell(target, clickPair.second.spellId, args);
}
else // This can happen during Player::_LoadAuras
{
- int32 bp0[MAX_SPELL_EFFECTS];
+ int32 bp[MAX_SPELL_EFFECTS] = { };
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
- bp0[j] = spellEntry->Effects[j].BasePoints;
+ bp[j] = spellEntry->Effects[j].BasePoints;
- bp0[i] = seatId;
- Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, bp0, nullptr, origCasterGUID);
+ bp[i] = seatId;
+
+ AuraCreateInfo createInfo(spellEntry, MAX_EFFECT_MASK, this);
+ createInfo
+ .SetCaster(clicker)
+ .SetBaseAmount(bp)
+ .SetCasterGUID(origCasterGUID);
+
+ Aura::TryRefreshStackOrCreate(createInfo);
}
}
else
@@ -13383,7 +13400,14 @@ void Unit::HandleSpellClick(Unit* clicker, int8 seatId /*= -1*/)
if (IsInMap(caster))
caster->CastSpell(target, spellEntry->Id, CastSpellExtraArgs().SetOriginalCaster(origCasterGUID));
else
- Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, nullptr, nullptr, origCasterGUID);
+ {
+ AuraCreateInfo createInfo(spellEntry, MAX_EFFECT_MASK, this);
+ createInfo
+ .SetCaster(clicker)
+ .SetCasterGUID(origCasterGUID);
+
+ Aura::TryRefreshStackOrCreate(createInfo);
+ }
}
spellClickHandled = true;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 642c25f49f9..9e7755521d8 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -756,7 +756,7 @@ class TC_GAME_API Unit : public WorldObject
typedef std::list<AuraEffect*> AuraEffectList;
typedef std::list<Aura*> AuraList;
- typedef std::list<AuraApplication *> AuraApplicationList;
+ typedef std::list<AuraApplication*> AuraApplicationList;
typedef std::vector<std::pair<uint8 /*procEffectMask*/, AuraApplication*>> AuraApplicationProcContainer;
@@ -1234,13 +1234,13 @@ class TC_GAME_API Unit : public WorldObject
bool InitTamedPet(Pet* pet, uint8 level, uint32 spell_id);
// aura apply/remove helpers - you should better not use these
- Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool resetPeriodicTimer = true);
+ Aura* _TryStackingOrRefreshingExistingAura(AuraCreateInfo& createInfo);
void _AddAura(UnitAura* aura, Unit* caster);
- AuraApplication * _CreateAuraApplication(Aura* aura, uint8 effMask);
+ AuraApplication* _CreateAuraApplication(Aura* aura, uint8 effMask);
void _ApplyAuraEffect(Aura* aura, uint8 effIndex);
- void _ApplyAura(AuraApplication * aurApp, uint8 effMask);
- void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
- void _UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode);
+ void _ApplyAura(AuraApplication* aurApp, uint8 effMask);
+ void _UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMode);
+ void _UnapplyAura(AuraApplication* aurApp, AuraRemoveMode removeMode);
void _RemoveNoStackAurasDueToAura(Aura* aura);
void _RegisterAuraEffect(AuraEffect* aurEff, bool apply);
@@ -1248,7 +1248,7 @@ class TC_GAME_API Unit : public WorldObject
AuraMap & GetOwnedAuras() { return m_ownedAuras; }
AuraMap const& GetOwnedAuras() const { return m_ownedAuras; }
- void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveOwnedAura(AuraMap::iterator& i, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveOwnedAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveOwnedAura(Aura* aura, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);