diff options
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.h | 1 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_warlock.cpp | 103 |
3 files changed, 81 insertions, 28 deletions
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 73ff4b66406..e72227434cb 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -1944,7 +1944,6 @@ bool SpellInfo::IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInf case SPELL_SPECIFIC_CURSE: case SPELL_SPECIFIC_BANE: case SPELL_SPECIFIC_ASPECT: - case SPELL_SPECIFIC_WARLOCK_CORRUPTION: return spellSpec == spellInfo->GetSpellSpecific(); default: return false; @@ -2726,10 +2725,6 @@ void SpellInfo::_LoadSpellSpecific() // Warlock (Demon Armor | Demon Skin | Fel Armor) if (SpellFamilyFlags[1] & 0x20000020 || SpellFamilyFlags[2] & 0x00000010) return SPELL_SPECIFIC_WARLOCK_ARMOR; - - //seed of corruption and corruption - if (SpellFamilyFlags[1] & 0x10 || SpellFamilyFlags[0] & 0x2) - return SPELL_SPECIFIC_WARLOCK_CORRUPTION; break; } case SPELLFAMILY_PRIEST: diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index a1b758f28e2..faf01836171 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -126,7 +126,6 @@ enum SpellSpecificType SPELL_SPECIFIC_MAGE_ARMOR = 9, SPELL_SPECIFIC_ELEMENTAL_SHIELD = 10, SPELL_SPECIFIC_MAGE_POLYMORPH = 11, - SPELL_SPECIFIC_WARLOCK_CORRUPTION = 17, SPELL_SPECIFIC_FOOD = 19, SPELL_SPECIFIC_DRINK = 20, SPELL_SPECIFIC_FOOD_AND_DRINK = 21, diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp index 00f8a882bef..931ed38128a 100644 --- a/src/server/scripts/Spells/spell_warlock.cpp +++ b/src/server/scripts/Spells/spell_warlock.cpp @@ -23,8 +23,10 @@ #include "ScriptMgr.h" #include "AreaTrigger.h" +#include "Containers.h" #include "Creature.h" #include "GameObject.h" +#include "GridNotifiers.h" #include "ObjectAccessor.h" #include "Pet.h" #include "Player.h" @@ -36,6 +38,7 @@ enum WarlockSpells { + SPELL_WARLOCK_CORRUPTION_DAMAGE = 146739, SPELL_WARLOCK_CREATE_HEALTHSTONE = 23517, SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388, SPELL_WARLOCK_DEMONIC_CIRCLE_SUMMON = 48018, @@ -575,30 +578,77 @@ class spell_warl_seduction : public SpellScript } }; -// 27285 - Seed of Corruption +// 27285 - Seed of Corruption (damage) class spell_warl_seed_of_corruption : public SpellScript { - void FilterTargets(std::list<WorldObject*>& targets) + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_WARLOCK_CORRUPTION_DAMAGE }); + } + + void HandleHit(SpellEffIndex /*effIndex*/) const + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_WARLOCK_CORRUPTION_DAMAGE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_warl_seed_of_corruption::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } +}; + +class spell_warl_seed_of_corruption_dummy : public SpellScript +{ + void RemoveVisualMissile(WorldObject*& target) const + { + target = nullptr; + } + + void SelectTarget(std::list<WorldObject*>& targets) const { - if (GetExplTargetUnit()) - targets.remove(GetExplTargetUnit()); + if (targets.size() < 2) + return; + + if (!GetExplTargetUnit()->HasAura(GetSpellInfo()->Id, GetCaster()->GetGUID())) + { + // primary target doesn't have seed, keep it + targets.clear(); + targets.push_back(GetExplTargetUnit()); + } + else + { + // primary target has seed, select random other target with no seed + targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id, GetCaster()->GetGUID())); + if (!targets.empty()) + Trinity::Containers::RandomResize(targets, 1); + else + targets.push_back(GetExplTargetUnit()); + } } void Register() override { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY); + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_warl_seed_of_corruption_dummy::RemoveVisualMissile, EFFECT_0, TARGET_UNIT_TARGET_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption_dummy::SelectTarget, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption_dummy::SelectTarget, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY); } }; // 27243 - Seed of Corruption -class spell_warl_seed_of_corruption_dummy : public AuraScript +class spell_warl_seed_of_corruption_dummy_aura : public AuraScript { bool Validate(SpellInfo const* /*spellInfo*/) override { return ValidateSpellInfo({ SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE }); } - void CalculateBuffer(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + void OnPeriodic(AuraEffect const* aurEff) const + { + if (Unit* caster = GetCaster()) + caster->CastSpell(GetTarget(), SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE, aurEff); + } + + void CalculateBuffer(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) const { Unit* caster = GetCaster(); if (!caster) @@ -607,34 +657,43 @@ class spell_warl_seed_of_corruption_dummy : public AuraScript amount = caster->SpellBaseDamageBonusDone(GetSpellInfo()->GetSchoolMask()) * GetEffectInfo(EFFECT_0).CalcValue(caster) / 100; } - void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo) + void HandleProc(AuraEffect* aurEff, ProcEventInfo const& eventInfo) { PreventDefaultAction(); - DamageInfo* damageInfo = eventInfo.GetDamageInfo(); - if (!damageInfo || !damageInfo->GetDamage()) + + DamageInfo const* damageInfo = eventInfo.GetDamageInfo(); + if (!damageInfo) return; - int32 amount = aurEff->GetAmount() - damageInfo->GetDamage(); - if (amount > 0) + Unit* caster = GetCaster(); + if (!caster) + return; + + if (!damageInfo->GetAttacker() || damageInfo->GetAttacker() != caster) + return; + + // other seed explosions detonate this instantly, no matter what damage amount is + if (!damageInfo->GetSpellInfo() || damageInfo->GetSpellInfo()->Id != SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE) { - const_cast<AuraEffect*>(aurEff)->SetAmount(amount); - if (!GetTarget()->HealthBelowPctDamaged(1, damageInfo->GetDamage())) - return; + int32 amount = aurEff->GetAmount() - damageInfo->GetDamage(); + if (amount > 0) + { + aurEff->SetAmount(amount); + if (!GetTarget()->HealthBelowPctDamaged(1, damageInfo->GetDamage())) + return; + } } Remove(); - Unit* caster = GetCaster(); - if (!caster) - return; - caster->CastSpell(eventInfo.GetActionTarget(), SPELL_WARLOCK_SEED_OF_CORRUPTION_DAMAGE, aurEff); } void Register() override { - DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_seed_of_corruption_dummy::CalculateBuffer, EFFECT_2, SPELL_AURA_DUMMY); - OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_dummy::HandleProc, EFFECT_2, SPELL_AURA_DUMMY); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_warl_seed_of_corruption_dummy_aura::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_seed_of_corruption_dummy_aura::CalculateBuffer, EFFECT_2, SPELL_AURA_DUMMY); + OnEffectProc += AuraEffectProcFn(spell_warl_seed_of_corruption_dummy_aura::HandleProc, EFFECT_2, SPELL_AURA_DUMMY); } }; @@ -1049,7 +1108,7 @@ void AddSC_warlock_spell_scripts() RegisterSpellScript(spell_warl_sayaad_precast_disorientation); RegisterSpellScript(spell_warl_seduction); RegisterSpellScript(spell_warl_seed_of_corruption); - RegisterSpellScript(spell_warl_seed_of_corruption_dummy); + RegisterSpellAndAuraScriptPair(spell_warl_seed_of_corruption_dummy, spell_warl_seed_of_corruption_dummy_aura); RegisterSpellScript(spell_warl_seed_of_corruption_generic); RegisterSpellScript(spell_warl_shadow_bolt); RegisterSpellScript(spell_warl_soul_swap); |