PageRenderTime 133ms CodeModel.GetById 11ms app.highlight 108ms RepoModel.GetById 2ms app.codeStats 1ms

/src/server/scripts/Spells/spell_generic.cpp

https://gitlab.com/tkrokli/TrinityCore_434
C++ | 4156 lines | 3424 code | 585 blank | 147 comment | 325 complexity | 85ae9a833aac52d19732228c4733c1ef MD5 | raw file

Large files files are truncated, but you can click here to view the full 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_GENERIC which cannot be included in AI script file
  20 * of creature using it or can't be bound to any player class.
  21 * Ordered alphabetically using scriptname.
  22 * Scriptnames of files in this file should be prefixed with "spell_gen_"
  23 */
  24
  25#include "ScriptMgr.h"
  26#include "Battleground.h"
  27#include "Cell.h"
  28#include "CellImpl.h"
  29#include "GridNotifiers.h"
  30#include "GridNotifiersImpl.h"
  31#include "Group.h"
  32#include "InstanceScript.h"
  33#include "LFGMgr.h"
  34#include "Pet.h"
  35#include "ReputationMgr.h"
  36#include "SkillDiscovery.h"
  37#include "SpellHistory.h"
  38#include "SpellScript.h"
  39#include "SpellAuraEffects.h"
  40#include "Vehicle.h"
  41
  42class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader
  43{
  44    public:
  45        spell_gen_absorb0_hitlimit1() : SpellScriptLoader("spell_gen_absorb0_hitlimit1") { }
  46
  47        class spell_gen_absorb0_hitlimit1_AuraScript : public AuraScript
  48        {
  49            PrepareAuraScript(spell_gen_absorb0_hitlimit1_AuraScript);
  50
  51        public:
  52            spell_gen_absorb0_hitlimit1_AuraScript()
  53            {
  54                limit = 0;
  55            }
  56
  57        private:
  58            uint32 limit;
  59
  60            bool Load() override
  61            {
  62                // Max absorb stored in 1 dummy effect
  63                limit = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
  64                return true;
  65            }
  66
  67            void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& absorbAmount)
  68            {
  69                absorbAmount = std::min(limit, absorbAmount);
  70            }
  71
  72            void Register() override
  73            {
  74                OnEffectAbsorb += AuraEffectAbsorbFn(spell_gen_absorb0_hitlimit1_AuraScript::Absorb, EFFECT_0);
  75            }
  76        };
  77
  78        AuraScript* GetAuraScript() const override
  79        {
  80            return new spell_gen_absorb0_hitlimit1_AuraScript();
  81        }
  82};
  83
  84// 28764 - Adaptive Warding (Frostfire Regalia Set)
  85enum AdaptiveWarding
  86{
  87    SPELL_GEN_ADAPTIVE_WARDING_FIRE     = 28765,
  88    SPELL_GEN_ADAPTIVE_WARDING_NATURE   = 28768,
  89    SPELL_GEN_ADAPTIVE_WARDING_FROST    = 28766,
  90    SPELL_GEN_ADAPTIVE_WARDING_SHADOW   = 28769,
  91    SPELL_GEN_ADAPTIVE_WARDING_ARCANE   = 28770
  92};
  93
  94class spell_gen_adaptive_warding : public SpellScriptLoader
  95{
  96    public:
  97        spell_gen_adaptive_warding() : SpellScriptLoader("spell_gen_adaptive_warding") { }
  98
  99        class spell_gen_adaptive_warding_AuraScript : public AuraScript
 100        {
 101            PrepareAuraScript(spell_gen_adaptive_warding_AuraScript);
 102
 103            bool Validate(SpellInfo const* /*spellInfo*/) override
 104            {
 105                if (!sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_FIRE) ||
 106                    !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_NATURE) ||
 107                    !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_FROST) ||
 108                    !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_SHADOW) ||
 109                    !sSpellMgr->GetSpellInfo(SPELL_GEN_ADAPTIVE_WARDING_ARCANE))
 110                    return false;
 111                return true;
 112            }
 113
 114            bool CheckProc(ProcEventInfo& eventInfo)
 115            {
 116                if (eventInfo.GetDamageInfo()->GetSpellInfo()) // eventInfo.GetSpellInfo()
 117                    return false;
 118
 119                // find Mage Armor
 120                if (!GetTarget()->GetAuraEffect(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000, 0x0, 0x0))
 121                    return false;
 122
 123                switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask()))
 124                {
 125                    case SPELL_SCHOOL_NORMAL:
 126                    case SPELL_SCHOOL_HOLY:
 127                        return false;
 128                    default:
 129                        break;
 130                }
 131                return true;
 132            }
 133
 134            void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
 135            {
 136                PreventDefaultAction();
 137
 138                uint32 spellId = 0;
 139                switch (GetFirstSchoolInMask(eventInfo.GetSchoolMask()))
 140                {
 141                    case SPELL_SCHOOL_FIRE:
 142                        spellId = SPELL_GEN_ADAPTIVE_WARDING_FIRE;
 143                        break;
 144                    case SPELL_SCHOOL_NATURE:
 145                        spellId = SPELL_GEN_ADAPTIVE_WARDING_NATURE;
 146                        break;
 147                    case SPELL_SCHOOL_FROST:
 148                        spellId = SPELL_GEN_ADAPTIVE_WARDING_FROST;
 149                        break;
 150                    case SPELL_SCHOOL_SHADOW:
 151                        spellId = SPELL_GEN_ADAPTIVE_WARDING_SHADOW;
 152                        break;
 153                    case SPELL_SCHOOL_ARCANE:
 154                        spellId = SPELL_GEN_ADAPTIVE_WARDING_ARCANE;
 155                        break;
 156                    default:
 157                        return;
 158                }
 159                GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff);
 160            }
 161
 162            void Register() override
 163            {
 164                DoCheckProc += AuraCheckProcFn(spell_gen_adaptive_warding_AuraScript::CheckProc);
 165                OnEffectProc += AuraEffectProcFn(spell_gen_adaptive_warding_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
 166            }
 167        };
 168
 169        AuraScript* GetAuraScript() const override
 170        {
 171            return new spell_gen_adaptive_warding_AuraScript();
 172        }
 173};
 174
 175enum AlchemistStone
 176{
 177    ALECHEMIST_STONE_HEAL      = 21399,
 178    ALECHEMIST_STONE_MANA      = 21400,
 179};
 180
 181// 17619 - Alchemist Stone
 182class spell_gen_alchemist_stone : public SpellScriptLoader
 183{
 184    public:
 185        spell_gen_alchemist_stone() : SpellScriptLoader("spell_gen_alchemist_stone") { }
 186
 187        class spell_gen_alchemist_stone_AuraScript : public AuraScript
 188        {
 189            PrepareAuraScript(spell_gen_alchemist_stone_AuraScript);
 190
 191            bool Validate(SpellInfo const* /*spellInfo*/) override
 192            {
 193                if (!sSpellMgr->GetSpellInfo(ALECHEMIST_STONE_HEAL) ||
 194                    !sSpellMgr->GetSpellInfo(ALECHEMIST_STONE_MANA))
 195                    return false;
 196                return true;
 197            }
 198
 199            bool CheckProc(ProcEventInfo& eventInfo)
 200            {
 201                return eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_POTION;
 202            }
 203
 204            void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
 205            {
 206                PreventDefaultAction();
 207
 208                uint32 spellId = 0;
 209                int32 bp = int32(eventInfo.GetDamageInfo()->GetDamage() * 0.4f);
 210
 211                if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_HEAL))
 212                    spellId = ALECHEMIST_STONE_HEAL;
 213                else if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_ENERGIZE))
 214                    spellId = ALECHEMIST_STONE_MANA;
 215
 216                if (!spellId)
 217                    return;
 218
 219                GetTarget()->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, NULL, aurEff);
 220            }
 221
 222
 223            void Register() override
 224            {
 225                DoCheckProc += AuraCheckProcFn(spell_gen_alchemist_stone_AuraScript::CheckProc);
 226                OnEffectProc += AuraEffectProcFn(spell_gen_alchemist_stone_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
 227            }
 228        };
 229
 230        AuraScript* GetAuraScript() const override
 231        {
 232            return new spell_gen_alchemist_stone_AuraScript();
 233        }
 234};
 235
 236class spell_gen_allow_cast_from_item_only : public SpellScriptLoader
 237{
 238    public:
 239        spell_gen_allow_cast_from_item_only() : SpellScriptLoader("spell_gen_allow_cast_from_item_only") { }
 240
 241        class spell_gen_allow_cast_from_item_only_SpellScript : public SpellScript
 242        {
 243            PrepareSpellScript(spell_gen_allow_cast_from_item_only_SpellScript);
 244
 245            SpellCastResult CheckRequirement()
 246            {
 247                if (!GetCastItem())
 248                    return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
 249                return SPELL_CAST_OK;
 250            }
 251
 252            void Register() override
 253            {
 254                OnCheckCast += SpellCheckCastFn(spell_gen_allow_cast_from_item_only_SpellScript::CheckRequirement);
 255            }
 256        };
 257
 258        SpellScript* GetSpellScript() const override
 259        {
 260            return new spell_gen_allow_cast_from_item_only_SpellScript();
 261        }
 262};
 263
 264enum AnimalBloodPoolSpell
 265{
 266    SPELL_ANIMAL_BLOOD      = 46221,
 267    SPELL_SPAWN_BLOOD_POOL  = 63471
 268};
 269
 270class spell_gen_animal_blood : public SpellScriptLoader
 271{
 272    public:
 273        spell_gen_animal_blood() : SpellScriptLoader("spell_gen_animal_blood") { }
 274
 275        class spell_gen_animal_blood_AuraScript : public AuraScript
 276        {
 277            PrepareAuraScript(spell_gen_animal_blood_AuraScript);
 278
 279            bool Validate(SpellInfo const* /*spellInfo*/) override
 280            {
 281                if (!sSpellMgr->GetSpellInfo(SPELL_SPAWN_BLOOD_POOL))
 282                    return false;
 283                return true;
 284            }
 285
 286            void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
 287            {
 288                // Remove all auras with spell id 46221, except the one currently being applied
 289                while (Aura* aur = GetUnitOwner()->GetOwnedAura(SPELL_ANIMAL_BLOOD, ObjectGuid::Empty, ObjectGuid::Empty, 0, GetAura()))
 290                    GetUnitOwner()->RemoveOwnedAura(aur);
 291            }
 292
 293            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
 294            {
 295                if (Unit* owner = GetUnitOwner())
 296                    if (owner->IsInWater())
 297                        owner->CastSpell(owner, SPELL_SPAWN_BLOOD_POOL, true);
 298            }
 299
 300            void Register() override
 301            {
 302                AfterEffectApply += AuraEffectRemoveFn(spell_gen_animal_blood_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
 303                AfterEffectRemove += AuraEffectRemoveFn(spell_gen_animal_blood_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
 304            }
 305        };
 306
 307        AuraScript* GetAuraScript() const override
 308        {
 309            return new spell_gen_animal_blood_AuraScript();
 310        }
 311};
 312
 313// 41337 Aura of Anger
 314class spell_gen_aura_of_anger : public SpellScriptLoader
 315{
 316    public:
 317        spell_gen_aura_of_anger() : SpellScriptLoader("spell_gen_aura_of_anger") { }
 318
 319        class spell_gen_aura_of_anger_AuraScript : public AuraScript
 320        {
 321            PrepareAuraScript(spell_gen_aura_of_anger_AuraScript);
 322
 323            void HandleEffectPeriodicUpdate(AuraEffect* aurEff)
 324            {
 325                if (AuraEffect* aurEff1 = aurEff->GetBase()->GetEffect(EFFECT_1))
 326                    aurEff1->ChangeAmount(aurEff1->GetAmount() + 5);
 327                aurEff->SetAmount(100 * aurEff->GetTickNumber());
 328            }
 329
 330            void Register() override
 331            {
 332                OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_aura_of_anger_AuraScript::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
 333            }
 334        };
 335
 336        AuraScript* GetAuraScript() const override
 337        {
 338            return new spell_gen_aura_of_anger_AuraScript();
 339        }
 340};
 341
 342enum ServiceUniform
 343{
 344    // Spells
 345    SPELL_SERVICE_UNIFORM       = 71450,
 346
 347    // Models
 348    MODEL_GOBLIN_MALE           = 31002,
 349    MODEL_GOBLIN_FEMALE         = 31003
 350};
 351
 352class spell_gen_aura_service_uniform : public SpellScriptLoader
 353{
 354    public:
 355        spell_gen_aura_service_uniform() : SpellScriptLoader("spell_gen_aura_service_uniform") { }
 356
 357        class spell_gen_aura_service_uniform_AuraScript : public AuraScript
 358        {
 359            PrepareAuraScript(spell_gen_aura_service_uniform_AuraScript);
 360
 361            bool Validate(SpellInfo const* /*spellInfo*/) override
 362            {
 363                if (!sSpellMgr->GetSpellInfo(SPELL_SERVICE_UNIFORM))
 364                    return false;
 365                return true;
 366            }
 367
 368            void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
 369            {
 370                // Apply model goblin
 371                Unit* target = GetTarget();
 372                if (target->GetTypeId() == TYPEID_PLAYER)
 373                {
 374                    if (target->getGender() == GENDER_MALE)
 375                        target->SetDisplayId(MODEL_GOBLIN_MALE);
 376                    else
 377                        target->SetDisplayId(MODEL_GOBLIN_FEMALE);
 378                }
 379            }
 380
 381            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
 382            {
 383                Unit* target = GetTarget();
 384                if (target->GetTypeId() == TYPEID_PLAYER)
 385                    target->RestoreDisplayId();
 386            }
 387
 388            void Register() override
 389            {
 390                AfterEffectApply += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
 391                AfterEffectRemove += AuraEffectRemoveFn(spell_gen_aura_service_uniform_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
 392            }
 393        };
 394
 395        AuraScript* GetAuraScript() const override
 396        {
 397            return new spell_gen_aura_service_uniform_AuraScript();
 398        }
 399};
 400
 401class spell_gen_av_drekthar_presence : public SpellScriptLoader
 402{
 403    public:
 404        spell_gen_av_drekthar_presence() : SpellScriptLoader("spell_gen_av_drekthar_presence") { }
 405
 406        class spell_gen_av_drekthar_presence_AuraScript : public AuraScript
 407        {
 408            PrepareAuraScript(spell_gen_av_drekthar_presence_AuraScript);
 409
 410            bool CheckAreaTarget(Unit* target)
 411            {
 412                switch (target->GetEntry())
 413                {
 414                    // alliance
 415                    case 14762: // Dun Baldar North Marshal
 416                    case 14763: // Dun Baldar South Marshal
 417                    case 14764: // Icewing Marshal
 418                    case 14765: // Stonehearth Marshal
 419                    case 11948: // Vandar Stormspike
 420                    // horde
 421                    case 14772: // East Frostwolf Warmaster
 422                    case 14776: // Tower Point Warmaster
 423                    case 14773: // Iceblood Warmaster
 424                    case 14777: // West Frostwolf Warmaster
 425                    case 11946: // Drek'thar
 426                        return true;
 427                    default:
 428                        return false;
 429                }
 430            }
 431
 432            void Register() override
 433            {
 434                DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_gen_av_drekthar_presence_AuraScript::CheckAreaTarget);
 435            }
 436        };
 437
 438        AuraScript* GetAuraScript() const override
 439        {
 440            return new spell_gen_av_drekthar_presence_AuraScript();
 441        }
 442};
 443
 444enum GenericBandage
 445{
 446    SPELL_RECENTLY_BANDAGED     = 11196
 447};
 448
 449class spell_gen_bandage : public SpellScriptLoader
 450{
 451    public:
 452        spell_gen_bandage() : SpellScriptLoader("spell_gen_bandage") { }
 453
 454        class spell_gen_bandage_SpellScript : public SpellScript
 455        {
 456            PrepareSpellScript(spell_gen_bandage_SpellScript);
 457
 458            bool Validate(SpellInfo const* /*spellInfo*/) override
 459            {
 460                if (!sSpellMgr->GetSpellInfo(SPELL_RECENTLY_BANDAGED))
 461                    return false;
 462                return true;
 463            }
 464
 465            SpellCastResult CheckCast()
 466            {
 467                if (Unit* target = GetExplTargetUnit())
 468                {
 469                    if (target->HasAura(SPELL_RECENTLY_BANDAGED))
 470                        return SPELL_FAILED_TARGET_AURASTATE;
 471                }
 472                return SPELL_CAST_OK;
 473            }
 474
 475            void HandleScript()
 476            {
 477                if (Unit* target = GetHitUnit())
 478                    GetCaster()->CastSpell(target, SPELL_RECENTLY_BANDAGED, true);
 479            }
 480
 481            void Register() override
 482            {
 483                OnCheckCast += SpellCheckCastFn(spell_gen_bandage_SpellScript::CheckCast);
 484                AfterHit += SpellHitFn(spell_gen_bandage_SpellScript::HandleScript);
 485            }
 486        };
 487
 488        SpellScript* GetSpellScript() const override
 489        {
 490            return new spell_gen_bandage_SpellScript();
 491        }
 492};
 493
 494enum Bonked
 495{
 496    SPELL_BONKED            = 62991,
 497    SPELL_FOAM_SWORD_DEFEAT = 62994,
 498    SPELL_ON_GUARD          = 62972
 499};
 500
 501class spell_gen_bonked : public SpellScriptLoader
 502{
 503    public:
 504        spell_gen_bonked() : SpellScriptLoader("spell_gen_bonked") { }
 505
 506        class spell_gen_bonked_SpellScript : public SpellScript
 507        {
 508            PrepareSpellScript(spell_gen_bonked_SpellScript);
 509
 510            void HandleScript(SpellEffIndex /*effIndex*/)
 511            {
 512                if (Player* target = GetHitPlayer())
 513                {
 514                    Aura const* aura = GetHitAura();
 515                    if (!(aura && aura->GetStackAmount() == 3))
 516                        return;
 517
 518                    target->CastSpell(target, SPELL_FOAM_SWORD_DEFEAT, true);
 519                    target->RemoveAurasDueToSpell(SPELL_BONKED);
 520
 521                    if (Aura const* auraOnGuard = target->GetAura(SPELL_ON_GUARD))
 522                    {
 523                        if (Item* item = target->GetItemByGuid(auraOnGuard->GetCastItemGUID()))
 524                            target->DestroyItemCount(item->GetEntry(), 1, true);
 525                    }
 526                }
 527            }
 528
 529            void Register() override
 530            {
 531                OnEffectHitTarget += SpellEffectFn(spell_gen_bonked_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
 532            }
 533        };
 534
 535        SpellScript* GetSpellScript() const override
 536        {
 537            return new spell_gen_bonked_SpellScript();
 538        }
 539};
 540
 541/* DOCUMENTATION: Break-Shield spells
 542    Break-Shield spells can be classified in three groups:
 543
 544        - Spells on vehicle bar used by players:
 545            + EFFECT_0: SCRIPT_EFFECT
 546            + EFFECT_1: NONE
 547            + EFFECT_2: NONE
 548        - Spells cast by players triggered by script:
 549            + EFFECT_0: SCHOOL_DAMAGE
 550            + EFFECT_1: SCRIPT_EFFECT
 551            + EFFECT_2: FORCE_CAST
 552        - Spells cast by NPCs on players:
 553            + EFFECT_0: SCHOOL_DAMAGE
 554            + EFFECT_1: SCRIPT_EFFECT
 555            + EFFECT_2: NONE
 556
 557    In the following script we handle the SCRIPT_EFFECT for effIndex EFFECT_0 and EFFECT_1.
 558        - When handling EFFECT_0 we're in the "Spells on vehicle bar used by players" case
 559          and we'll trigger "Spells cast by players triggered by script"
 560        - When handling EFFECT_1 we're in the "Spells cast by players triggered by script"
 561          or "Spells cast by NPCs on players" so we'll search for the first defend layer and drop it.
 562*/
 563
 564enum BreakShieldSpells
 565{
 566    SPELL_BREAK_SHIELD_DAMAGE_2K                 = 62626,
 567    SPELL_BREAK_SHIELD_DAMAGE_10K                = 64590,
 568
 569    SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS    = 62575, // Also on ToC5 mounts
 570    SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE = 64595,
 571    SPELL_BREAK_SHIELD_TRIGGER_UNK               = 66480
 572};
 573
 574class spell_gen_break_shield: public SpellScriptLoader
 575{
 576    public:
 577        spell_gen_break_shield(const char* name) : SpellScriptLoader(name) { }
 578
 579        class spell_gen_break_shield_SpellScript : public SpellScript
 580        {
 581            PrepareSpellScript(spell_gen_break_shield_SpellScript);
 582
 583            void HandleScriptEffect(SpellEffIndex effIndex)
 584            {
 585                Unit* target = GetHitUnit();
 586
 587                switch (effIndex)
 588                {
 589                    case EFFECT_0: // On spells wich trigger the damaging spell (and also the visual)
 590                    {
 591                        uint32 spellId;
 592
 593                        switch (GetSpellInfo()->Id)
 594                        {
 595                            case SPELL_BREAK_SHIELD_TRIGGER_UNK:
 596                            case SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE:
 597                                spellId = SPELL_BREAK_SHIELD_DAMAGE_10K;
 598                                break;
 599                            case SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS:
 600                                spellId = SPELL_BREAK_SHIELD_DAMAGE_2K;
 601                                break;
 602                            default:
 603                                return;
 604                        }
 605
 606                        if (Unit* rider = GetCaster()->GetCharmer())
 607                            rider->CastSpell(target, spellId, false);
 608                        else
 609                            GetCaster()->CastSpell(target, spellId, false);
 610                        break;
 611                    }
 612                    case EFFECT_1: // On damaging spells, for removing a defend layer
 613                    {
 614                        Unit::AuraApplicationMap const& auras = target->GetAppliedAuras();
 615                        for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
 616                        {
 617                            if (Aura* aura = itr->second->GetBase())
 618                            {
 619                                SpellInfo const* auraInfo = aura->GetSpellInfo();
 620                                if (auraInfo && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN))
 621                                {
 622                                    aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL);
 623                                    // Remove dummys from rider (Necessary for updating visual shields)
 624                                    if (Unit* rider = target->GetCharmer())
 625                                        if (Aura* defend = rider->GetAura(aura->GetId()))
 626                                            defend->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL);
 627                                    break;
 628                                }
 629                            }
 630                        }
 631                        break;
 632                    }
 633                    default:
 634                        break;
 635                }
 636            }
 637
 638            void Register() override
 639            {
 640                OnEffectHitTarget += SpellEffectFn(spell_gen_break_shield_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT);
 641            }
 642        };
 643
 644        SpellScript* GetSpellScript() const override
 645        {
 646            return new spell_gen_break_shield_SpellScript();
 647        }
 648};
 649
 650// 46394 Brutallus Burn
 651class spell_gen_burn_brutallus : public SpellScriptLoader
 652{
 653    public:
 654        spell_gen_burn_brutallus() : SpellScriptLoader("spell_gen_burn_brutallus") { }
 655
 656        class spell_gen_burn_brutallus_AuraScript : public AuraScript
 657        {
 658            PrepareAuraScript(spell_gen_burn_brutallus_AuraScript);
 659
 660            void HandleEffectPeriodicUpdate(AuraEffect* aurEff)
 661            {
 662                if (aurEff->GetTickNumber() % 11 == 0)
 663                    aurEff->SetAmount(aurEff->GetAmount() * 2);
 664            }
 665
 666            void Register() override
 667            {
 668                OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_gen_burn_brutallus_AuraScript::HandleEffectPeriodicUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
 669            }
 670        };
 671
 672        AuraScript* GetAuraScript() const override
 673        {
 674            return new spell_gen_burn_brutallus_AuraScript();
 675        }
 676};
 677
 678enum CannibalizeSpells
 679{
 680    SPELL_CANNIBALIZE_TRIGGERED = 20578
 681};
 682
 683class spell_gen_cannibalize : public SpellScriptLoader
 684{
 685    public:
 686        spell_gen_cannibalize() : SpellScriptLoader("spell_gen_cannibalize") { }
 687
 688        class spell_gen_cannibalize_SpellScript : public SpellScript
 689        {
 690            PrepareSpellScript(spell_gen_cannibalize_SpellScript);
 691
 692            bool Validate(SpellInfo const* /*spellInfo*/) override
 693            {
 694                if (!sSpellMgr->GetSpellInfo(SPELL_CANNIBALIZE_TRIGGERED))
 695                    return false;
 696                return true;
 697            }
 698
 699            SpellCastResult CheckIfCorpseNear()
 700            {
 701                Unit* caster = GetCaster();
 702                float max_range = GetSpellInfo()->GetMaxRange(false);
 703                WorldObject* result = NULL;
 704                // search for nearby enemy corpse in range
 705                Trinity::AnyDeadUnitSpellTargetInRangeCheck check(caster, max_range, GetSpellInfo(), TARGET_CHECK_ENEMY);
 706                Trinity::WorldObjectSearcher<Trinity::AnyDeadUnitSpellTargetInRangeCheck> searcher(caster, result, check);
 707                caster->GetMap()->VisitFirstFound(caster->m_positionX, caster->m_positionY, max_range, searcher);
 708                if (!result)
 709                    return SPELL_FAILED_NO_EDIBLE_CORPSES;
 710                return SPELL_CAST_OK;
 711            }
 712
 713            void HandleDummy(SpellEffIndex /*effIndex*/)
 714            {
 715                GetCaster()->CastSpell(GetCaster(), SPELL_CANNIBALIZE_TRIGGERED, false);
 716            }
 717
 718            void Register() override
 719            {
 720                OnEffectHit += SpellEffectFn(spell_gen_cannibalize_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
 721                OnCheckCast += SpellCheckCastFn(spell_gen_cannibalize_SpellScript::CheckIfCorpseNear);
 722            }
 723        };
 724
 725        SpellScript* GetSpellScript() const override
 726        {
 727            return new spell_gen_cannibalize_SpellScript();
 728        }
 729};
 730
 731enum ChaosBlast
 732{
 733    SPELL_CHAOS_BLAST   = 37675
 734};
 735
 736class spell_gen_chaos_blast : public SpellScriptLoader
 737{
 738    public:
 739        spell_gen_chaos_blast() : SpellScriptLoader("spell_gen_chaos_blast") { }
 740
 741        class spell_gen_chaos_blast_SpellScript : public SpellScript
 742        {
 743            PrepareSpellScript(spell_gen_chaos_blast_SpellScript);
 744
 745            bool Validate(SpellInfo const* /*spellInfo*/) override
 746            {
 747                if (!sSpellMgr->GetSpellInfo(SPELL_CHAOS_BLAST))
 748                    return false;
 749                return true;
 750            }
 751            void HandleDummy(SpellEffIndex /* effIndex */)
 752            {
 753                int32 basepoints0 = 100;
 754                Unit* caster = GetCaster();
 755                if (Unit* target = GetHitUnit())
 756                    caster->CastCustomSpell(target, SPELL_CHAOS_BLAST, &basepoints0, NULL, NULL, true);
 757            }
 758
 759            void Register() override
 760            {
 761                OnEffectHitTarget += SpellEffectFn(spell_gen_chaos_blast_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
 762            }
 763        };
 764
 765        SpellScript* GetSpellScript() const override
 766        {
 767            return new spell_gen_chaos_blast_SpellScript();
 768        }
 769};
 770
 771enum Clone
 772{
 773    SPELL_NIGHTMARE_FIGMENT_MIRROR_IMAGE        = 57528
 774};
 775
 776class spell_gen_clone : public SpellScriptLoader
 777{
 778    public:
 779        spell_gen_clone() : SpellScriptLoader("spell_gen_clone") { }
 780
 781        class spell_gen_clone_SpellScript : public SpellScript
 782        {
 783            PrepareSpellScript(spell_gen_clone_SpellScript);
 784
 785            void HandleScriptEffect(SpellEffIndex effIndex)
 786            {
 787                PreventHitDefaultEffect(effIndex);
 788                GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
 789            }
 790
 791            void Register() override
 792            {
 793                if (m_scriptSpellId == SPELL_NIGHTMARE_FIGMENT_MIRROR_IMAGE)
 794                {
 795                    OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_DUMMY);
 796                    OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_DUMMY);
 797                }
 798                else
 799                {
 800                    OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
 801                    OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
 802                }
 803            }
 804        };
 805
 806        SpellScript* GetSpellScript() const override
 807        {
 808            return new spell_gen_clone_SpellScript();
 809        }
 810};
 811
 812enum CloneWeaponSpells
 813{
 814    SPELL_COPY_WEAPON_AURA       = 41054,
 815    SPELL_COPY_WEAPON_2_AURA     = 63418,
 816    SPELL_COPY_WEAPON_3_AURA     = 69893,
 817
 818    SPELL_COPY_OFFHAND_AURA      = 45205,
 819    SPELL_COPY_OFFHAND_2_AURA    = 69896,
 820
 821    SPELL_COPY_RANGED_AURA       = 57594
 822};
 823
 824class spell_gen_clone_weapon : public SpellScriptLoader
 825{
 826    public:
 827        spell_gen_clone_weapon() : SpellScriptLoader("spell_gen_clone_weapon") { }
 828
 829        class spell_gen_clone_weapon_SpellScript : public SpellScript
 830        {
 831            PrepareSpellScript(spell_gen_clone_weapon_SpellScript);
 832
 833            void HandleScriptEffect(SpellEffIndex effIndex)
 834            {
 835                PreventHitDefaultEffect(effIndex);
 836                GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
 837            }
 838
 839            void Register() override
 840            {
 841                OnEffectHitTarget += SpellEffectFn(spell_gen_clone_weapon_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
 842            }
 843        };
 844
 845        SpellScript* GetSpellScript() const override
 846        {
 847            return new spell_gen_clone_weapon_SpellScript();
 848        }
 849};
 850
 851class spell_gen_clone_weapon_aura : public SpellScriptLoader
 852{
 853    public:
 854        spell_gen_clone_weapon_aura() : SpellScriptLoader("spell_gen_clone_weapon_aura") { }
 855
 856        class spell_gen_clone_weapon_auraScript : public AuraScript
 857        {
 858            PrepareAuraScript(spell_gen_clone_weapon_auraScript);
 859
 860        public:
 861            spell_gen_clone_weapon_auraScript()
 862            {
 863                prevItem = 0;
 864            }
 865
 866        private:
 867            bool Validate(SpellInfo const* /*spellInfo*/) override
 868            {
 869                if (!sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_AURA) ||
 870                    !sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_2_AURA) ||
 871                    !sSpellMgr->GetSpellInfo(SPELL_COPY_WEAPON_3_AURA) ||
 872                    !sSpellMgr->GetSpellInfo(SPELL_COPY_OFFHAND_AURA) ||
 873                    !sSpellMgr->GetSpellInfo(SPELL_COPY_OFFHAND_2_AURA) ||
 874                    !sSpellMgr->GetSpellInfo(SPELL_COPY_RANGED_AURA))
 875                    return false;
 876                return true;
 877            }
 878
 879            void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
 880            {
 881                Unit* caster = GetCaster();
 882                Unit* target = GetTarget();
 883                if (!caster)
 884                    return;
 885
 886                switch (GetSpellInfo()->Id)
 887                {
 888                    case SPELL_COPY_WEAPON_AURA:
 889                    case SPELL_COPY_WEAPON_2_AURA:
 890                    case SPELL_COPY_WEAPON_3_AURA:
 891                    {
 892                        prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID);
 893
 894                        if (Player* player = caster->ToPlayer())
 895                        {
 896                            if (Item* mainItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
 897                                target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, mainItem->GetEntry());
 898                        }
 899                        else
 900                            target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID));
 901                        break;
 902                    }
 903                    case SPELL_COPY_OFFHAND_AURA:
 904                    case SPELL_COPY_OFFHAND_2_AURA:
 905                    {
 906                        prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 1;
 907
 908                        if (Player* player = caster->ToPlayer())
 909                        {
 910                            if (Item* offItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
 911                                target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, offItem->GetEntry());
 912                        }
 913                        else
 914                            target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1));
 915                        break;
 916                    }
 917                    case SPELL_COPY_RANGED_AURA:
 918                    {
 919                        prevItem = target->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID) + 2;
 920
 921                        if (Player* player = caster->ToPlayer())
 922                        {
 923                            if (Item* rangedItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED))
 924                                target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, rangedItem->GetEntry());
 925                        }
 926                        else
 927                            target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2));
 928                        break;
 929                    }
 930                    default:
 931                        break;
 932                }
 933            }
 934
 935            void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
 936            {
 937                Unit* target = GetTarget();
 938
 939                switch (GetSpellInfo()->Id)
 940                {
 941                    case SPELL_COPY_WEAPON_AURA:
 942                    case SPELL_COPY_WEAPON_2_AURA:
 943                    case SPELL_COPY_WEAPON_3_AURA:
 944                        target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, prevItem);
 945                        break;
 946                    case SPELL_COPY_OFFHAND_AURA:
 947                    case SPELL_COPY_OFFHAND_2_AURA:
 948                        target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, prevItem);
 949                        break;
 950                    case SPELL_COPY_RANGED_AURA:
 951                        target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, prevItem);
 952                        break;
 953                    default:
 954                        break;
 955                }
 956            }
 957
 958            void Register() override
 959            {
 960                OnEffectApply += AuraEffectApplyFn(spell_gen_clone_weapon_auraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
 961                OnEffectRemove += AuraEffectRemoveFn(spell_gen_clone_weapon_auraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
 962            }
 963
 964        private:
 965            uint32 prevItem;
 966        };
 967
 968        AuraScript* GetAuraScript() const override
 969        {
 970            return new spell_gen_clone_weapon_auraScript();
 971        }
 972};
 973
 974class spell_gen_count_pct_from_max_hp : public SpellScriptLoader
 975{
 976    public:
 977        spell_gen_count_pct_from_max_hp(char const* name, int32 damagePct = 0) : SpellScriptLoader(name), _damagePct(damagePct) { }
 978
 979        class spell_gen_count_pct_from_max_hp_SpellScript : public SpellScript
 980        {
 981            PrepareSpellScript(spell_gen_count_pct_from_max_hp_SpellScript);
 982
 983        public:
 984            spell_gen_count_pct_from_max_hp_SpellScript(int32 damagePct) : SpellScript(), _damagePct(damagePct) { }
 985
 986            void RecalculateDamage()
 987            {
 988                if (!_damagePct)
 989                    _damagePct = GetHitDamage();
 990
 991                SetHitDamage(GetHitUnit()->CountPctFromMaxHealth(_damagePct));
 992            }
 993
 994            void Register() override
 995            {
 996                OnHit += SpellHitFn(spell_gen_count_pct_from_max_hp_SpellScript::RecalculateDamage);
 997            }
 998
 999        private:
1000            int32 _damagePct;
1001        };
1002
1003        SpellScript* GetSpellScript() const override
1004        {
1005            return new spell_gen_count_pct_from_max_hp_SpellScript(_damagePct);
1006        }
1007
1008    private:
1009        int32 _damagePct;
1010};
1011
1012// 63845 - Create Lance
1013enum CreateLanceSpells
1014{
1015    SPELL_CREATE_LANCE_ALLIANCE = 63914,
1016    SPELL_CREATE_LANCE_HORDE    = 63919
1017};
1018
1019class spell_gen_create_lance : public SpellScriptLoader
1020{
1021    public:
1022        spell_gen_create_lance() : SpellScriptLoader("spell_gen_create_lance") { }
1023
1024        class spell_gen_create_lance_SpellScript : public SpellScript
1025        {
1026            PrepareSpellScript(spell_gen_create_lance_SpellScript);
1027
1028            bool Validate(SpellInfo const* /*spellInfo*/) override
1029            {
1030                if (!sSpellMgr->GetSpellInfo(SPELL_CREATE_LANCE_ALLIANCE) ||
1031                    !sSpellMgr->GetSpellInfo(SPELL_CREATE_LANCE_HORDE))
1032                    return false;
1033                return true;
1034            }
1035
1036            void HandleScript(SpellEffIndex effIndex)
1037            {
1038                PreventHitDefaultEffect(effIndex);
1039
1040                if (Player* target = GetHitPlayer())
1041                {
1042                    if (target->GetTeam() == ALLIANCE)
1043                        GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_ALLIANCE, true);
1044                    else
1045                        GetCaster()->CastSpell(target, SPELL_CREATE_LANCE_HORDE, true);
1046                }
1047            }
1048
1049            void Register() override
1050            {
1051                OnEffectHitTarget += SpellEffectFn(spell_gen_create_lance_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
1052            }
1053        };
1054
1055        SpellScript* GetSpellScript() const override
1056        {
1057            return new spell_gen_create_lance_SpellScript();
1058        }
1059};
1060
1061class spell_gen_creature_permanent_feign_death : public SpellScriptLoader
1062{
1063    public:
1064        spell_gen_creature_permanent_feign_death() : SpellScriptLoader("spell_gen_creature_permanent_feign_death") { }
1065
1066        class spell_gen_creature_permanent_feign_death_AuraScript : public AuraScript
1067        {
1068            PrepareAuraScript(spell_gen_creature_permanent_feign_death_AuraScript);
1069
1070            void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1071            {
1072                Unit* target = GetTarget();
1073                target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
1074                target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
1075
1076                if (target->GetTypeId() == TYPEID_UNIT)
1077                    target->ToCreature()->SetReactState(REACT_PASSIVE);
1078            }
1079
1080            void Register() override
1081            {
1082                OnEffectApply += AuraEffectApplyFn(spell_gen_creature_permanent_feign_death_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
1083            }
1084        };
1085
1086        AuraScript* GetAuraScript() const override
1087        {
1088            return new spell_gen_creature_permanent_feign_death_AuraScript();
1089        }
1090};
1091
1092enum DalaranDisguiseSpells
1093{
1094    SPELL_SUNREAVER_DISGUISE_TRIGGER       = 69672,
1095    SPELL_SUNREAVER_DISGUISE_FEMALE        = 70973,
1096    SPELL_SUNREAVER_DISGUISE_MALE          = 70974,
1097
1098    SPELL_SILVER_COVENANT_DISGUISE_TRIGGER = 69673,
1099    SPELL_SILVER_COVENANT_DISGUISE_FEMALE  = 70971,
1100    SPELL_SILVER_COVENANT_DISGUISE_MALE    = 70972
1101};
1102
1103class spell_gen_dalaran_disguise : public SpellScriptLoader
1104{
1105    public:
1106        spell_gen_dalaran_disguise(const char* name) : SpellScriptLoader(name) { }
1107
1108        class spell_gen_dalaran_disguise_SpellScript : public SpellScript
1109        {
1110            PrepareSpellScript(spell_gen_dalaran_disguise_SpellScript);
1111
1112            bool Validate(SpellInfo const* spellInfo) override
1113            {
1114                switch (spellInfo->Id)
1115                {
1116                    case SPELL_SUNREAVER_DISGUISE_TRIGGER:
1117                        if (!sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_FEMALE) ||
1118                            !sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_MALE))
1119                            return false;
1120                        break;
1121                    case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER:
1122                        if (!sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) ||
1123                            !sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_MALE))
1124                            return false;
1125                        break;
1126                }
1127                return true;
1128            }
1129
1130            void HandleScript(SpellEffIndex /*effIndex*/)
1131            {
1132                if (Player* player = GetHitPlayer())
1133                {
1134                    uint8 gender = player->getGender();
1135
1136                    uint32 spellId = GetSpellInfo()->Id;
1137
1138                    switch (spellId)
1139                    {
1140                        case SPELL_SUNREAVER_DISGUISE_TRIGGER:
1141                            spellId = gender ? SPELL_SUNREAVER_DISGUISE_FEMALE : SPELL_SUNREAVER_DISGUISE_MALE;
1142                            break;
1143                        case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER:
1144                            spellId = gender ? SPELL_SILVER_COVENANT_DISGUISE_FEMALE : SPELL_SILVER_COVENANT_DISGUISE_MALE;
1145                            break;
1146                        default:
1147                            break;
1148                    }
1149
1150                    GetCaster()->CastSpell(player, spellId, true);
1151                }
1152            }
1153
1154            void Register() override
1155            {
1156                OnEffectHitTarget += SpellEffectFn(spell_gen_dalaran_disguise_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
1157            }
1158        };
1159
1160        SpellScript* GetSpellScript() const override
1161        {
1162            return new spell_gen_dalaran_disguise_SpellScript();
1163        }
1164};
1165
1166enum DefendVisuals
1167{
1168    SPELL_VISUAL_SHIELD_1 = 63130,
1169    SPELL_VISUAL_SHIELD_2 = 63131,
1170    SPELL_VISUAL_SHIELD_3 = 63132
1171};
1172
1173class spell_gen_defend : public SpellScriptLoader
1174{
1175    public:
1176        spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { }
1177
1178        class spell_gen_defend_AuraScript : public AuraScript
1179        {
1180            PrepareAuraScript(spell_gen_defend_AuraScript);
1181
1182            bool Validate(SpellInfo const* /*spellInfo*/) override
1183            {
1184                if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_1))
1185                    return false;
1186                if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_2))
1187                    return false;
1188                if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_3))
1189                    return false;
1190                return true;
1191            }
1192
1193            void RefreshVisualShields(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
1194            {
1195                if (GetCaster())
1196                {
1197                    Unit* target = GetTarget();
1198
1199                    for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i)
1200                        target->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i);
1201
1202                    target->CastSpell(target, SPELL_VISUAL_SHIELD_1 + GetAura()->GetStackAmount() - 1, true, NULL, aurEff);
1203                }
1204                else
1205                    GetTarget()->RemoveAurasDueToSpell(GetId());
1206            }
1207
1208            void RemoveVisualShields(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1209            {
1210                for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i)
1211                    GetTarget()->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i);
1212            }
1213
1214            void RemoveDummyFromDriver(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
1215            {
1216                if (Unit* caster = GetCaster())
1217                    if (TempSummon* vehicle = caster->ToTempSummon())
1218                        if (Unit* rider = vehicle->GetSummoner())
1219                            rider->RemoveAurasDueToSpell(GetId());
1220            }
1221
1222            void Register() override
1223            {
1224                SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId);
1225
1226                // Defend spells cast by NPCs (add visuals)
1227                if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
1228                {
1229                    AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
1230                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
1231                }
1232
1233                // Remove Defend spell from player when he dismounts
1234                if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
1235                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
1236
1237                // Defend spells cast by players (add/remove visuals)
1238                if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY)
1239                {
1240                    AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
1241                    OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
1242                }
1243            }
1244        };
1245
1246        AuraScript* GetAuraScript() const override
1247        {
1248            return new spell_gen_defend_AuraScript();
1249        }
1250};
1251
1252class spell_gen_despawn_self : public SpellScriptLoader
1253{
1254    public:
1255        spell_gen_despawn_self() : SpellScriptLoader("spell_gen_despawn_self") { }
1256
1257        class spell_gen_despawn_self_SpellScript : public SpellScript
1258        {
1259            PrepareSpellScript(spell_gen_despawn_self_SpellScript);
1260
1261            bool Load() override
1262            {
1263                return GetCaster()->GetTypeId() == TYPEID_UNIT;
1264            }
1265
1266            void HandleDummy(SpellEffIndex effIndex)
1267            {
1268                if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_DUMMY || GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_SCRIPT_EFFECT)
1269                    GetCaster()->ToCreature()->DespawnOrUnsummon();
1270            }
1271
1272            void Register() override
1273            {
1274                OnEffectHitTarget += SpellEffectFn(spell_gen_despawn_self_SpellScript::HandleDummy, EFFECT_ALL, SPELL_EFFECT_ANY);
1275            }
1276        };
1277
1278        SpellScript* GetSpellScript() const override
1279        {
1280            return new spell_gen_despawn_self_SpellScript();
1281        }
1282};
1283
1284enum DivineStormSpell
1285{
1286    SPELL_DIVINE_STORM      = 53385,
1287};
1288
1289// 70769 Divine Storm!
1290class spell_gen_divine_storm_cd_reset : public SpellScriptLoader
1291{
1292    public:
1293        spell_gen_divine_storm_cd_reset() : SpellScriptLoader("spell_gen_divine_storm_cd_reset") { }
1294
1295        class spell_gen_divine_storm_cd_reset_SpellScript : public SpellScript
1296        {
1297            PrepareSpellScript(spell_gen_divine_storm_cd_reset_SpellScript);
1298
1299            bool Load() override
1300            {
1301                return GetCaster()->GetTypeId() == TYPEID_PLAYER;
1302            }
1303
1304            bool Validate(SpellInfo const* /*spellInfo*/) override
1305            {
1306                if (!sSpellMgr->GetSpellInfo(SPELL_DIVINE_STORM))
1307                    return false;
1308                return true;
1309            }
1310
1311            void HandleScript(SpellEffIndex /*effIndex*/)
1312            {
1313                Player* caster = GetCaster()->ToPlayer();
1314                if (caster->GetSpellHistory()->HasCooldown(SPELL_DIVINE_STORM))
1315                    caster->GetSpellHistory()->ResetCooldown(SPELL_DIVINE_STORM, true);
1316            }
1317
1318            void Register() override
1319            {
1320                OnEffectHitTarget += SpellEffectFn(spell_gen_divine_storm_cd_reset_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
1321            }
1322        };
1323
1324        SpellScript* GetSpellScript() const override
1325        {
1326            return new spell_gen_divine_storm_cd_reset_SpellScript();
1327        }
1328};
1329
1330class spell_gen_ds_flush_knockback : public SpellScriptLoader
1331{
1332    public:
1333        spell_gen_ds_flush_knockback() : SpellScriptLoader("spell_gen_ds_flush_knockback") { }
1334
1335        class spell_gen_ds_flush_knockback_SpellScript : public SpellScript
1336        {
1337            PrepareSpellScript(spell_gen_ds_flush_knockback_SpellScript);
1338
1339            void HandleScript(SpellEffIndex /*effIndex*/)
1340            {
1341                // Here the target is the water spout and determines the position where the player is knocked from
1342                if (Unit* target = GetHitUnit())
1343                {
1344                    if (Player* player = GetCaster()->ToPlayer())
1345                    {
1346                        float horizontalSpeed = 20.0f + (40.0f - GetCaster()->GetDistance(target));
1347                        float verticalSpeed = 8.0f;
1348                        // This method relies on the Dalaran Sewer map disposition and Water Spout position
1349                        // What we do is knock the player from a position exactly behind him and at the end of the pipe
1350                        player->KnockbackFrom(target->GetPositionX(), player->GetPositionY(

Large files files are truncated, but you can click here to view the full file