From 81e5943bd0947c9e61adc1ab8abb2e25fa8705e0 Mon Sep 17 00:00:00 2001 From: PolarCookie Date: Sat, 3 Sep 2022 11:31:56 +0200 Subject: [PATCH] Core/Spell: SpellAura Redux (#22794) * typo and correction * spell aura no longer shared between targets _spellAura isolated * SPELL_AURA_CONTROL_VEHICLE is not strictly single target spell Steam Tank Control and Wyrmrest Commander units can reseat themselves again * Rename 9999_99_99_99_world.sql to 2019_03_08_00_world.sql --- .../world/4.3.4/2022_09_03_00_world.sql | 4 +++ src/server/game/Spells/Auras/SpellAuras.cpp | 3 --- src/server/game/Spells/Spell.cpp | 25 ++++++++++--------- src/server/game/Spells/SpellScript.h | 2 +- src/server/scripts/Spells/spell_generic.cpp | 19 ++++++++++++++ 5 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 sql/updates/world/4.3.4/2022_09_03_00_world.sql diff --git a/sql/updates/world/4.3.4/2022_09_03_00_world.sql b/sql/updates/world/4.3.4/2022_09_03_00_world.sql new file mode 100644 index 0000000000..1cf16d8a63 --- /dev/null +++ b/sql/updates/world/4.3.4/2022_09_03_00_world.sql @@ -0,0 +1,4 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_gen_vehicle_control_link' AND `spell_id` IN (49078, 50343); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(49078, 'spell_gen_vehicle_control_link'), +(50343, 'spell_gen_vehicle_control_link'); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index b7ac87db55..f9b61aab92 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1205,9 +1205,6 @@ bool Aura::IsLimitedTargetWith(Aura const* aura) const break; } - if (HasEffectType(SPELL_AURA_CONTROL_VEHICLE) && aura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE)) - return true; - return false; } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index e82a4b52ea..372c851690 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2759,7 +2759,9 @@ void Spell::TargetInfo::DoDamageAndTriggers(Spell* spell) spell->m_caster->ToPlayer()->UpdatePvP(true); } + spell->_spellAura = HitAura; spell->CallScriptAfterHitHandlers(); + spell->_spellAura = nullptr; } void Spell::GOTargetInfo::DoTargetSpellHit(Spell* spell, uint8 effIndex) @@ -2958,8 +2960,7 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo) { bool refresh = false; - // delayed spells with multiple targets need to create a new aura object, otherwise we'll access a deleted aura - if (!_spellAura || (m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())) + if (!hitInfo.HitAura) { uint8 const allAuraEffectMask = Aura::BuildEffectMaskForOwner(hitInfo.AuraSpellInfo, MAX_EFFECT_MASK, unit); int32 const* bp = hitInfo.AuraBasePoints; @@ -2976,18 +2977,18 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo) if (Aura* aura = Aura::TryRefreshStackOrCreate(createInfo)) { - _spellAura = aura->ToUnitAura(); + hitInfo.HitAura = aura->ToUnitAura(); // Set aura stack amount to desired value if (m_spellValue->AuraStackAmount > 1) { if (!refresh) - _spellAura->SetStackAmount(m_spellValue->AuraStackAmount); + hitInfo.HitAura->SetStackAmount(m_spellValue->AuraStackAmount); else - _spellAura->ModStackAmount(m_spellValue->AuraStackAmount); + hitInfo.HitAura->ModStackAmount(m_spellValue->AuraStackAmount); } - _spellAura->SetDiminishGroup(hitInfo.DRGroup); + hitInfo.HitAura->SetDiminishGroup(hitInfo.DRGroup); hitInfo.AuraDuration = caster->ModSpellDuration(hitInfo.AuraSpellInfo, unit, hitInfo.AuraDuration, hitInfo.Positive, _spellAura->GetEffectMask()); @@ -2998,10 +2999,10 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo) else if (m_originalCaster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, hitInfo.AuraSpellInfo) || m_spellInfo->HasAttribute(SPELL_ATTR8_HASTE_AFFECTS_DURATION)) hitInfo.AuraDuration = int32(hitInfo.AuraDuration * m_originalCaster->GetFloatValue(UNIT_MOD_CAST_SPEED)); - if (hitInfo.AuraDuration != _spellAura->GetMaxDuration()) + if (hitInfo.AuraDuration != hitInfo.HitAura->GetMaxDuration()) { - _spellAura->SetMaxDuration(hitInfo.AuraDuration); - _spellAura->SetDuration(hitInfo.AuraDuration); + hitInfo.HitAura->SetMaxDuration(hitInfo.AuraDuration); + hitInfo.HitAura->SetDuration(hitInfo.AuraDuration); } if (DynamicObject* dynObj = m_originalCaster->GetDynObject(m_spellInfo->Id)) @@ -3020,13 +3021,13 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo) } } else - _spellAura->AddStaticApplication(unit, aura_effmask); - - hitInfo.HitAura = _spellAura; + hitInfo.HitAura->AddStaticApplication(unit, aura_effmask); } } + _spellAura = hitInfo.HitAura; HandleEffects(unit, nullptr, nullptr, nullptr, effIndex, SPELL_EFFECT_HANDLE_HIT_TARGET); + _spellAura = nullptr; } void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask) diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index a2b0d34545..ad846ca67e 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -930,7 +930,7 @@ class TC_GAME_API AuraScript : public _SpellScript AuraEffectApplyHookHandler::HookList AfterEffectApply; // executed after aura effect is removed with specified mode from target - // should be used when when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe + // should be used when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe // example: OnEffectRemove.Register(this, &class::function, EffectIndexSpecifier, EffectAuraNameSpecifier); // example: OnEffectRemove.Register(this, &class::function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes); // where function is: void function (AuraEffect const* aurEff, AuraEffectHandleModes mode); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 7ffd658edd..8d0d752031 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -5470,6 +5470,24 @@ class spell_gen_shadowmeld : public AuraScript } }; +enum SiegeTankControl +{ + SPELL_SIEGE_TANK_CONTROL = 47963 +}; + +class spell_gen_vehicle_control_link : public AuraScript +{ + void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_SIEGE_TANK_CONTROL); //aurEff->GetAmount() + } + + void Register() override + { + AfterEffectRemove.Register(&spell_gen_vehicle_control_link::OnRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -5607,4 +5625,5 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_rocket_barrage); RegisterSpellScript(spell_gen_face_rage); RegisterSpellScript(spell_gen_shadowmeld); + RegisterSpellScript(spell_gen_vehicle_control_link); }