diff --git a/data/sql/updates/pending_db_world/rev_1615287196510790727.sql b/data/sql/updates/pending_db_world/rev_1615287196510790727.sql new file mode 100644 index 000000000..c88dabb69 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1615287196510790727.sql @@ -0,0 +1,8 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1615287196510790727'); + +-- Delete spell_linked_spell for Shadowmeld +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (58984); + +-- Fix Shadowmeld +DELETE FROM `spell_script_names` WHERE `ScriptName` = 'spell_gen_shadowmeld'; +INSERT INTO `spell_script_names` VALUES (58984, 'spell_gen_shadowmeld'); \ No newline at end of file diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index e3ee4347f..4ff610c1c 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -5041,6 +5041,63 @@ public: } }; +class spell_gen_shadowmeld : public SpellScriptLoader +{ +public: + spell_gen_shadowmeld() : SpellScriptLoader("spell_gen_shadowmeld") {} + + class spell_gen_shadowmeld_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_shadowmeld_SpellScript); + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + caster->InterruptSpell(CURRENT_AUTOREPEAT_SPELL); // break Auto Shot and autohit + caster->InterruptSpell(CURRENT_CHANNELED_SPELL); // break channeled spells + + bool instant_exit = true; + if (Player* pCaster = caster->ToPlayer()) // if is a creature instant exits combat, else check if someone in party is in combat in visibility distance + { + uint64 myGUID = pCaster->GetGUID(); + float visibilityRange = pCaster->GetMap()->GetVisibilityRange(); + if (Group* pGroup = pCaster->GetGroup()) + { + const Group::MemberSlotList membersList = pGroup->GetMemberSlots(); + for (Group::member_citerator itr = membersList.begin(); itr != membersList.end() && instant_exit; ++itr) + if (itr->guid != myGUID) + if (Player* GroupMember = ObjectAccessor::GetPlayer(*pCaster, itr->guid)) + if (GroupMember->IsInCombat() && pCaster->GetMap() == GroupMember->GetMap() && pCaster->IsWithinDistInMap(GroupMember, visibilityRange)) + instant_exit = false; + } + + pCaster->SendAttackSwingCancelAttack(); + } + + if (!caster->GetInstanceScript() || !caster->GetInstanceScript()->IsEncounterInProgress()) //Don't leave combat if you are in combat with a boss + { + if (!instant_exit) { + caster->getHostileRefManager().deleteReferences(); // exit combat after 6 seconds + } + else caster->CombatStop(); // isn't necessary to call AttackStop because is just called in CombatStop + } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gen_shadowmeld_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_gen_shadowmeld_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { // ours: @@ -5170,4 +5227,5 @@ void AddSC_generic_spell_scripts() new spell_gen_eject_all_passengers(); new spell_gen_eject_passenger(); new spell_gen_charmed_unit_spell_cooldown(); + new spell_gen_shadowmeld(); }