diff options
| author | ariel- <ariel-@users.noreply.github.com> | 2018-01-27 03:45:40 -0300 |
|---|---|---|
| committer | Ariel Silva <ariel-@users.noreply.github.com> | 2018-03-09 14:41:28 -0300 |
| commit | e8d5aa56cc48572d81e1898b7b4ff10cfa6d1957 (patch) | |
| tree | b21b5dff1cdb693074e23eb57906f6a2a2182a76 /src/server/game/Entities/Unit | |
| parent | 9b38a6352c0fe2499de54fd769aa1c721a410bda (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.cpp | 84 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 14 |
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); |
