PageRenderTime 121ms CodeModel.GetById 2ms app.highlight 110ms RepoModel.GetById 1ms app.codeStats 1ms

/src/server/scripts/Spells/spell_priest.cpp

https://gitlab.com/tkrokli/TrinityCore_434
C++ | 1265 lines | 992 code | 210 blank | 63 comment | 75 complexity | ee45969e31dfc1c059e25c796a70d203 MD5 | raw file
   1/*
   2 * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms of the GNU General Public License as published by the
   6 * Free Software Foundation; either version 2 of the License, or (at your
   7 * option) any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along
  15 * with this program. If not, see <http://www.gnu.org/licenses/>.
  16 */
  17
  18/*
  19 * Scripts for spells with SPELLFAMILY_PRIEST and SPELLFAMILY_GENERIC spells used by priest players.
  20 * Ordered alphabetically using scriptname.
  21 * Scriptnames of files in this file should be prefixed with "spell_pri_".
  22 */
  23
  24#include "Player.h"
  25#include "ScriptMgr.h"
  26#include "SpellScript.h"
  27#include "SpellAuraEffects.h"
  28#include "GridNotifiers.h"
  29
  30enum PriestSpells
  31{
  32    SPELL_PRIEST_ABSOLUTION                         = 33167,
  33    SPELL_PRIEST_BODY_AND_SOUL_DISPEL               = 64136,
  34    SPELL_PRIEST_BODY_AND_SOUL_SPEED                = 65081,
  35    SPELL_PRIEST_CURE_DISEASE                       = 528,
  36    SPELL_PRIEST_DISPEL_MAGIC_FRIENDLY              = 97690,
  37    SPELL_PRIEST_DISPEL_MAGIC_HOSTILE               = 97691,
  38    SPELL_PRIEST_DIVINE_AEGIS                       = 47753,
  39    SPELL_PRIEST_DIVINE_TOUCH                       = 63544,
  40    SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING         = 55675,
  41    SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC              = 55677,
  42    SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL         = 56131,
  43    SPELL_PRIEST_GLYPH_OF_LIGHTWELL                 = 55673,
  44    SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL    = 56161,
  45    SPELL_PRIEST_GLYPH_OF_SHADOW                    = 107906,
  46    SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL               = 48153,
  47    SPELL_PRIEST_ITEM_EFFICIENCY                    = 37595,
  48    SPELL_PRIEST_LEAP_OF_FAITH                      = 73325,
  49    SPELL_PRIEST_LEAP_OF_FAITH_EFFECT               = 92832,
  50    SPELL_PRIEST_LEAP_OF_FAITH_EFFECT_TRIGGER       = 92833,
  51    SPELL_PRIEST_LEAP_OF_FAITH_TRIGGERED            = 92572,
  52    SPELL_PRIEST_MANA_LEECH_PROC                    = 34650,
  53    SPELL_PRIEST_PENANCE_R1                         = 47540,
  54    SPELL_PRIEST_PENANCE_R1_DAMAGE                  = 47758,
  55    SPELL_PRIEST_PENANCE_R1_HEAL                    = 47757,
  56    SPELL_PRIEST_REFLECTIVE_SHIELD_R1               = 33201,
  57    SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED        = 33619,
  58    SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH    = 107903,
  59    SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH       = 107904,
  60    SPELL_PRIEST_SHADOW_WORD_DEATH                  = 32409,
  61    SPELL_PRIEST_TWIN_DISCIPLINES_RANK_1            = 47586,
  62    SPELL_PRIEST_T9_HEALING_2P                      = 67201,
  63    SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL              = 15290,
  64    SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL              = 64085
  65};
  66
  67enum PriestSpellIcons
  68{
  69    PRIEST_ICON_ID_BORROWED_TIME                    = 2899,
  70    PRIEST_ICON_ID_DIVINE_TOUCH_TALENT              = 3021,
  71    PRIEST_ICON_ID_PAIN_AND_SUFFERING               = 2874
  72};
  73
  74enum MiscSpells
  75{
  76    SPELL_GEN_REPLENISHMENT                         = 57669
  77};
  78
  79class PowerCheck
  80{
  81    public:
  82        explicit PowerCheck(Powers const power) : _power(power) { }
  83
  84        bool operator()(WorldObject* obj) const
  85        {
  86            if (Unit* target = obj->ToUnit())
  87                return target->getPowerType() != _power;
  88
  89            return true;
  90        }
  91
  92    private:
  93        Powers const _power;
  94};
  95
  96class RaidCheck
  97{
  98    public:
  99        explicit RaidCheck(Unit const* caster) : _caster(caster) { }
 100
 101        bool operator()(WorldObject* obj) const
 102        {
 103            if (Unit* target = obj->ToUnit())
 104                return !_caster->IsInRaidWith(target);
 105
 106            return true;
 107        }
 108
 109    private:
 110        Unit const* _caster;
 111};
 112
 113class spell_pri_body_and_soul : public SpellScriptLoader
 114{
 115    public:
 116        spell_pri_body_and_soul() : SpellScriptLoader("spell_pri_body_and_soul") { }
 117
 118        class spell_pri_body_and_soul_AuraScript : public AuraScript
 119        {
 120            PrepareAuraScript(spell_pri_body_and_soul_AuraScript);
 121
 122            bool Validate(SpellInfo const* /*spellInfo*/) override
 123            {
 124                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_CURE_DISEASE) ||
 125                    !sSpellMgr->GetSpellInfo(SPELL_PRIEST_BODY_AND_SOUL_DISPEL))
 126                    return false;
 127                return true;
 128            }
 129
 130            void HandleEffectSpeedProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
 131            {
 132                PreventDefaultAction();
 133                // Proc only with Power Word: Shield or Leap of Faith
 134                if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[0] & 0x1 || eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[2] & 0x80000))
 135                    return;
 136
 137                GetTarget()->CastCustomSpell(SPELL_PRIEST_BODY_AND_SOUL_SPEED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), eventInfo.GetProcTarget(), true, NULL, aurEff);
 138            }
 139
 140            void HandleEffectDispelProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
 141            {
 142                PreventDefaultAction();
 143                // Proc only with Cure Disease
 144                if (eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_PRIEST_CURE_DISEASE || eventInfo.GetProcTarget() != GetTarget())
 145                    return;
 146
 147                if (roll_chance_i(aurEff->GetAmount()))
 148                    GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_PRIEST_BODY_AND_SOUL_DISPEL, true, NULL, aurEff);
 149            }
 150
 151            void Register() override
 152            {
 153                OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul_AuraScript::HandleEffectSpeedProc, EFFECT_0, SPELL_AURA_DUMMY);
 154                OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul_AuraScript::HandleEffectDispelProc, EFFECT_1, SPELL_AURA_DUMMY);
 155            }
 156        };
 157
 158        AuraScript* GetAuraScript() const override
 159        {
 160            return new spell_pri_body_and_soul_AuraScript();
 161        }
 162};
 163
 164// 34861 - Circle of Healing
 165class spell_pri_circle_of_healing : public SpellScriptLoader
 166{
 167    public:
 168        spell_pri_circle_of_healing() : SpellScriptLoader("spell_pri_circle_of_healing") { }
 169
 170        class spell_pri_circle_of_healing_SpellScript : public SpellScript
 171        {
 172            PrepareSpellScript(spell_pri_circle_of_healing_SpellScript);
 173
 174            bool Validate(SpellInfo const* /*spellInfo*/) override
 175            {
 176                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING))
 177                    return false;
 178                return true;
 179            }
 180
 181            void FilterTargets(std::list<WorldObject*>& targets)
 182            {
 183                targets.remove_if(RaidCheck(GetCaster()));
 184
 185                uint32 const maxTargets = GetCaster()->HasAura(SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING) ? 6 : 5; // Glyph of Circle of Healing
 186
 187                if (targets.size() > maxTargets)
 188                {
 189                    targets.sort(Trinity::HealthPctOrderPred());
 190                    targets.resize(maxTargets);
 191                }
 192            }
 193
 194            void Register() override
 195            {
 196                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_circle_of_healing_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
 197            }
 198        };
 199
 200        SpellScript* GetSpellScript() const override
 201        {
 202            return new spell_pri_circle_of_healing_SpellScript();
 203        }
 204};
 205
 206// 527 - Dispel magic
 207class spell_pri_dispel_magic : public SpellScriptLoader
 208{
 209public:
 210    spell_pri_dispel_magic() : SpellScriptLoader("spell_pri_dispel_magic") { }
 211
 212    class spell_pri_dispel_magic_SpellScript : public SpellScript
 213    {
 214        PrepareSpellScript(spell_pri_dispel_magic_SpellScript);
 215
 216        bool Validate(SpellInfo const* /*spellInfo*/)
 217        {
 218            if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ABSOLUTION))
 219                return false;
 220            if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL))
 221                return false;
 222            if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC))
 223                return false;
 224            return true;
 225        }
 226
 227        SpellCastResult CheckCast()
 228        {
 229            Unit* caster = GetCaster();
 230            Unit* target = GetExplTargetUnit();
 231
 232            if (!target || (!caster->HasAura(SPELL_PRIEST_ABSOLUTION) && caster != target && target->IsFriendlyTo(caster)))
 233                return SPELL_FAILED_BAD_TARGETS;
 234            return SPELL_CAST_OK;
 235        }
 236
 237        void AfterEffectHit(SpellEffIndex /*effIndex*/)
 238        {
 239            if (GetHitUnit()->IsFriendlyTo(GetCaster()))
 240            {
 241                GetCaster()->CastSpell(GetHitUnit(), SPELL_PRIEST_DISPEL_MAGIC_FRIENDLY, true);
 242                if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffect(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC, EFFECT_0))
 243                {
 244                    int32 heal = GetHitUnit()->CountPctFromMaxHealth(aurEff->GetAmount());
 245                    GetCaster()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL, SPELLVALUE_BASE_POINT0, heal, GetHitUnit());
 246                }
 247            }
 248            else
 249                GetCaster()->CastSpell(GetHitUnit(), SPELL_PRIEST_DISPEL_MAGIC_HOSTILE, true);
 250        }
 251
 252        void Register()
 253        {
 254            OnCheckCast += SpellCheckCastFn(spell_pri_dispel_magic_SpellScript::CheckCast);
 255            OnEffectHitTarget += SpellEffectFn(spell_pri_dispel_magic_SpellScript::AfterEffectHit, EFFECT_0, SPELL_EFFECT_DUMMY);
 256        }
 257    };
 258
 259    SpellScript* GetSpellScript() const
 260    {
 261        return new spell_pri_dispel_magic_SpellScript();
 262    }
 263};
 264
 265// -47509 - Divine Aegis
 266class spell_pri_divine_aegis : public SpellScriptLoader
 267{
 268    public:
 269        spell_pri_divine_aegis() : SpellScriptLoader("spell_pri_divine_aegis") { }
 270
 271        class spell_pri_divine_aegis_AuraScript : public AuraScript
 272        {
 273            PrepareAuraScript(spell_pri_divine_aegis_AuraScript);
 274
 275            bool Validate(SpellInfo const* /*spellInfo*/) override
 276            {
 277                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_DIVINE_AEGIS))
 278                    return false;
 279                return true;
 280            }
 281
 282            bool CheckProc(ProcEventInfo& eventInfo)
 283            {
 284                return eventInfo.GetProcTarget() != nullptr;
 285            }
 286
 287            void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
 288            {
 289                PreventDefaultAction();
 290
 291                int32 absorb = CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount());
 292
 293                // Multiple effects stack, so let's try to find this aura.
 294                if (AuraEffect const* aegis = eventInfo.GetProcTarget()->GetAuraEffect(SPELL_PRIEST_DIVINE_AEGIS, EFFECT_0))
 295                    absorb += aegis->GetAmount();
 296
 297                absorb = std::min(absorb, eventInfo.GetProcTarget()->getLevel() * 125);
 298
 299                GetTarget()->CastCustomSpell(SPELL_PRIEST_DIVINE_AEGIS, SPELLVALUE_BASE_POINT0, absorb, eventInfo.GetProcTarget(), true, NULL, aurEff);
 300            }
 301
 302            void Register() override
 303            {
 304                DoCheckProc += AuraCheckProcFn(spell_pri_divine_aegis_AuraScript::CheckProc);
 305                OnEffectProc += AuraEffectProcFn(spell_pri_divine_aegis_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
 306            }
 307        };
 308
 309        AuraScript* GetAuraScript() const override
 310        {
 311            return new spell_pri_divine_aegis_AuraScript();
 312        }
 313};
 314
 315// 64844 - Divine Hymn
 316class spell_pri_divine_hymn : public SpellScriptLoader
 317{
 318    public:
 319        spell_pri_divine_hymn() : SpellScriptLoader("spell_pri_divine_hymn") { }
 320
 321        class spell_pri_divine_hymn_SpellScript : public SpellScript
 322        {
 323            PrepareSpellScript(spell_pri_divine_hymn_SpellScript);
 324
 325            void FilterTargets(std::list<WorldObject*>& targets)
 326            {
 327                targets.remove_if(RaidCheck(GetCaster()));
 328
 329                uint32 const maxTargets = 3;
 330
 331                if (targets.size() > maxTargets)
 332                {
 333                    targets.sort(Trinity::HealthPctOrderPred());
 334                    targets.resize(maxTargets);
 335                }
 336            }
 337
 338            void Register() override
 339            {
 340                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_divine_hymn_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ALLY);
 341            }
 342        };
 343
 344        SpellScript* GetSpellScript() const override
 345        {
 346            return new spell_pri_divine_hymn_SpellScript();
 347        }
 348};
 349
 350// 55680 - Glyph of Prayer of Healing
 351class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader
 352{
 353    public:
 354        spell_pri_glyph_of_prayer_of_healing() : SpellScriptLoader("spell_pri_glyph_of_prayer_of_healing") { }
 355
 356        class spell_pri_glyph_of_prayer_of_healing_AuraScript : public AuraScript
 357        {
 358            PrepareAuraScript(spell_pri_glyph_of_prayer_of_healing_AuraScript);
 359
 360            bool Validate(SpellInfo const* /*spellInfo*/) override
 361            {
 362                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL))
 363                    return false;
 364                return true;
 365            }
 366
 367            void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
 368            {
 369                PreventDefaultAction();
 370
 371                SpellInfo const* triggeredSpellInfo = sSpellMgr->EnsureSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL);
 372                int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks());
 373                GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff);
 374            }
 375
 376            void Register() override
 377            {
 378                OnEffectProc += AuraEffectProcFn(spell_pri_glyph_of_prayer_of_healing_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
 379            }
 380        };
 381
 382        AuraScript* GetAuraScript() const override
 383        {
 384            return new spell_pri_glyph_of_prayer_of_healing_AuraScript();
 385        }
 386};
 387
 388class spell_pri_improved_power_word_shield : public SpellScriptLoader
 389{
 390    public:
 391        spell_pri_improved_power_word_shield() : SpellScriptLoader("spell_pri_improved_power_word_shield") { }
 392
 393        class spell_pri_improved_power_word_shield_AuraScript : public AuraScript
 394        {
 395            PrepareAuraScript(spell_pri_improved_power_word_shield_AuraScript);
 396
 397            void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)
 398            {
 399                if (!spellMod)
 400                {
 401                    spellMod = new SpellModifier(GetAura());
 402                    spellMod->op = SpellModOp(aurEff->GetMiscValue());
 403                    spellMod->type = SPELLMOD_PCT;
 404                    spellMod->spellId = GetId();
 405                    spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask;
 406                }
 407
 408                spellMod->value = aurEff->GetAmount();
 409            }
 410
 411            void Register() override
 412            {
 413                DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_pri_improved_power_word_shield_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
 414            }
 415        };
 416
 417        AuraScript* GetAuraScript() const override
 418        {
 419            return new spell_pri_improved_power_word_shield_AuraScript();
 420        }
 421};
 422
 423// 37594 - Greater Heal Refund
 424class spell_pri_item_greater_heal_refund : public SpellScriptLoader
 425{
 426    public:
 427        spell_pri_item_greater_heal_refund() : SpellScriptLoader("spell_pri_item_greater_heal_refund") { }
 428
 429        class spell_pri_item_greater_heal_refund_AuraScript : public AuraScript
 430        {
 431            PrepareAuraScript(spell_pri_item_greater_heal_refund_AuraScript);
 432
 433            bool Validate(SpellInfo const* /*spellInfo*/) override
 434            {
 435                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ITEM_EFFICIENCY))
 436                    return false;
 437                return true;
 438            }
 439
 440            void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
 441            {
 442                PreventDefaultAction();
 443                GetTarget()->CastSpell(GetTarget(), SPELL_PRIEST_ITEM_EFFICIENCY, true, NULL, aurEff);
 444            }
 445
 446            void Register() override
 447            {
 448                OnEffectProc += AuraEffectProcFn(spell_pri_item_greater_heal_refund_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
 449            }
 450        };
 451
 452        AuraScript* GetAuraScript() const override
 453        {
 454            return new spell_pri_item_greater_heal_refund_AuraScript();
 455        }
 456};
 457
 458// 47788 - Guardian Spirit
 459class spell_pri_guardian_spirit : public SpellScriptLoader
 460{
 461    public:
 462        spell_pri_guardian_spirit() : SpellScriptLoader("spell_pri_guardian_spirit") { }
 463
 464        class spell_pri_guardian_spirit_AuraScript : public AuraScript
 465        {
 466            PrepareAuraScript(spell_pri_guardian_spirit_AuraScript);
 467
 468        public:
 469            spell_pri_guardian_spirit_AuraScript()
 470            {
 471                healPct = 0;
 472            }
 473
 474        private:
 475            uint32 healPct;
 476
 477            bool Validate(SpellInfo const* /*spellInfo*/) override
 478            {
 479                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL))
 480                    return false;
 481                return true;
 482            }
 483
 484            bool Load() override
 485            {
 486                healPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
 487                return true;
 488            }
 489
 490            void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
 491            {
 492                // Set absorbtion amount to unlimited
 493                amount = -1;
 494            }
 495
 496            void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
 497            {
 498                Unit* target = GetTarget();
 499                if (dmgInfo.GetDamage() < target->GetHealth())
 500                    return;
 501
 502                int32 healAmount = int32(target->CountPctFromMaxHealth(healPct));
 503                // remove the aura now, we don't want 40% healing bonus
 504                Remove(AURA_REMOVE_BY_ENEMY_SPELL);
 505                target->CastCustomSpell(target, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL, &healAmount, NULL, NULL, true);
 506                absorbAmount = dmgInfo.GetDamage();
 507            }
 508
 509            void Register() override
 510            {
 511                DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_guardian_spirit_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_SCHOOL_ABSORB);
 512                OnEffectAbsorb += AuraEffectAbsorbFn(spell_pri_guardian_spirit_AuraScript::Absorb, EFFECT_1);
 513            }
 514        };
 515
 516        AuraScript* GetAuraScript() const override
 517        {
 518            return new spell_pri_guardian_spirit_AuraScript();
 519        }
 520};
 521
 522// 64904 - Hymn of Hope
 523class spell_pri_hymn_of_hope : public SpellScriptLoader
 524{
 525    public:
 526        spell_pri_hymn_of_hope() : SpellScriptLoader("spell_pri_hymn_of_hope") { }
 527
 528        class spell_pri_hymn_of_hope_SpellScript : public SpellScript
 529        {
 530            PrepareSpellScript(spell_pri_hymn_of_hope_SpellScript);
 531
 532            void FilterTargets(std::list<WorldObject*>& targets)
 533            {
 534                targets.remove_if(PowerCheck(POWER_MANA));
 535                targets.remove_if(RaidCheck(GetCaster()));
 536
 537                uint32 const maxTargets = 3;
 538
 539                if (targets.size() > maxTargets)
 540                {
 541                    targets.sort(Trinity::PowerPctOrderPred(POWER_MANA));
 542                    targets.resize(maxTargets);
 543                }
 544            }
 545
 546            void Register() override
 547            {
 548                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_hymn_of_hope_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ALLY);
 549            }
 550        };
 551
 552        SpellScript* GetSpellScript() const override
 553        {
 554            return new spell_pri_hymn_of_hope_SpellScript();
 555        }
 556};
 557
 558// 92833 - Leap of Faith
 559class spell_pri_leap_of_faith_effect_trigger : public SpellScriptLoader
 560{
 561    public:
 562        spell_pri_leap_of_faith_effect_trigger() : SpellScriptLoader("spell_pri_leap_of_faith_effect_trigger") { }
 563
 564        class spell_pri_leap_of_faith_effect_trigger_SpellScript : public SpellScript
 565        {
 566            PrepareSpellScript(spell_pri_leap_of_faith_effect_trigger_SpellScript);
 567
 568            bool Validate(SpellInfo const* /*spellInfo*/) override
 569            {
 570                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_LEAP_OF_FAITH_EFFECT))
 571                    return false;
 572                return true;
 573            }
 574
 575            void HandleEffectDummy(SpellEffIndex /*effIndex*/)
 576            {
 577                Position destPos = GetHitDest()->GetPosition();
 578
 579                SpellCastTargets targets;
 580                targets.SetDst(destPos);
 581                targets.SetUnitTarget(GetCaster());
 582                GetHitUnit()->CastSpell(targets, sSpellMgr->GetSpellInfo(GetEffectValue()), NULL);
 583            }
 584
 585            void Register() override
 586            {
 587                OnEffectHitTarget += SpellEffectFn(spell_pri_leap_of_faith_effect_trigger_SpellScript::HandleEffectDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
 588            }
 589        };
 590
 591        SpellScript* GetSpellScript() const override
 592        {
 593            return new spell_pri_leap_of_faith_effect_trigger_SpellScript();
 594        }
 595};
 596
 597// 7001 - Lightwell Renew
 598class spell_pri_lightwell_renew : public SpellScriptLoader
 599{
 600    public:
 601        spell_pri_lightwell_renew() : SpellScriptLoader("spell_pri_lightwell_renew") { }
 602
 603        class spell_pri_lightwell_renew_AuraScript : public AuraScript
 604        {
 605            PrepareAuraScript(spell_pri_lightwell_renew_AuraScript);
 606
 607            void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
 608            {
 609                if (Unit* caster = GetCaster())
 610                {
 611                    // Bonus from Glyph of Lightwell
 612                    if (AuraEffect* modHealing = caster->GetAuraEffect(SPELL_PRIEST_GLYPH_OF_LIGHTWELL, EFFECT_0))
 613                        AddPct(amount, modHealing->GetAmount());
 614                }
 615            }
 616
 617            void Register() override
 618            {
 619                DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_lightwell_renew_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
 620            }
 621        };
 622
 623        AuraScript* GetAuraScript() const override
 624        {
 625            return new spell_pri_lightwell_renew_AuraScript();
 626        }
 627};
 628
 629// 8129 - Mana Burn
 630class spell_pri_mana_burn : public SpellScriptLoader
 631{
 632    public:
 633        spell_pri_mana_burn() : SpellScriptLoader("spell_pri_mana_burn") { }
 634
 635        class spell_pri_mana_burn_SpellScript : public SpellScript
 636        {
 637            PrepareSpellScript(spell_pri_mana_burn_SpellScript);
 638
 639            void HandleAfterHit()
 640            {
 641                if (Unit* unitTarget = GetHitUnit())
 642                    unitTarget->RemoveAurasWithMechanic((1 << MECHANIC_FEAR) | (1 << MECHANIC_POLYMORPH));
 643            }
 644
 645            void Register() override
 646            {
 647                AfterHit += SpellHitFn(spell_pri_mana_burn_SpellScript::HandleAfterHit);
 648            }
 649        };
 650
 651        SpellScript* GetSpellScript() const override
 652        {
 653            return new spell_pri_mana_burn_SpellScript;
 654        }
 655};
 656
 657// 28305 - Mana Leech (Passive) (Priest Pet Aura)
 658class spell_pri_mana_leech : public SpellScriptLoader
 659{
 660    public:
 661        spell_pri_mana_leech() : SpellScriptLoader("spell_pri_mana_leech") { }
 662
 663        class spell_pri_mana_leech_AuraScript : public AuraScript
 664        {
 665            PrepareAuraScript(spell_pri_mana_leech_AuraScript);
 666
 667        public:
 668            spell_pri_mana_leech_AuraScript()
 669            {
 670                _procTarget = nullptr;
 671            }
 672
 673        private:
 674            bool Validate(SpellInfo const* /*spellInfo*/) override
 675            {
 676                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_MANA_LEECH_PROC))
 677                    return false;
 678                return true;
 679            }
 680
 681            bool CheckProc(ProcEventInfo& /*eventInfo*/)
 682            {
 683                _procTarget = GetTarget()->GetOwner();
 684                return _procTarget != nullptr;
 685            }
 686
 687            void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
 688            {
 689                PreventDefaultAction();
 690                GetTarget()->CastSpell(_procTarget, SPELL_PRIEST_MANA_LEECH_PROC, true, NULL, aurEff);
 691            }
 692
 693            void Register() override
 694            {
 695                DoCheckProc += AuraCheckProcFn(spell_pri_mana_leech_AuraScript::CheckProc);
 696                OnEffectProc += AuraEffectProcFn(spell_pri_mana_leech_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
 697            }
 698
 699        private:
 700            Unit* _procTarget;
 701        };
 702
 703        AuraScript* GetAuraScript() const override
 704        {
 705            return new spell_pri_mana_leech_AuraScript();
 706        }
 707};
 708
 709// 49821 - Mind Sear
 710class spell_pri_mind_sear : public SpellScriptLoader
 711{
 712    public:
 713        spell_pri_mind_sear() : SpellScriptLoader("spell_pri_mind_sear") { }
 714
 715        class spell_pri_mind_sear_SpellScript : public SpellScript
 716        {
 717            PrepareSpellScript(spell_pri_mind_sear_SpellScript);
 718
 719            void FilterTargets(std::list<WorldObject*>& unitList)
 720            {
 721                unitList.remove_if(Trinity::ObjectGUIDCheck(GetCaster()->GetChannelObjectGuid()));
 722            }
 723
 724            void Register() override
 725            {
 726                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
 727            }
 728        };
 729
 730        SpellScript* GetSpellScript() const override
 731        {
 732            return new spell_pri_mind_sear_SpellScript();
 733        }
 734};
 735
 736// 47948 - Pain and Suffering (Proc)
 737class spell_pri_pain_and_suffering_proc : public SpellScriptLoader
 738{
 739    public:
 740        spell_pri_pain_and_suffering_proc() : SpellScriptLoader("spell_pri_pain_and_suffering_proc") { }
 741
 742        class spell_pri_pain_and_suffering_proc_SpellScript : public SpellScript
 743        {
 744            PrepareSpellScript(spell_pri_pain_and_suffering_proc_SpellScript);
 745
 746            void HandleEffectScriptEffect(SpellEffIndex /*effIndex*/)
 747            {
 748                Unit* caster = GetCaster();
 749                // Refresh Shadow Word: Pain on target
 750                if (Unit* target = GetHitUnit())
 751                    if (AuraEffect* aur = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, caster->GetGUID()))
 752                    {
 753                        aur->SetBonusAmount(caster->SpellDamageBonusDone(target, aur->GetSpellInfo(), 0, DOT));
 754                        aur->CalculatePeriodic(caster, false, false);
 755                        aur->GetBase()->RefreshDuration();
 756                    }
 757            }
 758
 759            void Register() override
 760            {
 761                OnEffectHitTarget += SpellEffectFn(spell_pri_pain_and_suffering_proc_SpellScript::HandleEffectScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
 762            }
 763        };
 764
 765        SpellScript* GetSpellScript() const override
 766        {
 767            return new spell_pri_pain_and_suffering_proc_SpellScript;
 768        }
 769};
 770
 771// 47540 - Penance
 772class spell_pri_penance : public SpellScriptLoader
 773{
 774    public:
 775        spell_pri_penance() : SpellScriptLoader("spell_pri_penance") { }
 776
 777        class spell_pri_penance_SpellScript : public SpellScript
 778        {
 779            PrepareSpellScript(spell_pri_penance_SpellScript);
 780
 781            bool Load() override
 782            {
 783                return GetCaster()->GetTypeId() == TYPEID_PLAYER;
 784            }
 785
 786            bool Validate(SpellInfo const* spellInfo) override
 787            {
 788                SpellInfo const* firstRankSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_PENANCE_R1);
 789                if (!firstRankSpellInfo)
 790                    return false;
 791
 792                // can't use other spell than this penance due to spell_ranks dependency
 793                if (!spellInfo->IsRankOf(firstRankSpellInfo))
 794                    return false;
 795
 796                uint8 rank = spellInfo->GetRank();
 797                if (!sSpellMgr->GetSpellWithRank(SPELL_PRIEST_PENANCE_R1_DAMAGE, rank, true))
 798                    return false;
 799                if (!sSpellMgr->GetSpellWithRank(SPELL_PRIEST_PENANCE_R1_HEAL, rank, true))
 800                    return false;
 801
 802                return true;
 803            }
 804
 805            void HandleDummy(SpellEffIndex /*effIndex*/)
 806            {
 807                Unit* caster = GetCaster();
 808                if (Unit* unitTarget = GetHitUnit())
 809                {
 810                    if (!unitTarget->IsAlive())
 811                        return;
 812
 813                    uint8 rank = GetSpellInfo()->GetRank();
 814
 815                    if (caster->IsFriendlyTo(unitTarget))
 816                        caster->CastSpell(unitTarget, sSpellMgr->GetSpellWithRank(SPELL_PRIEST_PENANCE_R1_HEAL, rank), false);
 817                    else
 818                        caster->CastSpell(unitTarget, sSpellMgr->GetSpellWithRank(SPELL_PRIEST_PENANCE_R1_DAMAGE, rank), false);
 819                }
 820            }
 821
 822            SpellCastResult CheckCast()
 823            {
 824                Player* caster = GetCaster()->ToPlayer();
 825                if (Unit* target = GetExplTargetUnit())
 826                    if (!caster->IsFriendlyTo(target) && !caster->IsValidAttackTarget(target))
 827                        return SPELL_FAILED_BAD_TARGETS;
 828                return SPELL_CAST_OK;
 829            }
 830
 831            void Register() override
 832            {
 833                OnEffectHitTarget += SpellEffectFn(spell_pri_penance_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
 834                OnCheckCast += SpellCheckCastFn(spell_pri_penance_SpellScript::CheckCast);
 835            }
 836        };
 837
 838        SpellScript* GetSpellScript() const override
 839        {
 840            return new spell_pri_penance_SpellScript;
 841        }
 842};
 843
 844// -47569 - Phantasm
 845class spell_pri_phantasm : public SpellScriptLoader
 846{
 847    public:
 848        spell_pri_phantasm() : SpellScriptLoader("spell_pri_phantasm") { }
 849
 850        class spell_pri_phantasm_AuraScript : public AuraScript
 851        {
 852            PrepareAuraScript(spell_pri_phantasm_AuraScript);
 853
 854            bool CheckProc(ProcEventInfo& /*eventInfo*/)
 855            {
 856                return roll_chance_i(GetEffect(EFFECT_0)->GetAmount());
 857            }
 858
 859            void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
 860            {
 861                PreventDefaultAction();
 862                GetTarget()->RemoveMovementImpairingAuras();
 863            }
 864
 865            void Register() override
 866            {
 867                DoCheckProc += AuraCheckProcFn(spell_pri_phantasm_AuraScript::CheckProc);
 868                OnEffectProc += AuraEffectProcFn(spell_pri_phantasm_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
 869            }
 870        };
 871
 872        AuraScript* GetAuraScript() const override
 873        {
 874            return new spell_pri_phantasm_AuraScript();
 875        }
 876};
 877
 878// 17 - Power Word: Shield
 879class spell_pri_power_word_shield : public SpellScriptLoader
 880{
 881    public:
 882        spell_pri_power_word_shield() : SpellScriptLoader("spell_pri_power_word_shield") { }
 883
 884        class spell_pri_power_word_shield_AuraScript : public AuraScript
 885        {
 886            PrepareAuraScript(spell_pri_power_word_shield_AuraScript);
 887
 888            bool Validate(SpellInfo const* /*spellInfo*/) override
 889            {
 890                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED))
 891                    return false;
 892                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_REFLECTIVE_SHIELD_R1))
 893                    return false;
 894                return true;
 895            }
 896
 897            void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated)
 898            {
 899                canBeRecalculated = false;
 900                if (Unit* caster = GetCaster())
 901                {
 902                    // +87% from sp bonus
 903                    float bonus = 0.87f;
 904
 905                    // Borrowed Time
 906                    if (AuraEffect const* borrowedTime = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_BORROWED_TIME, EFFECT_1))
 907                        bonus += CalculatePct(1.0f, borrowedTime->GetAmount());
 908
 909                    bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask());
 910
 911                    // Improved PW: Shield: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :)
 912                    // Improved PW: Shield is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage
 913                    bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus);
 914                    bonus *= caster->CalculateLevelPenalty(GetSpellInfo());
 915
 916                    amount += int32(bonus);
 917
 918                    // Twin Disciplines
 919                    if (AuraEffect const* twinDisciplines = caster->GetAuraEffectOfRankedSpell(SPELL_PRIEST_TWIN_DISCIPLINES_RANK_1, EFFECT_1))
 920                        AddPct(amount, twinDisciplines->GetAmount());
 921
 922                    // Focused Power
 923                    amount *= caster->GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
 924                }
 925            }
 926
 927            void ReflectDamage(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)
 928            {
 929                Unit* target = GetTarget();
 930                if (dmgInfo.GetAttacker() == target)
 931                    return;
 932
 933                if (AuraEffect const* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PRIEST_REFLECTIVE_SHIELD_R1, EFFECT_0))
 934                {
 935                    int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount());
 936                    target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff);
 937                }
 938            }
 939
 940            void Register() override
 941            {
 942                DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_power_word_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
 943                AfterEffectAbsorb += AuraEffectAbsorbFn(spell_pri_power_word_shield_AuraScript::ReflectDamage, EFFECT_0);
 944            }
 945        };
 946
 947        AuraScript* GetAuraScript() const override
 948        {
 949            return new spell_pri_power_word_shield_AuraScript();
 950        }
 951};
 952
 953// 33110 - Prayer of Mending Heal
 954class spell_pri_prayer_of_mending_heal : public SpellScriptLoader
 955{
 956    public:
 957        spell_pri_prayer_of_mending_heal() : SpellScriptLoader("spell_pri_prayer_of_mending_heal") { }
 958
 959        class spell_pri_prayer_of_mending_heal_SpellScript : public SpellScript
 960        {
 961            PrepareSpellScript(spell_pri_prayer_of_mending_heal_SpellScript);
 962
 963            void HandleHeal(SpellEffIndex /*effIndex*/)
 964            {
 965                if (Unit* caster = GetOriginalCaster())
 966                {
 967                    if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_PRIEST_T9_HEALING_2P, EFFECT_0))
 968                    {
 969                        int32 heal = GetHitHeal();
 970                        AddPct(heal, aurEff->GetAmount());
 971                        SetHitHeal(heal);
 972                    }
 973                }
 974            }
 975
 976            void Register() override
 977            {
 978                OnEffectHitTarget += SpellEffectFn(spell_pri_prayer_of_mending_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL);
 979            }
 980        };
 981
 982        SpellScript* GetSpellScript() const override
 983        {
 984            return new spell_pri_prayer_of_mending_heal_SpellScript();
 985        }
 986};
 987
 988// 139 - Renew
 989class spell_pri_renew : public SpellScriptLoader
 990{
 991    public:
 992        spell_pri_renew() : SpellScriptLoader("spell_pri_renew") { }
 993
 994        class spell_pri_renew_AuraScript : public AuraScript
 995        {
 996            PrepareAuraScript(spell_pri_renew_AuraScript);
 997
 998            bool Validate(SpellInfo const* /*spellInfo*/) override
 999            {
1000                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_DIVINE_TOUCH))
1001                    return false;
1002                return true;
1003            }
1004
1005            bool Load() override
1006            {
1007                return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER;
1008            }
1009
1010            void HandleApplyEffect(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1011            {
1012                if (Unit* caster = GetCaster())
1013                {
1014                    // Divine Touch
1015                    if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_DIVINE_TOUCH_TALENT, EFFECT_0))
1016                    {
1017                        uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), aurEff->GetAmount(), DOT);
1018                        heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT);
1019                        int32 basepoints0 = CalculatePct(int32(heal) * aurEff->GetTotalTicks(), empoweredRenewAurEff->GetAmount());
1020                        caster->CastCustomSpell(GetTarget(), SPELL_PRIEST_DIVINE_TOUCH, &basepoints0, NULL, NULL, true, NULL, aurEff);
1021                    }
1022                }
1023            }
1024
1025            void Register() override
1026            {
1027                OnEffectApply += AuraEffectApplyFn(spell_pri_renew_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
1028            }
1029        };
1030
1031        AuraScript* GetAuraScript() const override
1032        {
1033            return new spell_pri_renew_AuraScript();
1034        }
1035};
1036
1037// 32379 - Shadow Word Death
1038class spell_pri_shadow_word_death : public SpellScriptLoader
1039{
1040    public:
1041        spell_pri_shadow_word_death() : SpellScriptLoader("spell_pri_shadow_word_death") { }
1042
1043        class spell_pri_shadow_word_death_SpellScript : public SpellScript
1044        {
1045            PrepareSpellScript(spell_pri_shadow_word_death_SpellScript);
1046
1047            void HandleDamage()
1048            {
1049                int32 damage = GetHitDamage();
1050
1051                // Pain and Suffering reduces damage
1052                if (AuraEffect* aurEff = GetCaster()->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_PAIN_AND_SUFFERING, EFFECT_1))
1053                    AddPct(damage, aurEff->GetAmount());
1054
1055                GetCaster()->CastCustomSpell(GetCaster(), SPELL_PRIEST_SHADOW_WORD_DEATH, &damage, nullptr, nullptr, true);
1056            }
1057
1058            void Register() override
1059            {
1060                OnHit += SpellHitFn(spell_pri_shadow_word_death_SpellScript::HandleDamage);
1061            }
1062        };
1063
1064        SpellScript* GetSpellScript() const override
1065        {
1066            return new spell_pri_shadow_word_death_SpellScript();
1067        }
1068};
1069
1070// 15473 - Shadowform
1071class spell_pri_shadowform : public SpellScriptLoader
1072{
1073    public:
1074        spell_pri_shadowform() : SpellScriptLoader("spell_pri_shadowform") { }
1075
1076        class spell_pri_shadowform_AuraScript : public AuraScript
1077        {
1078            PrepareAuraScript(spell_pri_shadowform_AuraScript);
1079
1080            bool Validate(SpellInfo const* /*spellInfo*/) override
1081            {
1082                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH) ||
1083                    !sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH))
1084                    return false;
1085                return true;
1086            }
1087
1088            void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1089            {
1090                GetTarget()->CastSpell(GetTarget(), GetTarget()->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOW) ? SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH : SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH, true);
1091            }
1092
1093            void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1094            {
1095                GetTarget()->RemoveAurasDueToSpell(GetTarget()->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOW) ? SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH : SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH);
1096            }
1097
1098            void Register() override
1099            {
1100                AfterEffectApply += AuraEffectApplyFn(spell_pri_shadowform_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
1101                AfterEffectRemove += AuraEffectRemoveFn(spell_pri_shadowform_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
1102            }
1103        };
1104
1105        AuraScript* GetAuraScript() const override
1106        {
1107            return new spell_pri_shadowform_AuraScript();
1108        }
1109};
1110
1111// 15286 - Vampiric Embrace
1112class spell_pri_vampiric_embrace : public SpellScriptLoader
1113{
1114    public:
1115        spell_pri_vampiric_embrace() : SpellScriptLoader("spell_pri_vampiric_embrace") { }
1116
1117        class spell_pri_vampiric_embrace_AuraScript : public AuraScript
1118        {
1119            PrepareAuraScript(spell_pri_vampiric_embrace_AuraScript);
1120
1121            bool Validate(SpellInfo const* /*spellInfo*/) override
1122            {
1123                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL))
1124                    return false;
1125                return true;
1126            }
1127
1128            bool CheckProc(ProcEventInfo& eventInfo)
1129            {
1130                // Not proc from Mind Sear
1131                return !(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x80000);
1132            }
1133
1134            void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
1135            {
1136                PreventDefaultAction();
1137                int32 self = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()));
1138                int32 team = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount() / 2));
1139
1140                GetTarget()->CastCustomSpell((Unit*)NULL, SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL, &team, &self, NULL, true, NULL, aurEff);
1141            }
1142
1143            void Register() override
1144            {
1145                DoCheckProc += AuraCheckProcFn(spell_pri_vampiric_embrace_AuraScript::CheckProc);
1146                OnEffectProc += AuraEffectProcFn(spell_pri_vampiric_embrace_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
1147            }
1148        };
1149
1150        AuraScript* GetAuraScript() const override
1151        {
1152            return new spell_pri_vampiric_embrace_AuraScript();
1153        }
1154};
1155
1156// 15290 - Vampiric Embrace (heal)
1157class spell_pri_vampiric_embrace_target : public SpellScriptLoader
1158{
1159    public:
1160        spell_pri_vampiric_embrace_target() : SpellScriptLoader("spell_pri_vampiric_embrace_target") { }
1161
1162        class spell_pri_vampiric_embrace_target_SpellScript : public SpellScript
1163        {
1164            PrepareSpellScript(spell_pri_vampiric_embrace_target_SpellScript);
1165
1166            void FilterTargets(std::list<WorldObject*>& unitList)
1167            {
1168                unitList.remove(GetCaster());
1169            }
1170
1171            void Register() override
1172            {
1173                OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_vampiric_embrace_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY);
1174            }
1175        };
1176
1177        SpellScript* GetSpellScript() const override
1178        {
1179            return new spell_pri_vampiric_embrace_target_SpellScript();
1180        }
1181};
1182
1183// 34914 - Vampiric Touch
1184class spell_pri_vampiric_touch : public SpellScriptLoader
1185{
1186    public:
1187        spell_pri_vampiric_touch() : SpellScriptLoader("spell_pri_vampiric_touch") { }
1188
1189        class spell_pri_vampiric_touch_AuraScript : public AuraScript
1190        {
1191            PrepareAuraScript(spell_pri_vampiric_touch_AuraScript);
1192
1193            bool Validate(SpellInfo const* /*spellInfo*/) override
1194            {
1195                if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL) ||
1196                    !sSpellMgr->GetSpellInfo(SPELL_GEN_REPLENISHMENT))
1197                    return false;
1198                return true;
1199            }
1200
1201            void HandleDispel(DispelInfo* /*dispelInfo*/)
1202            {
1203                if (Unit* caster = GetCaster())
1204                    if (Unit* target = GetUnitOwner())
1205                        if (AuraEffect const* aurEff = GetEffect(EFFECT_1))
1206                        {
1207                            int32 damage = aurEff->GetAmount() * 8;
1208                            // backfire damage
1209                            caster->CastCustomSpell(target, SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL, &damage, NULL, NULL, true, NULL, aurEff);
1210                        }
1211            }
1212
1213            bool CheckProc(ProcEventInfo& eventInfo)
1214            {
1215                return eventInfo.GetProcTarget() == GetCaster();
1216            }
1217
1218            void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
1219            {
1220                eventInfo.GetProcTarget()->CastSpell((Unit*)NULL, SPELL_GEN_REPLENISHMENT, true, NULL, aurEff);
1221            }
1222
1223            void Register() override
1224            {
1225                AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel);
1226                DoCheckProc += AuraCheckProcFn(spell_pri_vampiric_touch_AuraScript::CheckProc);
1227                OnEffectProc += AuraEffectProcFn(spell_pri_vampiric_touch_AuraScript::HandleEffectProc, EFFECT_2, SPELL_AURA_DUMMY);
1228            }
1229        };
1230
1231        AuraScript* GetAuraScript() const override
1232        {
1233            return new spell_pri_vampiric_touch_AuraScript();
1234        }
1235};
1236
1237void AddSC_priest_spell_scripts()
1238{
1239    new spell_pri_body_and_soul();
1240    new spell_pri_circle_of_healing();
1241    new spell_pri_dispel_magic();
1242    new spell_pri_divine_aegis();
1243    new spell_pri_divine_hymn();
1244    new spell_pri_glyph_of_prayer_of_healing();
1245    new spell_pri_hymn_of_hope();
1246    new spell_pri_improved_power_word_shield();
1247    new spell_pri_item_greater_heal_refund();
1248    new spell_pri_guardian_spirit();
1249    new spell_pri_leap_of_faith_effect_trigger();
1250    new spell_pri_lightwell_renew();
1251    new spell_pri_mana_burn();
1252    new spell_pri_mana_leech();
1253    new spell_pri_mind_sear();
1254    new spell_pri_pain_and_suffering_proc();
1255    new spell_pri_penance();
1256    new spell_pri_phantasm();
1257    new spell_pri_power_word_shield();
1258    new spell_pri_prayer_of_mending_heal();
1259    new spell_pri_renew();
1260    new spell_pri_shadow_word_death();
1261    new spell_pri_shadowform();
1262    new spell_pri_vampiric_embrace();
1263    new spell_pri_vampiric_embrace_target();
1264    new spell_pri_vampiric_touch();
1265}