From e8d5aa56cc48572d81e1898b7b4ff10cfa6d1957 Mon Sep 17 00:00:00 2001 From: ariel- Date: Sat, 27 Jan 2018 03:45:40 -0300 Subject: Core/Spells: rework part 3: spells only handle at most one UnitAura and one DynObjAura during its lifetime Closes #15088 --- src/server/game/Spells/Spell.cpp | 68 +++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 26 deletions(-) (limited to 'src/server/game/Spells/Spell.cpp') diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a92024361c8..799818fd81f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -609,7 +609,8 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO m_glyphIndex = 0; m_preCastSpell = 0; m_triggeredByAuraSpell = nullptr; - m_spellAura = nullptr; + _spellAura = nullptr; + _dynObjAura = nullptr; //Auto Shot & Shoot (wand) m_autoRepeat = m_spellInfo->IsAutoRepeatRangedSpell(); @@ -2315,9 +2316,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) uint32 procVictim = m_procVictim; uint32 hitMask = PROC_HIT_NONE; - m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied - - // Spells with this flag cannot trigger if effect is cast on self + // Spells with this flag cannot trigger if effect is cast on self bool const canEffectTrigger = !m_spellInfo->HasAttribute(SPELL_ATTR3_CANT_TRIGGER_PROC) && unitTarget->CanProc() && (CanExecuteTriggersOnHit(mask) || missInfo == SPELL_MISS_IMMUNE || missInfo == SPELL_MISS_IMMUNE2); Unit* spellHitTarget = nullptr; @@ -2604,14 +2603,11 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA } } - uint8 aura_effmask = 0; - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect()) - aura_effmask |= 1 << i; + uint8 aura_effmask = Aura::BuildEffectMaskForOwner(m_spellInfo, effectMask, unit); // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add - bool const triggered = m_triggeredByAuraSpell != nullptr; - DiminishingGroup const diminishGroup = m_spellInfo->GetDiminishingReturnsGroupForSpell(triggered); + bool triggered = (m_triggeredByAuraSpell != nullptr); + DiminishingGroup diminishGroup = m_spellInfo->GetDiminishingReturnsGroupForSpell(triggered); DiminishingLevels diminishLevel = DIMINISHING_LEVEL_1; if (diminishGroup && aura_effmask) @@ -2628,7 +2624,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA // Select rank for aura with level requirements only in specific cases // Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target SpellInfo const* aurSpellInfo = m_spellInfo; - int32 basePoints[MAX_SPELL_EFFECTS]; + int32 basePoints[MAX_SPELL_EFFECTS] = { }; if (scaleAura) { aurSpellInfo = m_spellInfo->GetAuraRankForLevel(unitTarget->getLevel()); @@ -2647,18 +2643,39 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA if (m_originalCaster) { bool refresh = false; - bool const resetPeriodicTimer = !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER); - m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, - m_originalCaster, (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, resetPeriodicTimer); - if (m_spellAura) + + if (!_spellAura) + { + bool const resetPeriodicTimer = !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER); + uint8 const allAuraEffectMask = Aura::BuildEffectMaskForOwner(aurSpellInfo, MAX_EFFECT_MASK, unit); + int32 const* bp = basePoints; + if (aurSpellInfo == m_spellInfo) + bp = m_spellValue->EffectBasePoints; + + AuraCreateInfo createInfo(aurSpellInfo, allAuraEffectMask, unit); + createInfo + .SetCaster(m_originalCaster) + .SetBaseAmount(bp) + .SetCastItem(m_CastItem) + .SetPeriodicReset(resetPeriodicTimer) + .SetOwnerEffectMask(aura_effmask) + .IsRefresh = &refresh; + + if (Aura* aura = Aura::TryRefreshStackOrCreate(createInfo)) + _spellAura = aura->ToUnitAura(); + } + else + _spellAura->AddStaticApplication(unit, aura_effmask); + + if (_spellAura) { // Set aura stack amount to desired value if (m_spellValue->AuraStackAmount > 1) { if (!refresh) - m_spellAura->SetStackAmount(m_spellValue->AuraStackAmount); + _spellAura->SetStackAmount(m_spellValue->AuraStackAmount); else - m_spellAura->ModStackAmount(m_spellValue->AuraStackAmount); + _spellAura->ModStackAmount(m_spellValue->AuraStackAmount); } // Now Reduce spell duration using data received at spell hit @@ -2677,12 +2694,14 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA } } - int32 duration = m_spellAura->GetMaxDuration(); + int32 duration = _spellAura->GetMaxDuration(); // unit is immune to aura if it was diminished to 0 duration if (!positive && !unit->ApplyDiminishingToDuration(aurSpellInfo, triggered, duration, m_originalCaster, diminishLevel)) { - m_spellAura->Remove(); + _spellAura->Remove(); + _spellAura = nullptr; + bool found = false; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA) @@ -2692,7 +2711,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA } else { - static_cast(m_spellAura)->SetDiminishGroup(diminishGroup); + _spellAura->SetDiminishGroup(diminishGroup); duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask); @@ -2703,12 +2722,11 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA else if (m_originalCaster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, aurSpellInfo) || m_spellInfo->HasAttribute(SPELL_ATTR5_HASTE_AFFECT_DURATION)) duration = int32(duration * m_originalCaster->GetFloatValue(UNIT_MOD_CAST_SPEED)); - if (duration != m_spellAura->GetMaxDuration()) + if (duration != _spellAura->GetMaxDuration()) { - m_spellAura->SetMaxDuration(duration); - m_spellAura->SetDuration(duration); + _spellAura->SetMaxDuration(duration); + _spellAura->SetDuration(duration); } - m_spellAura->_RegisterForTargets(); } } } @@ -3536,8 +3554,6 @@ uint64 Spell::handle_delayed(uint64 t_offset) void Spell::_handle_immediate_phase() { - m_spellAura = nullptr; - // handle some immediate features of the spell here HandleThreatSpells(); -- cgit v1.2.3