diff options
| author | QAston <qaston@gmail.com> | 2010-12-30 02:03:46 +0100 |
|---|---|---|
| committer | QAston <qaston@gmail.com> | 2010-12-30 02:03:46 +0100 |
| commit | c8adcc95f9046235e6ce6ceac98324b406cbebf9 (patch) | |
| tree | 63eaf2e02409c055f9c53dd6d55c7edc6d9e2376 /src/server/scripts | |
| parent | 51b46987c3d5bc14f67ea6370e759f6b0bfd61c3 (diff) | |
Core/Unit: Move spell specific code from Unit::CalcAbsorbResist to AuraScripts.
Diffstat (limited to 'src/server/scripts')
| -rw-r--r-- | src/server/scripts/Examples/example_spell.cpp | 14 | ||||
| -rw-r--r-- | src/server/scripts/Outland/BlackTemple/illidari_council.cpp | 33 | ||||
| -rw-r--r-- | src/server/scripts/PrecompiledHeaders/ScriptPCH.h | 1 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_dk.cpp | 239 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_druid.cpp | 29 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_generic.cpp | 36 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_mage.cpp | 95 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_paladin.cpp | 77 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_priest.cpp | 110 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_rogue.cpp | 79 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_shaman.cpp | 8 |
11 files changed, 680 insertions, 41 deletions
diff --git a/src/server/scripts/Examples/example_spell.cpp b/src/server/scripts/Examples/example_spell.cpp index 8d44cb92a4d..2a9d9a605c4 100644 --- a/src/server/scripts/Examples/example_spell.cpp +++ b/src/server/scripts/Examples/example_spell.cpp @@ -285,14 +285,6 @@ class spell_ex_absorb_aura : public SpellScriptLoader SPELL_TRIGGERED = 18282 }; - bool Validate(SpellEntry const * /*spellEntry*/) - { - // check if spellid exists in dbc, we will trigger it later - if (!sSpellStore.LookupEntry(SPELL_TRIGGERED)) - return false; - return true; - } - void HandleOnEffectAbsorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) { sLog->outString("Our aura is now absorbing damage done to us!"); @@ -300,6 +292,11 @@ class spell_ex_absorb_aura : public SpellScriptLoader absorbAmount = dmgInfo.GetDamage(); } + void HandleAfterEffectAbsorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + sLog->outString("Our aura has absorbed %u damage!", absorbAmount); + } + /*void HandleAfterAbsorb(DamageInfo & dmgInfo) { sLog->outString("Our auras have just absorbed damage done to us!"); @@ -309,6 +306,7 @@ class spell_ex_absorb_aura : public SpellScriptLoader void Register() { OnEffectAbsorb += AuraEffectAbsorbFn(spell_ex_absorb_auraAuraScript::HandleOnEffectAbsorb, EFFECT_0); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_ex_absorb_auraAuraScript::HandleAfterEffectAbsorb, EFFECT_0); //AfterAbsorb += AuraAbsorbFn(spell_ex_absorb_auraAuraScript::HandleAfterAbsorb); } }; diff --git a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp index efcc8285984..9dc832d3056 100644 --- a/src/server/scripts/Outland/BlackTemple/illidari_council.cpp +++ b/src/server/scripts/Outland/BlackTemple/illidari_council.cpp @@ -89,6 +89,7 @@ static CouncilYells CouncilEnrage[]= #define SPELL_EMPOWERED_SMITE 41471 #define SPELL_CIRCLE_OF_HEALING 41455 #define SPELL_REFLECTIVE_SHIELD 41475 +#define SPELL_REFLECTIVE_SHIELD_T 33619 #define SPELL_DIVINE_WRATH 41472 #define SPELL_HEAL_VISUAL 24171 @@ -878,14 +879,43 @@ public: } } }; - }; +// SPELL_REFLECTIVE_SHIELD +class spell_boss_lady_malande_shield : public SpellScriptLoader +{ +public: + spell_boss_lady_malande_shield() : SpellScriptLoader("spell_boss_lady_malande_shield") { } + class spell_boss_lady_malande_shield_AuraScript : public AuraScript + { + PrepareAuraScript(spell_boss_lady_malande_shield_AuraScript); + bool Validate(SpellEntry const * /*spellEntry*/) + { + return sSpellStore.LookupEntry(SPELL_REFLECTIVE_SHIELD_T); + } + void Trigger(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + Unit * target = GetTarget(); + if (dmgInfo.GetAttacker() == target) + return; + int32 bp = absorbAmount / 2; + target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_REFLECTIVE_SHIELD_T, &bp, NULL, NULL, true, NULL, aurEff); + } + void Register() + { + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_boss_lady_malande_shield_AuraScript::Trigger, EFFECT_0); + } + }; + AuraScript *GetAuraScript() const + { + return new spell_boss_lady_malande_shield_AuraScript(); + } +}; void AddSC_boss_illidari_council() { @@ -895,4 +925,5 @@ void AddSC_boss_illidari_council() new boss_lady_malande(); new boss_veras_darkshadow(); new boss_high_nethermancer_zerevor(); + new spell_boss_lady_malande_shield(); } diff --git a/src/server/scripts/PrecompiledHeaders/ScriptPCH.h b/src/server/scripts/PrecompiledHeaders/ScriptPCH.h index 2cba3171202..1cd25309055 100644 --- a/src/server/scripts/PrecompiledHeaders/ScriptPCH.h +++ b/src/server/scripts/PrecompiledHeaders/ScriptPCH.h @@ -23,6 +23,7 @@ #include "DBCStores.h" #include "ObjectMgr.h" #include "SpellScript.h" +#include "SpellAuraEffects.h" #ifdef _WIN32 #include <windows.h> diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 706853db0ae..35656dd9af4 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -32,6 +32,165 @@ enum DeathKnightSpells DK_SPELL_SCOURGE_STRIKE_TRIGGERED = 70890, }; +// 50462 - Anti-Magic Shell (on raid member) +class spell_dk_anti_magic_shell_raid : public SpellScriptLoader +{ +public: + spell_dk_anti_magic_shell_raid() : SpellScriptLoader("spell_dk_anti_magic_shell_raid") { } + + class spell_dk_anti_magic_shell_raid_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_anti_magic_shell_raid_AuraScript); + + uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + return true; + } + + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + // TODO: this should absorb limited amount of damage, but no info on calculation formula + amount = -1; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_anti_magic_shell_raid_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_raid_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_dk_anti_magic_shell_raid_AuraScript(); + } +}; + +// 48707 - Anti-Magic Shell (on self) +class spell_dk_anti_magic_shell_self : public SpellScriptLoader +{ +public: + spell_dk_anti_magic_shell_self() : SpellScriptLoader("spell_dk_anti_magic_shell_self") { } + + class spell_dk_anti_magic_shell_self_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_anti_magic_shell_self_AuraScript); + + enum Spells + { + DK_SPELL_RUNIC_POWER_ENERGIZE = 49088, + }; + + uint32 absorbPct, hpPct; + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + hpPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_1, GetCaster()); + return true; + } + + bool Validate(SpellEntry const * /*spellEntry*/) + { + return sSpellStore.LookupEntry(DK_SPELL_RUNIC_POWER_ENERGIZE); + } + + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + absorbAmount = std::min(CalculatePctN(dmgInfo.GetDamage(), absorbPct), GetTarget()->CountPctFromMaxHealth(hpPct)); + } + + void Trigger(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + Unit * target = GetTarget(); + // damage absorbed by Anti-Magic Shell energizes the DK with additional runic power. + // This, if I'm not mistaken, shows that we get back ~20% of the absorbed damage as runic power. + int32 bp = absorbAmount * 2 / 10; + target->CastCustomSpell(target, DK_SPELL_RUNIC_POWER_ENERGIZE, &bp, NULL, NULL, true, NULL, aurEff); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_anti_magic_shell_self_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_self_AuraScript::Absorb, EFFECT_0); + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_shell_self_AuraScript::Trigger, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_dk_anti_magic_shell_self_AuraScript(); + } +}; + +// 50461 - Anti-Magic Zone +class spell_dk_anti_magic_zone : public SpellScriptLoader +{ +public: + spell_dk_anti_magic_zone() : SpellScriptLoader("spell_dk_anti_magic_zone") { } + + class spell_dk_anti_magic_zone_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_anti_magic_zone_AuraScript); + + enum Spells + { + DK_SPELL_ANTI_MAGIC_SHELL_TALENT = 51052, + }; + + uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + return true; + } + + bool Validate(SpellEntry const * /*spellEntry*/) + { + return sSpellStore.LookupEntry(DK_SPELL_ANTI_MAGIC_SHELL_TALENT); + } + + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + SpellEntry const * talentSpell = sSpellStore.LookupEntry(DK_SPELL_ANTI_MAGIC_SHELL_TALENT); + amount = SpellMgr::CalculateSpellEffectAmount(talentSpell, EFFECT_0, GetCaster()); + // assume caster is a player here + if (Unit * caster = GetCaster()) + amount += 2 * caster->ToPlayer()->GetTotalAttackPowerValue(BASE_ATTACK); + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_anti_magic_zone_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_anti_magic_zone_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_dk_anti_magic_zone_AuraScript(); + } +}; + // 49158 Corpse Explosion (51325, 51326, 51327, 51328) class spell_dk_corpse_explosion : public SpellScriptLoader { @@ -168,9 +327,15 @@ public: PrepareAuraScript(spell_dk_spell_deflection_AuraScript); uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + return true; + } + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) { - absorbPct = amount; // Set absorbtion amount to unlimited amount = -1; } @@ -195,11 +360,83 @@ public: } }; +// 52284 - Will of the Necropolis +class spell_dk_will_of_the_necropolis : public SpellScriptLoader +{ +public: + spell_dk_will_of_the_necropolis() : SpellScriptLoader("spell_dk_will_of_the_necropolis") { } + + class spell_dk_will_of_the_necropolis_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dk_will_of_the_necropolis_AuraScript); + + enum Spells + { + DK_SPELL_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189, + DK_SPELL_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284, + }; + bool Validate(SpellEntry const *spellEntry) + { + // can't use other spell than will of the necropolis due to spell_ranks dependency + if (sSpellMgr->GetFirstSpellInChain(DK_SPELL_WILL_OF_THE_NECROPOLIS_AURA_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id)) + return false; + + uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id); + if (!sSpellMgr->GetSpellWithRank(DK_SPELL_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank, true)) + return false; + + return true; + } + + uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + return true; + } + + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + // min pct of hp is stored in effect 0 of talent spell + uint32 rank = sSpellMgr->GetSpellRank(GetSpellProto()->Id); + SpellEntry const * talentProto = sSpellStore.LookupEntry(sSpellMgr->GetSpellWithRank(DK_SPELL_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank)); + + int32 remainingHp = int32(GetTarget()->GetHealth() - dmgInfo.GetDamage()); + int32 minHp = int32(GetTarget()->CountPctFromMaxHealth(SpellMgr::CalculateSpellEffectAmount(talentProto, EFFECT_0, GetCaster()))); + + // Damage that would take you below [effect0] health or taken while you are at [effect0] + if (remainingHp < minHp) + absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_will_of_the_necropolis_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_will_of_the_necropolis_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_dk_will_of_the_necropolis_AuraScript(); + } +}; void AddSC_deathknight_spell_scripts() { + new spell_dk_anti_magic_shell_raid(); + new spell_dk_anti_magic_shell_self(); + new spell_dk_anti_magic_zone(); new spell_dk_corpse_explosion(); new spell_dk_runic_power_feed(); new spell_dk_scourge_strike(); new spell_dk_spell_deflection(); + new spell_dk_will_of_the_necropolis(); } diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 47e5ad00a87..0e5c1dd95ef 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -94,9 +94,15 @@ public: PrepareAuraScript(spell_dru_moonkin_form_passive_AuraScript); uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + return true; + } + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) { - absorbPct = amount; // Set absorbtion amount to unlimited amount = -1; } @@ -132,9 +138,15 @@ public: PrepareAuraScript(spell_dru_primal_tenacity_AuraScript); uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_1, GetCaster()); + return true; + } + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) { - absorbPct = amount; // Set absorbtion amount to unlimited amount = -1; } @@ -170,19 +182,22 @@ public: PrepareAuraScript(spell_dru_savage_defense_AuraScript); uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + return true; + } + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) { - absorbPct = amount; // Set absorbtion amount to unlimited amount = -1; } void Absorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) { - // don't waste charge when no dmg - if (!dmgInfo.GetDamage()) - return; - absorbAmount = CalculatePctN(GetTarget()->GetTotalAttackPowerValue(BASE_ATTACK), absorbPct); + absorbAmount = int32(CalculatePctN(GetTarget()->GetTotalAttackPowerValue(BASE_ATTACK), absorbPct)); aurEff->SetAmount(0); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index e99d1e44548..0f664c3d829 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -25,6 +25,41 @@ #include "ScriptPCH.h" #include "SpellAuraEffects.h" +class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader +{ +public: + spell_gen_absorb0_hitlimit1() : SpellScriptLoader("spell_gen_absorb0_hitlimit1") { } + + class spell_gen_absorb0_hitlimit1_AuraScript : public AuraScript + { + PrepareAuraScript(spell_gen_absorb0_hitlimit1_AuraScript); + + uint32 limit; + + bool Load() + { + // Max absorb stored in 1 dummy effect + limit = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_1); + return true; + } + + void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + absorbAmount = std::min(limit, absorbAmount); + } + + void Register() + { + OnEffectAbsorb += AuraEffectAbsorbFn(spell_gen_absorb0_hitlimit1_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_gen_absorb0_hitlimit1_AuraScript(); + } +}; + // 41337 Aura of Anger class spell_gen_aura_of_anger : public SpellScriptLoader { @@ -562,6 +597,7 @@ class spell_gen_shroud_of_death : public SpellScriptLoader void AddSC_generic_spell_scripts() { + new spell_gen_absorb0_hitlimit1(); new spell_gen_aura_of_anger(); new spell_gen_burn_brutallus(); new spell_gen_leeching_swarm(); diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp index 901f36a3065..d4794e10b68 100644 --- a/src/server/scripts/Spells/spell_mage.cpp +++ b/src/server/scripts/Spells/spell_mage.cpp @@ -38,6 +38,39 @@ enum MageSpells SPELL_MAGE_GLYPH_OF_BLAST_WAVE = 62126, }; +class spell_mage_blast_wave : public SpellScriptLoader +{ + public: + spell_mage_blast_wave() : SpellScriptLoader("spell_mage_blast_wave") { } + + class spell_mage_blast_wave_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mage_blast_wave_SpellScript) + bool Validate(SpellEntry const * /*spellEntry*/) + { + if (!sSpellStore.LookupEntry(SPELL_MAGE_GLYPH_OF_BLAST_WAVE)) + return false; + return true; + } + + void HandleKnockBack(SpellEffIndex effIndex) + { + if (GetCaster()->HasAura(SPELL_MAGE_GLYPH_OF_BLAST_WAVE)) + PreventHitDefaultEffect(effIndex); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_mage_blast_wave_SpellScript::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); + } + }; + + SpellScript * GetSpellScript() const + { + return new spell_mage_blast_wave_SpellScript(); + } +}; + class spell_mage_cold_snap : public SpellScriptLoader { public: @@ -176,43 +209,61 @@ class spell_mage_summon_water_elemental : public SpellScriptLoader } }; -class spell_mage_blast_wave : public SpellScriptLoader +// Frost Ward and Fire Ward +class spell_mage_frost_warding_trigger : public SpellScriptLoader { - public: - spell_mage_blast_wave() : SpellScriptLoader("spell_mage_blast_wave") { } +public: + spell_mage_frost_warding_trigger() : SpellScriptLoader("spell_mage_frost_warding_trigger") { } - class spell_mage_blast_wave_SpellScript : public SpellScript + class spell_mage_frost_warding_trigger_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mage_frost_warding_trigger_AuraScript); + + enum Spells { - PrepareSpellScript(spell_mage_blast_wave_SpellScript) - bool Validate(SpellEntry const * /*spellEntry*/) - { - if (!sSpellStore.LookupEntry(SPELL_MAGE_GLYPH_OF_BLAST_WAVE)) - return false; - return true; - } + SPELL_MAGE_FROST_WARDING_TRIGGERED = 57776, + SPELL_MAGE_FROST_WARDING_R1 = 28332, + }; - void HandleKnockBack(SpellEffIndex effIndex) - { - if (GetCaster()->HasAura(SPELL_MAGE_GLYPH_OF_BLAST_WAVE)) - PreventHitDefaultEffect(effIndex); - } + bool Validate(SpellEntry const * /*spellEntry*/) + { + return sSpellStore.LookupEntry(SPELL_MAGE_FROST_WARDING_TRIGGERED) + && sSpellStore.LookupEntry(SPELL_MAGE_FROST_WARDING_R1); + } - void Register() + void Absorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + Unit * target = GetTarget(); + if (AuraEffect * talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_MAGE_FROST_WARDING_R1, EFFECT_0)) { - OnEffect += SpellEffectFn(spell_mage_blast_wave_SpellScript::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK); + int32 chance = SpellMgr::CalculateSpellEffectAmount(talentAurEff->GetSpellProto(), EFFECT_1); + + if (roll_chance_i(chance)) + { + absorbAmount = dmgInfo.GetDamage(); + int32 bp = absorbAmount; + target->CastCustomSpell(target, SPELL_MAGE_FROST_WARDING_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); + } } - }; + } - SpellScript * GetSpellScript() const + void Register() { - return new spell_mage_blast_wave_SpellScript(); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_mage_frost_warding_trigger_AuraScript::Absorb, EFFECT_0); } + }; + + AuraScript *GetAuraScript() const + { + return new spell_mage_frost_warding_trigger_AuraScript(); + } }; void AddSC_mage_spell_scripts() { + new spell_mage_blast_wave; new spell_mage_cold_snap; + new spell_mage_frost_warding_trigger(); new spell_mage_polymorph_cast_visual; new spell_mage_summon_water_elemental; - new spell_mage_blast_wave; } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index b53f172bfdf..828fa5de699 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -39,6 +39,82 @@ enum PaladinSpells SPELL_BLESSING_OF_LOWER_CITY_SHAMAN = 37881, }; +// 31850 - Ardent Defender +class spell_pal_ardent_defender : public SpellScriptLoader +{ +public: + spell_pal_ardent_defender() : SpellScriptLoader("spell_pal_ardent_defender") { } + + class spell_pal_ardent_defender_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_ardent_defender_AuraScript); + + uint32 absorbPct, healPct; + + enum Spell + { + PAL_SPELL_ARDENT_DEFENDER_HEAL = 66235, + }; + + bool Load() + { + healPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_1); + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0); + return GetUnitOwner()->ToPlayer(); + } + + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + Unit * pVictim = GetTarget(); + int32 remainingHealth = pVictim->GetHealth() - dmgInfo.GetDamage(); + uint32 allowedHealth = pVictim->CountPctFromMaxHealth(35); + // If damage kills us + if (remainingHealth <= 0 && !pVictim->ToPlayer()->HasSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL)) + { + // Cast healing spell, completely avoid damage + absorbAmount = dmgInfo.GetDamage(); + + uint32 defenseSkillValue = pVictim->GetDefenseSkillValue(); + // Max heal when defense skill denies critical hits from raid bosses + // Formula: max defense at level + 140 (raiting from gear) + uint32 reqDefForMaxHeal = pVictim->getLevel() * 5 + 140; + float pctFromDefense = (defenseSkillValue >= reqDefForMaxHeal) + ? 1.0f + : float(defenseSkillValue) / float(reqDefForMaxHeal); + + int32 healAmount = int32(pVictim->CountPctFromMaxHealth(uint32(healPct * pctFromDefense))); + pVictim->CastCustomSpell(pVictim, PAL_SPELL_ARDENT_DEFENDER_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff); + pVictim->ToPlayer()->AddSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL, 0, time(NULL) + 120); + } + else if (remainingHealth < int32(allowedHealth)) + { + // Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x% + uint32 damageToReduce = (pVictim->GetHealth() < allowedHealth) + ? dmgInfo.GetDamage() + : allowedHealth - remainingHealth; + absorbAmount = CalculatePctN(damageToReduce, absorbPct); + } + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_ardent_defender_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_pal_ardent_defender_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_pal_ardent_defender_AuraScript(); + } +}; + class spell_pal_blessing_of_faith : public SpellScriptLoader { public: @@ -253,6 +329,7 @@ public: void AddSC_paladin_spell_scripts() { + new spell_pal_ardent_defender(); new spell_pal_blessing_of_faith(); new spell_pal_blessing_of_sanctuary(); new spell_pal_guarded_by_the_light(); diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 6631d840309..b149f182a1d 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -31,6 +31,66 @@ enum PriestSpells PRIEST_SPELL_PENANCE_R1_HEAL = 47757, }; +// Guardian Spirit +class spell_pri_guardian_spirit : public SpellScriptLoader +{ +public: + spell_pri_guardian_spirit() : SpellScriptLoader("spell_pri_guardian_spirit") { } + + class spell_pri_guardian_spirit_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_guardian_spirit_AuraScript); + + uint32 healPct; + + enum Spell + { + PRI_SPELL_GUARDIAN_SPIRIT_HEAL = 48153, + }; + + bool Validate(SpellEntry const * /*spellEntry*/) + { + return sSpellStore.LookupEntry(PRI_SPELL_GUARDIAN_SPIRIT_HEAL); + } + + bool Load() + { + healPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_1); + return true; + } + + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + Unit * target = GetTarget(); + if (dmgInfo.GetDamage() < target->GetHealth()) + return; + + int32 healAmount = int32(target->CountPctFromMaxHealth(healPct)); + // remove the aura now, we don't want 40% healing bonus + Remove(AURA_REMOVE_BY_ENEMY_SPELL); + target->CastCustomSpell(target, PRI_SPELL_GUARDIAN_SPIRIT_HEAL, &healAmount, NULL, NULL, true); + absorbAmount = dmgInfo.GetDamage(); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_guardian_spirit_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_pri_guardian_spirit_AuraScript::Absorb, EFFECT_1); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_pri_guardian_spirit_AuraScript(); + } +}; + class spell_pri_mana_burn : public SpellScriptLoader { public: @@ -148,9 +208,59 @@ class spell_pri_penance : public SpellScriptLoader } }; +// Reflective Shield +class spell_pri_reflective_shield_trigger : public SpellScriptLoader +{ +public: + spell_pri_reflective_shield_trigger() : SpellScriptLoader("spell_pri_reflective_shield_trigger") { } + + class spell_pri_reflective_shield_trigger_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pri_reflective_shield_trigger_AuraScript); + + enum Spells + { + SPELL_PRI_REFLECTIVE_SHIELD_TRIGGERED = 33619, + SPELL_PRI_REFLECTIVE_SHIELD_R1 = 33201, + }; + + bool Validate(SpellEntry const * /*spellEntry*/) + { + return sSpellStore.LookupEntry(SPELL_PRI_REFLECTIVE_SHIELD_TRIGGERED) && sSpellStore.LookupEntry(SPELL_PRI_REFLECTIVE_SHIELD_R1); + } + + void Trigger(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + Unit * target = GetTarget(); + if (dmgInfo.GetAttacker() == target) + return; + Unit * caster = GetCaster(); + if (!caster) + return; + if (AuraEffect * talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PRI_REFLECTIVE_SHIELD_R1, EFFECT_0)) + { + int32 bp = CalculatePctN(absorbAmount, talentAurEff->GetAmount()); + target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_PRI_REFLECTIVE_SHIELD_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff); + } + } + + void Register() + { + AfterEffectAbsorb += AuraEffectAbsorbFn(spell_pri_reflective_shield_trigger_AuraScript::Trigger, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_pri_reflective_shield_trigger_AuraScript(); + } +}; + void AddSC_priest_spell_scripts() { + new spell_pri_guardian_spirit(); new spell_pri_mana_burn; new spell_pri_pain_and_suffering_proc; new spell_pri_penance; + new spell_pri_reflective_shield_trigger(); } diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp index ffae231839c..6d1afef3460 100644 --- a/src/server/scripts/Spells/spell_rogue.cpp +++ b/src/server/scripts/Spells/spell_rogue.cpp @@ -30,6 +30,76 @@ enum RogueSpells ROGUE_SPELL_PREY_ON_THE_WEAK = 58670, }; +// Cheat Death +class spell_rog_cheat_death : public SpellScriptLoader +{ +public: + spell_rog_cheat_death() : SpellScriptLoader("spell_rog_cheat_death") { } + + class spell_rog_cheat_death_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rog_cheat_death_AuraScript); + + uint32 absorbChance; + + enum Spell + { + ROG_SPELL_CHEAT_DEATH_COOLDOWN = 31231, + }; + + bool Validate(SpellEntry const * /*spellEntry*/) + { + return sSpellStore.LookupEntry(ROG_SPELL_CHEAT_DEATH_COOLDOWN); + } + + bool Load() + { + absorbChance = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0); + return GetUnitOwner()->ToPlayer(); + } + + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) + { + // Set absorbtion amount to unlimited + amount = -1; + } + + void Absorb(AuraEffect * aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount) + { + Unit * target = GetTarget(); + if (dmgInfo.GetDamage() < target->GetHealth()) + return; + if (target->ToPlayer()->HasSpellCooldown(ROG_SPELL_CHEAT_DEATH_COOLDOWN)) + return; + if (!roll_chance_i(absorbChance)) + return; + + target->CastSpell(target, ROG_SPELL_CHEAT_DEATH_COOLDOWN, true); + target->ToPlayer()->AddSpellCooldown(ROG_SPELL_CHEAT_DEATH_COOLDOWN, 0, time(NULL) + 60); + + uint32 health10 = target->CountPctFromMaxHealth(10); + + // hp > 10% - absorb hp till 10% + if (target->GetHealth() > health10) + absorbAmount = dmgInfo.GetDamage() - target->GetHealth() + health10; + // hp lower than 10% - absorb everything + else + absorbAmount = dmgInfo.GetDamage(); + } + + void Register() + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_rog_cheat_death_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_rog_cheat_death_AuraScript::Absorb, EFFECT_0); + } + }; + + AuraScript *GetAuraScript() const + { + return new spell_rog_cheat_death_AuraScript(); + } +}; + // 31130 - Nerves of Steel class spell_rog_nerves_of_steel : public SpellScriptLoader { @@ -41,9 +111,15 @@ public: PrepareAuraScript(spell_rog_nerves_of_steel_AuraScript); uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + return true; + } + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) { - absorbPct = amount; // Set absorbtion amount to unlimited amount = -1; } @@ -216,6 +292,7 @@ class spell_rog_shiv : public SpellScriptLoader void AddSC_rogue_spell_scripts() { + new spell_rog_cheat_death(); new spell_rog_nerves_of_steel(); new spell_rog_preparation(); new spell_rog_prey_on_the_weak(); diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index bf8e179a438..7c59c5227ca 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -47,9 +47,15 @@ public: PrepareAuraScript(spell_sha_astral_shift_AuraScript); uint32 absorbPct; + + bool Load() + { + absorbPct = SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_0, GetCaster()); + return true; + } + void CalculateAmount(AuraEffect const * /*aurEff*/, int32 & amount, bool & canBeRecalculated) { - absorbPct = amount; // Set absorbtion amount to unlimited amount = -1; } |
