diff options
-rw-r--r-- | sql/updates/world/2013_07_24_04_world_spell_script_names_434.sql | 6 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_warlock.cpp | 212 |
2 files changed, 218 insertions, 0 deletions
diff --git a/sql/updates/world/2013_07_24_04_world_spell_script_names_434.sql b/sql/updates/world/2013_07_24_04_world_spell_script_names_434.sql new file mode 100644 index 00000000000..3d23063a240 --- /dev/null +++ b/sql/updates/world/2013_07_24_04_world_spell_script_names_434.sql @@ -0,0 +1,6 @@ +DELETE FROM spell_script_names WHERE ScriptName LIKE "spell_warlock_soul_swap%"; +INSERT INTO spell_script_names (spell_id, ScriptName) VALUES +(86121, "spell_warlock_soul_swap"), +(86211, "spell_warlock_soul_swap_override"), +(92795, "spell_warlock_soul_swap_dot_marker"), +(86213, "spell_warlock_soul_swap_exhale"); diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 8cab9e8d56c..c459ce07630 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -49,6 +49,7 @@ enum WarlockSpells SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181, SPELL_WARLOCK_GLYPH_OF_SHADOWFLAME = 63311, SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106, + SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP = 56226, SPELL_WARLOCK_GLYPH_OF_SUCCUBUS = 56250, SPELL_WARLOCK_HAUNT = 48181, SPELL_WARLOCK_HAUNT_HEAL = 48210, @@ -68,6 +69,10 @@ enum WarlockSpells SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106, SPELL_WARLOCK_SHADOW_WARD = 6229, SPELL_WARLOCK_SOULSHATTER = 32835, + SPELL_WARLOCK_SOUL_SWAP_CD_MARKER = 94229, + SPELL_WARLOCK_SOUL_SWAP_OVERRIDE = 86211, + SPELL_WARLOCK_SOUL_SWAP_MOD_COST = 92794, + SPELL_WARLOCK_SOUL_SWAP_DOT_MARKER = 92795, SPELL_WARLOCK_UNSTABLE_AFFLICTION = 30108, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117 }; @@ -1171,6 +1176,209 @@ class spell_warl_soul_leech : public SpellScriptLoader } }; +// 86121 - Soul Swap +class spell_warl_soul_swap : public SpellScriptLoader +{ +public: + spell_warl_soul_swap() : SpellScriptLoader("spell_warl_soul_swap") { } + + class spell_warl_soul_swap_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_soul_swap_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP) + || !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_CD_MARKER) + || !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + return false; + return true; + } + + void HandleHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_OVERRIDE, true); + GetHitUnit()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_DOT_MARKER, true); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_warl_soul_swap_SpellScript(); + } +}; + +// 86211 - Soul Swap Override - Also acts as a dot container +class spell_warl_soul_swap_override : public SpellScriptLoader +{ +public: + spell_warl_soul_swap_override() : SpellScriptLoader("spell_warl_soul_swap_override") { } + + class spell_warl_soul_swap_override_AuraScript : public AuraScript + { + PrepareAuraScript(spell_warl_soul_swap_override_AuraScript); + + bool Load() OVERRIDE + { + swapCaster = NULL; + return true; + } + + //! Forced to, pure virtual functions must have a body when linking + void Register() OVERRIDE { } + + public: + void AddDot(uint32 id) { dotList.push_back(id); } + std::list<uint32> const GetDotList() const { return dotList; } + Unit* GetOriginalSwapSource() const { return swapCaster; } + void SetOriginalSwapSource(Unit* victim) { swapCaster = victim; } + + private: + std::list<uint32> dotList; + Unit* swapCaster; + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_warl_soul_swap_override_AuraScript(); + } +}; + +typedef spell_warl_soul_swap_override::spell_warl_soul_swap_override_AuraScript SoulSwapOverrideAuraScript; + +//! Soul Swap Copy Spells - 92795 - Simply copies spell IDs. +class spell_warl_soul_swap_dot_marker : public SpellScriptLoader +{ +public: + spell_warl_soul_swap_dot_marker() : SpellScriptLoader("spell_warl_soul_swap_dot_marker") { } + + class spell_warl_soul_swap_dot_marker_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_soul_swap_dot_marker_SpellScript); + + void HandleHit(SpellEffIndex effIndex) + { + Unit* swapVictim = GetCaster(); + Unit* warlock = GetHitUnit(); + if (!warlock || !swapVictim) + return; + + flag96 classMask = GetSpellInfo()->Effects[effIndex].SpellClassMask; + + Unit::AuraApplicationMap const& appliedAuras = swapVictim->GetAppliedAuras(); + SoulSwapOverrideAuraScript* swapSpellScript = NULL; + if (Aura* swapOverrideAura = warlock->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + swapSpellScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverrideAura->GetScriptByName("spell_warlock_soul_swap_override")); + + if (swapSpellScript == NULL) + return; + + for (Unit::AuraApplicationMap::const_iterator itr = appliedAuras.begin(); itr != appliedAuras.end(); ++itr) + { + SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo(); + if (itr->second->GetBase()->GetCaster() == warlock) + if (spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellProto->SpellFamilyFlags & classMask)) + swapSpellScript->AddDot(itr->first); + } + + swapSpellScript->SetOriginalSwapSource(swapVictim); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_dot_marker_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_warl_soul_swap_dot_marker_SpellScript(); + } +}; + +// 86213 - Soul Swap Exhale +class spell_warl_soul_swap_exhale : public SpellScriptLoader +{ +public: + spell_warl_soul_swap_exhale() : SpellScriptLoader("spell_warl_soul_swap_exhale") { } + + class spell_warl_soul_swap_exhale_SpellScript : public SpellScript + { + PrepareSpellScript(spell_warl_soul_swap_exhale_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_MOD_COST) || !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + return false; + return true; + } + + SpellCastResult CheckCast() + { + Unit* currentTarget = GetExplTargetUnit(); + Unit* swapTarget = NULL; + if (Aura const* swapOverride = GetCaster()->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + if (SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName("spell_warlock_soul_swap_override"))) + swapTarget = swapScript->GetOriginalSwapSource(); + + // Soul Swap Exhale can't be cast on the same target than Soul Swap + if (swapTarget && currentTarget && swapTarget == currentTarget) + return SPELL_FAILED_BAD_TARGETS; + + return SPELL_CAST_OK; + } + + void OnEffectHit(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_MOD_COST, true); + bool hasGlyph = GetCaster()->HasAura(SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP); + + std::list<uint32> dotList; + Unit* swapSource = NULL; + if (Aura const* swapOverride = GetCaster()->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE)) + { + SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName("spell_warlock_soul_swap_override")); + if (!swapScript) + return; + dotList = swapScript->GetDotList(); + swapSource = swapScript->GetOriginalSwapSource(); + } + + if (dotList.empty()) + return; + + for (std::list<uint32>::const_iterator itr = dotList.begin(); itr != dotList.end(); ++itr) + { + GetCaster()->AddAura(*itr, GetHitUnit()); + if (!hasGlyph && swapSource) + swapSource->RemoveAurasDueToSpell(*itr); + } + + // Remove Soul Swap Exhale buff + GetCaster()->RemoveAurasDueToSpell(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE); + + if (hasGlyph) // Add a cooldown on Soul Swap if caster has the glyph + GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_CD_MARKER, false); + } + + void Register() OVERRIDE + { + OnCheckCast += SpellCheckCastFn(spell_warl_soul_swap_exhale_SpellScript::CheckCast); + OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_exhale_SpellScript::OnEffectHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_warl_soul_swap_exhale_SpellScript(); + } +}; + // 29858 - Soulshatter /// Updated 4.3.4 class spell_warl_soulshatter : public SpellScriptLoader @@ -1277,6 +1485,10 @@ void AddSC_warlock_spell_scripts() new spell_warl_shadow_trance_proc(); new spell_warl_shadow_ward(); new spell_warl_soul_leech(); + new spell_warl_soul_swap(); + new spell_warl_soul_swap_dot_marker(); + new spell_warl_soul_swap_exhale(); + new spell_warl_soul_swap_override(); new spell_warl_soulshatter(); new spell_warl_unstable_affliction(); } |