aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2018-01-27 03:45:40 -0300
committerShauren <shauren.trinity@gmail.com>2021-08-28 15:59:11 +0200
commitf3548d45d0a74203ef6f5c7282c31ba794ddf7a1 (patch)
tree94a7c69af30d4b13018457cf40c06366ebc11ba9 /src/server/game/Entities
parent52ae3c89d1d4dbcff309d940fd41c7212edc77b7 (diff)
Core/Spells: rework part 3: spells only handle at most one UnitAura and one DynObjAura during its lifetime
Closes #15088 (cherry picked from commit e8d5aa56cc48572d81e1898b7b4ff10cfa6d1957)
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp7
-rw-r--r--src/server/game/Entities/Player/Player.cpp8
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp103
-rw-r--r--src/server/game/Entities/Unit/Unit.h14
4 files changed, 78 insertions, 54 deletions
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 7df230526dc..f7bd8b75bb1 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -1210,7 +1210,12 @@ void Pet::_LoadAuras(uint32 timediff)
AuraLoadEffectInfo& info = effectInfo[key];
ObjectGuid castId = ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellInfo->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>());
- if (Aura* aura = Aura::TryCreate(spellInfo, castId, key.EffectMask, this, nullptr, difficulty, info.BaseAmounts.data(), nullptr, casterGuid))
+ AuraCreateInfo createInfo(castId, spellInfo, difficulty, key.EffectMask, this);
+ createInfo
+ .SetCasterGUID(casterGuid)
+ .SetBaseAmount(info.BaseAmounts.data());
+
+ if (Aura* aura = Aura::TryCreate(createInfo))
{
if (!aura->CanBeSaved())
{
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 441b6c8bd4d..bbb4ccf5887 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -18759,7 +18759,13 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
AuraLoadEffectInfo& info = effectInfo[key];
ObjectGuid castId = ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellInfo->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>());
- if (Aura* aura = Aura::TryCreate(spellInfo, castId, key.EffectMask, this, nullptr, difficulty, info.BaseAmounts.data(), nullptr, casterGuid, itemGuid, castItemId, castItemLevel))
+ AuraCreateInfo createInfo(castId, spellInfo, difficulty, key.EffectMask, this);
+ createInfo
+ .SetCasterGUID(casterGuid)
+ .SetBaseAmount(info.BaseAmounts.data())
+ .SetCastItem(itemGuid, castItemId, castItemLevel);
+
+ if (Aura* aura = Aura::TryCreate(createInfo))
{
if (!aura->CanBeSaved())
{
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index fadd871a970..b75fc274072 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3255,44 +3255,31 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId());
}
-Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool resetPeriodicTimer /*= true*/, ObjectGuid castItemGuid /*= ObjectGuid::Empty*/, uint32 castItemId /*= 0*/, int32 castItemLevel /*= -1*/)
+Aura* Unit::_TryStackingOrRefreshingExistingAura(AuraCreateInfo& createInfo)
{
- ASSERT(!casterGUID.IsEmpty() || caster);
+ ASSERT(!createInfo.CasterGUID.IsEmpty() || 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
- if (castItem)
- {
- castItemGuid = castItem->GetGUID();
- if (Player* owner = castItem->GetOwner())
- {
- castItemId = castItem->GetEntry();
- castItemLevel = int32(castItem->GetItemLevel(owner));
- }
- else if (castItem->GetOwnerGUID() == caster->GetGUID())
- {
- castItemId = castItem->GetEntry();
- castItemLevel = int32(castItem->GetItemLevel(caster->ToPlayer()));
- }
- }
+ ObjectGuid castItemGUID = createInfo.CastItemGUID;
// 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, 0))
{
// 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
- for (SpellEffectInfo const* effect : newAura->GetEffects())
+ for (SpellEffectInfo const* effect : createInfo.GetSpellInfo()->GetEffects())
{
if (!effect)
continue;
@@ -3301,9 +3288,9 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint3
if (!eff)
continue;
- int bp;
- if (baseAmount)
- bp = *(baseAmount + effect->EffectIndex);
+ int32 bp;
+ if (createInfo.BaseAmount)
+ bp = *(createInfo.BaseAmount + effect->EffectIndex);
else
bp = effect->BasePoints;
@@ -3312,18 +3299,18 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint3
}
// correct cast item guid if needed
- if (castItemGuid != foundAura->GetCastItemGUID())
+ if (castItemGUID != foundAura->GetCastItemGUID())
{
ObjectGuid* oldGUID = const_cast<ObjectGuid*>(&foundAura->m_castItemGuid);
- *oldGUID = castItemGuid;
+ *oldGUID = castItemGUID;
uint32* oldItemId = const_cast<uint32*>(&foundAura->m_castItemId);
- *oldItemId = castItemId;
+ *oldItemId = createInfo.CastItemId;
int32* oldItemLevel = const_cast<int32*>(&foundAura->m_castItemLevel);
- *oldItemLevel = castItemLevel;
+ *oldItemLevel = createInfo.CastItemLevel;
}
// try to increase stack amount
- foundAura->ModStackAmount(1, AURA_REMOVE_BY_DEFAULT, resetPeriodicTimer);
+ foundAura->ModStackAmount(1, AURA_REMOVE_BY_DEFAULT, createInfo.ResetPeriodicTimer);
return foundAura;
}
}
@@ -3334,7 +3321,7 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint3
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);
@@ -3371,7 +3358,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, uint32 effMask)
+AuraApplication* Unit::_CreateAuraApplication(Aura* aura, uint32 effMask)
{
// can't apply aura on unit which is going to be deleted - to not create a memory leak
ASSERT(!m_cleanupDone);
@@ -3421,7 +3408,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, uint32 effMask)
+void Unit::_ApplyAura(AuraApplication* aurApp, uint32 effMask)
{
Aura* aura = aurApp->GetBase();
@@ -3464,7 +3451,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint32 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);
@@ -3552,7 +3539,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);
@@ -3621,8 +3608,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());
@@ -3952,7 +3939,12 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, U
if (aura->IsSingleTarget())
aura->UnregisterSingleTarget();
- if (Aura* newAura = Aura::TryRefreshStackOrCreate(aura->GetSpellInfo(), aura->GetCastGUID(), effMask, stealer, nullptr, aura->GetCastDifficulty(), &baseDamage[0], nullptr, aura->GetCasterGUID()))
+ AuraCreateInfo createInfo(aura->GetCastGUID(), aura->GetSpellInfo(), aura->GetCastDifficulty(), 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())
@@ -12315,12 +12307,19 @@ Aura* Unit::AddAura(SpellInfo const* spellInfo, uint32 effMask, Unit* target)
{
if (!(effMask & (1 << i)))
continue;
+
if (target->IsImmunedToSpellEffect(spellInfo, i, this))
effMask &= ~(1 << i);
}
+ if (!effMask)
+ return nullptr;
+
ObjectGuid castId = ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellInfo->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>());
- if (Aura* aura = Aura::TryRefreshStackOrCreate(spellInfo, castId, effMask, target, this, GetMap()->GetDifficultyID()))
+ AuraCreateInfo createInfo(castId, spellInfo, GetMap()->GetDifficultyID(), effMask, target);
+ createInfo.SetCaster(this);
+
+ if (Aura* aura = Aura::TryRefreshStackOrCreate(createInfo))
{
aura->ApplyForTargets();
return aura;
@@ -12769,18 +12768,25 @@ 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 (SpellEffectInfo const* effect : spellEntry->GetEffects())
if (effect)
- bp0[effect->EffectIndex] = effect->BasePoints;
+ bp[effect->EffectIndex] = effect->BasePoints;
+
+ bp[i] = seatId;
- bp0[i] = seatId;
- Aura::TryRefreshStackOrCreate(spellEntry, ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellEntry->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>()), MAX_EFFECT_MASK, this, clicker, GetMap()->GetDifficultyID(), bp0, nullptr, origCasterGUID);
+ AuraCreateInfo createInfo(ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellEntry->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>()), spellEntry, GetMap()->GetDifficultyID(), MAX_EFFECT_MASK, this);
+ createInfo
+ .SetCaster(clicker)
+ .SetBaseAmount(bp)
+ .SetCasterGUID(origCasterGUID);
+
+ Aura::TryRefreshStackOrCreate(createInfo);
}
}
else
@@ -12788,7 +12794,14 @@ void Unit::HandleSpellClick(Unit* clicker, int8 seatId /*= -1*/)
if (IsInMap(caster))
caster->CastSpell(target, spellEntry->Id, CastSpellExtraArgs().SetOriginalCaster(origCasterGUID));
else
- Aura::TryRefreshStackOrCreate(spellEntry, ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellEntry->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>()), MAX_EFFECT_MASK, this, clicker, GetMap()->GetDifficultyID(), nullptr, nullptr, origCasterGUID);
+ {
+ AuraCreateInfo createInfo(ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellEntry->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>()), spellEntry, GetMap()->GetDifficultyID(), 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 a2bb7f1a301..ff5c76a1bb5 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -762,7 +762,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::array<DiminishingReturn, DIMINISHING_MAX> Diminishing;
typedef std::vector<std::pair<uint32 /*procEffectMask*/, AuraApplication*>> AuraApplicationProcContainer;
@@ -1337,13 +1337,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, uint32 effMask, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = ObjectGuid::Empty, uint32 castItemId = 0, int32 castItemLevel = -1);
+ Aura* _TryStackingOrRefreshingExistingAura(AuraCreateInfo& createInfo);
void _AddAura(UnitAura* aura, Unit* caster);
- AuraApplication * _CreateAuraApplication(Aura* aura, uint32 effMask);
+ AuraApplication* _CreateAuraApplication(Aura* aura, uint32 effMask);
void _ApplyAuraEffect(Aura* aura, uint8 effIndex);
- void _ApplyAura(AuraApplication * aurApp, uint32 effMask);
- void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
- void _UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode);
+ void _ApplyAura(AuraApplication* aurApp, uint32 effMask);
+ void _UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMode);
+ void _UnapplyAura(AuraApplication* aurApp, AuraRemoveMode removeMode);
void _RemoveNoStackAurasDueToAura(Aura* aura);
void _RegisterAuraEffect(AuraEffect* aurEff, bool apply);
@@ -1351,7 +1351,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, uint32 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveOwnedAura(Aura* aura, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);