From 07f2087683e11065277e87cf784fe5e2ba074bf6 Mon Sep 17 00:00:00 2001 From: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Date: Wed, 7 Apr 2021 13:30:58 +0200 Subject: [PATCH] fix(Core/Spell): Handle ClearAllDebuffs (#5006) --- .../rev_1616715058536439500.sql | 5 +++ src/server/game/Entities/Unit/Unit.cpp | 26 ++++++++++++++ src/server/game/Entities/Unit/Unit.h | 14 ++++---- src/server/scripts/Spells/spell_generic.cpp | 35 +++++++++++++++++++ 4 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1616715058536439500.sql diff --git a/data/sql/updates/pending_db_world/rev_1616715058536439500.sql b/data/sql/updates/pending_db_world/rev_1616715058536439500.sql new file mode 100644 index 000000000..6a8f59309 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1616715058536439500.sql @@ -0,0 +1,5 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1616715058536439500'); + +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_gen_clear_debuffs'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(34098, 'spell_gen_clear_debuffs'); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8aae8bcb0..19ed98b0f 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -4427,6 +4427,19 @@ void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode) RemoveAura(aurApp, mode); } +void Unit::RemoveOwnedAuras(std::function const& check) +{ + for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();) + { + if (check(iter->second)) + { + RemoveOwnedAura(iter); + continue; + } + ++iter; + } +} + void Unit::RemoveAppliedAuras(std::function const& check) { for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();) @@ -4440,6 +4453,19 @@ void Unit::RemoveAppliedAuras(std::function const& } } +void Unit::RemoveOwnedAuras(uint32 spellId, std::function const& check) +{ + for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);) + { + if (check(iter->second)) + { + RemoveOwnedAura(iter); + continue; + } + ++iter; + } +} + void Unit::RemoveAppliedAuras(uint32 spellId, std::function const& check) { for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index e51727a4b..d547f2a92 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1971,6 +1971,14 @@ public: void RemoveAura(AuraApplication* aurApp, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveAura(Aura* aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); + // Convenience methods removing auras by predicate + void RemoveAppliedAuras(std::function const& check); + void RemoveOwnedAuras(std::function const& check); + + // Optimized overloads taking advantage of map key + void RemoveAppliedAuras(uint32 spellId, std::function const& check); + void RemoveOwnedAuras(uint32 spellId, std::function const& check); + void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID = 0, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); void RemoveAuraFromStack(uint32 spellId, uint64 casterGUID = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, uint64 casterGUID, Unit* dispeller, uint8 chargesRemoved = 1); @@ -1985,12 +1993,6 @@ public: void RemoveMovementImpairingAuras(bool withRoot); void RemoveAurasByShapeShift(); - // Convenience methods removing auras by predicate - void RemoveAppliedAuras(std::function const& check); - - // Optimized overloads taking advantage of map key - void RemoveAppliedAuras(uint32 spellId, std::function const& check); - void RemoveAreaAurasDueToLeaveWorld(); void RemoveAllAuras(); void RemoveArenaAuras(); diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index ac1abfde9..490bf880b 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1745,6 +1745,40 @@ public: } }; +// 34098 - ClearAllDebuffs +class spell_gen_clear_debuffs : public SpellScriptLoader +{ +public: + spell_gen_clear_debuffs() : SpellScriptLoader("spell_gen_clear_debuffs") { } + + class spell_gen_clear_debuffs_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_clear_debuffs_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Unit* target = GetHitUnit()) + { + target->RemoveOwnedAuras([](Aura const* aura) + { + SpellInfo const* spellInfo = aura->GetSpellInfo(); + return !spellInfo->IsPositive() && !spellInfo->IsPassive(); + }); + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_clear_debuffs_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_gen_clear_debuffs_SpellScript(); + } +}; + // 63845 - Create Lance enum CreateLanceSpells { @@ -5154,6 +5188,7 @@ void AddSC_generic_spell_scripts() new spell_gen_av_drekthar_presence(); new spell_gen_burn_brutallus(); new spell_gen_cannibalize(); + new spell_gen_clear_debuffs(); new spell_gen_create_lance(); new spell_gen_netherbloom(); new spell_gen_nightmare_vine();