diff options
| author | ariel- <ariel-@users.noreply.github.com> | 2018-01-27 03:45:40 -0300 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2021-08-28 15:59:11 +0200 |
| commit | f3548d45d0a74203ef6f5c7282c31ba794ddf7a1 (patch) | |
| tree | 94a7c69af30d4b13018457cf40c06366ebc11ba9 /src/server/game/Entities | |
| parent | 52ae3c89d1d4dbcff309d940fd41c7212edc77b7 (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.cpp | 7 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 103 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 14 |
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); |
