All pastes #794950 Raw Edit

Unnamed

public text v1 · immutable
#794950 ·published 2007-11-23 15:37 UTC
rendered paste body
/* Copyright (C) 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
*/

/* ScriptData
SDName: Boss_Lady_Vashj
SD%Complete: 0
SDComment: VERIFY SCRIPT
EndScriptData */

#include "../../../sc_defines.h"
#include "../../../creature/simple_ai.h"
#include "../../../../../../game/GameObject.h"
#include "../../../../../../game/Player.h"
#include "../../../../../../game/TargetedMovementGenerator.h"

#define SPELL_MULTI_SHOT              38310 //right
#define SPELL_SHOCK_BLAST             38509 //right
#define SPELL_ENTANGLE                38316
#define SPELL_STATIC_CHARGE_TRIGGER   38280 //right
#define SPELL_FORKED_LIGHTNING        40088 //right
#define SPELL_SHOOT                   40873 //right
#define SPELL_SUMMON_FATHOM_SPOREBAT  38431
#define SPELL_POISON_BOLT             40095 //right

#define SAY_INTRO                     "Water is life. It has become a rare commodity here in Outland. A commodity that we alone shall control. We are the Highborne, and the time has come at last for us to retake our rightful place in the world!"
#define SAY_AGGRO1                    "I'll split you from stem to stern! "
#define SAY_AGGRO2                    "Victory to Lord Illidan!"
#define SAY_AGGRO3                    "I spit on you, surface filth!"
#define SAY_AGGRO4                    "Death to the outsiders!"
#define SAY_PHASE1                    "I did not wish to lower myself by engaging your kind, but you leave me little choice!"
#define SAY_PHASE2                    "The time is now! Leave none standing!"
#define SAY_PHASE3                    "You may want to take cover."
#define SAY_BOWSHOT1                  "Straight to the heart!"
#define SAY_BOWSHOT2                  "Seek your mark!"
#define SAY_SLAY1                     "Your time ends now!"
#define SAY_SLAY2                     "You have failed!"
#define SAY_DEATH                     "Lord Illidan, I... I am... sorry."

#define SOUND_INTRO                   11531
#define SOUND_AGGRO1                  11532
#define SOUND_AGGRO2                  11533
#define SOUND_AGGRO3                  11534
#define SOUND_AGGRO4                  11535
#define SOUND_PHASE1                  11538
#define SOUND_PHASE2                  11539
#define SOUND_PHASE3                  11540
#define SOUND_BOWSHOT1                11536
#define SOUND_BOWSHOT2                11537
#define SOUND_SLAY1                   11541
#define SOUND_SLAY2                   11542
#define SOUND_DEATH                   11544

#define MIDDLE_X                      30.134
#define MIDDLE_Y                      -923.65
#define MIDDLE_Z                      42.9

#define ENCHANTED_ELEMENTAL           21958
#define TAINTED_ELEMENTAL             22009
#define COILFANG_STRIDER              22056
#define COILFANG_ELITE                22055

float ElementPos[8][4] = 
{
    {8.3, -835.3, 21.9, 5},
    {53.4, -835.3, 21.9, 4.5},
    {96, -861.9, 21.8, 4},
    {96, 986.4, 21.4, 2.5},
    {54.4, -1010.6, 22, 1.8},
    {9.8, -1012, 21.7, 1.4},
    {-35, -987.6, 21.5, 0.8},
    {-58.9, -901.6, 21.5, 6}
};

float CoilfangElitePos[3][4] =
{
    {28.843145, -923.284912, 42.901909, 6.007766},
    {31.183281, -953.502625, 41.523602, 1.640957},
    {58.895180, -923.124268, 41.545307, 3.152848}
};

float CoilfangStriderPos[3][4] =
{
    {66.427010, -948.778503, 41.262245, 2.584220},
    {7.513962, -959.538208, 41.300422, 1.034629},
    {-12.843201, -907.798401, 41.239620, 6.087094}
};

/*
#define ADD1_X195.338287
#define ADD1_Y1-984.918823
#define ADD1_Z122.329681
#define ADD1_O12.354881
#define ADD1_X212.150002
#define ADD1_Y2-1010.970337
#define ADD1_Z222.764811
#define ADD1_O21.299308
#define ADD1_X3-52.953896
#define ADD1_Y3-962.246216
#define ADD1_Z322.293423
#define ADD1_O30.396885
#define ADD1_X4-50.719109
#define ADD1_Y4-878.143799
#define ADD1_Z422.580536
#define ADD1_O45.864827
#define ADD4_X128.843145
#define ADD4_Y1923.284912
#define ADD4_Z142.901909
#define ADD4_O16.007766
#define ADD4_X231.183281
#define ADD4_Y2-953.502625
#define ADD4_Z241.523602
#define ADD4_O21.640957
#define ADD4_X358.895180
#define ADD4_Y3-923.124268
#define ADD4_Z341.545307
#define ADD4_O33.152848*/

struct MANGOS_DLL_DECL boss_lady_vashjAI : public ScriptedAI
{
    boss_lady_vashjAI (Creature *c) : ScriptedAI(c) 
    {
        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
        EnterEvadeMode();
    }

    ScriptedInstance *pInstance;

    uint32 ShockBlast_Timer;
    uint32 Entangle_Timer;
    uint32 StaticCharge_Timer;
    uint32 ForkedLightning_Timer;
    uint32 Check_Timer;
    uint32 EnchantedElemental_Timer;
    uint32 TaintedElemental_Timer;
    uint32 CoilfangElite_Timer;
    uint32 CoilfangStrider_Timer;
    //uint32 SummonSporebat_Timer;
    uint8 EnchantedElemental_Pos;
    uint8 Phase;
    bool Entangle;

    bool InCombat;

    void EnterEvadeMode()
    {
        ShockBlast_Timer = 1+rand()%60000;
        Entangle_Timer = 30000;
        StaticCharge_Timer = 10000+rand()%15000;
        ForkedLightning_Timer = 5000;
        Check_Timer = 1000;
        EnchantedElemental_Timer = 10000;
        TaintedElemental_Timer = 50000;
        CoilfangElite_Timer = 45000+rand()%5000;
        CoilfangStrider_Timer = 60000+rand()%10000;
        //SummonSporebat_Timer = 20000;
        EnchantedElemental_Pos = 0;
        Phase = 0;
        Entangle = false;

        InCombat = false;

        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);

        m_creature->RemoveAllAuras();
        m_creature->DeleteThreatList();
        m_creature->CombatStop();
        DoGoHome();

        if(pInstance)
            pInstance->SetData("LadyVashjEvent", 0);
    }

    void KilledUnit(Unit *victim)
    {
        switch(rand()%2)
        {
            case 0:
            DoYell(SAY_SLAY1, LANG_UNIVERSAL, NULL);
            DoPlaySoundToSet(m_creature, SOUND_SLAY1);
            break;
            case 1:
            DoPlaySoundToSet(m_creature, SOUND_SLAY1);
            DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL);
            break;
        }
    }

    void JustDied(Unit *victim)
    {
        DoPlaySoundToSet(m_creature, SOUND_DEATH);
        DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);

        if(pInstance)
            pInstance->SetData("LadyVashjEvent", 0);
    }

    void StartEvent()
    {
        switch(rand()%4)
        {
            case 0:
            DoPlaySoundToSet(m_creature, SOUND_AGGRO1);
            DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL);
            break;
            case 1:
            DoPlaySoundToSet(m_creature, SOUND_AGGRO2);
            DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL);
            break;
            case 2:
            DoPlaySoundToSet(m_creature, SOUND_AGGRO3);
            DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL);
            break;
            case 3:
            DoPlaySoundToSet(m_creature, SOUND_AGGRO4);
            DoYell(SAY_AGGRO4, LANG_UNIVERSAL, NULL);
            break;
        }

        InCombat = true;
        Phase = 1;

        if(pInstance)
            pInstance->SetData("LadyVashjEvent", 1);
    }

    void AttackStart(Unit *who)
    {
        if(!who && who != m_creature)
        return;

        if (who->isTargetableForAttack() && who!= m_creature)
        {
            //Begin melee attack if we are within range
            if(Phase != 2)
                DoStartMeleeAttack(who);

            if(!InCombat)
                StartEvent();
        }
    }

    void MoveInLineOfSight(Unit *who)
    {
        if (!who || m_creature->getVictim())
            return;

        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
        {
            float attackRadius = m_creature->GetAttackDistance(who);
            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
            {
                if(who->HasStealthAura())
                who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);

                if(Phase != 2)
                    DoStartMeleeAttack(who);

                if(!InCombat)
                    StartEvent();
            }
        }
    }

    void CastShootOrMultishot()
    {
        switch(rand()%2)
        {
            case 0:
            //Shoot
            //Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits her target for 4097-5543 Physical damage.
            DoCast(m_creature->getVictim(), SPELL_SHOOT);
            break;
            case 1:
            //Multishot
            //Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits 1 person and 4 people around him for 6475-7525 physical damage.
            DoCast(m_creature->getVictim(), SPELL_MULTI_SHOT);
            break;
        }

        if(rand()%3)
        {
            switch(rand()%2)
            {
                case 0:
                DoPlaySoundToSet(m_creature, SOUND_BOWSHOT1);
                DoYell(SAY_BOWSHOT1, LANG_UNIVERSAL, NULL);
                break;
                case 1:
                DoPlaySoundToSet(m_creature, SOUND_BOWSHOT2);
                DoYell(SAY_BOWSHOT2, LANG_UNIVERSAL, NULL);
                break;
            }
        }
    }

    //called when a tainted elemental dies
    void EventTaintedElementalDeath()
    {
        TaintedElemental_Timer = 50000; //the next elemental will spawn 50 seconds after the previous one's death
    }

    void UpdateAI(const uint32 diff)
    {
        //Return since we have no target
        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
        return;

        if(Phase == 1 || Phase == 3)
        {
            //ShockBlast_Timer
            if (ShockBlast_Timer < diff)
            { 
                //Shock Burst
                //Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list.
                DoCast(m_creature->getVictim(), SPELL_SHOCK_BLAST);
                Unit* target = NULL;
                target = SelectUnit(SELECT_TARGET_TOPAGGRO,1);
                m_creature->TauntApply(target);

                ShockBlast_Timer = 1+rand()%60000; //random cooldown
            }else ShockBlast_Timer -= diff;

            //StaticCharge_Timer
            if(StaticCharge_Timer < diff)
            {
                //Static Charge
                //Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic.
                Unit *target = NULL;
                target = SelectUnit(SELECT_TARGET_RANDOM, 0);

                if(target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER, 0))
                DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); //cast Static Charge every 2 seconds for 20 seconds

                StaticCharge_Timer = 10000+rand()%20000; //blizzlike
            }else StaticCharge_Timer -= diff;

            //Entangle_Timer
            if (Entangle_Timer < diff)
            {
                if(!Entangle)
                {
                    //Entangle
                    //Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom.
                    DoCast(m_creature->getVictim(), SPELL_ENTANGLE);
                    Entangle = true;
                    Entangle_Timer = 10000;
                }
                else
                {
                    CastShootOrMultishot();
                    Entangle = false;
                    Entangle_Timer = 40000;
                }
            }else Entangle_Timer -= diff;

            //Phase 1
            if(Phase == 1)
            {
                //Start phase 2
                if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 70)
                {
                    //Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable.
                    Phase = 2;
                    m_creature->GetMotionMaster()->Clear();
                    m_creature->Relocate(MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
                    m_creature->SendMoveToPacket(MIDDLE_X, MIDDLE_Y, MIDDLE_Z, true);

                    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);

                    DoPlaySoundToSet(m_creature, SOUND_PHASE2);
                    DoYell(SAY_PHASE2, LANG_UNIVERSAL, NULL);
                }
            }
            //Phase 3
            else
            {
                //Toxic Spores
                //Used in Phase 3 by the Spore Bats, it creates a contaminated green patch of ground, dealing about 2775-3225 nature damage every second to anyone who stands in it.

                /*
                if(SummonSporebat_Timer < diff && !Phase1 && !Phase2)
                {
                DoCast(m_creature->getVictim(), SPELL_SUMMON_FATHOM_SPOREBAT);
                DoYell(SAY_SUMMONSPOREBAT, LANG_UNIVERSAL, NULL);
                SummonSporebat_Timer = SummonSporebat_Timer -= 1000;//she should summon sporebats faster and faster
                }else SummonSporebat_Timer -= diff;*/

            }

            //Melee attack
            DoMeleeAttackIfReady();

            //Check_Timer - used to check if somebody is in melee range
            if(Check_Timer < diff)
            {
                bool InMeleeRange = false;
                Unit *target;
                std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
                for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                {
                    target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                    if(target && target->IsWithinDistInMap(m_creature, 5)) //if in melee range
                    {
                        InMeleeRange = true;
                        break;
                    }
                }

                //if nobody is in melee range
                if(!InMeleeRange)
                    CastShootOrMultishot();

                Check_Timer = 1000;
            }else Check_Timer -= diff;
        }
        //Phase 2
        else
        {
            //ForkedLightning_Timer
            if(ForkedLightning_Timer < diff)
            {
                //Forked Lightning
                //Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage.
                Unit *target = NULL;
                target = SelectUnit(SELECT_TARGET_RANDOM, 0);

                if(!target)
                    target = m_creature->getVictim();

                DoCast(target, SPELL_FORKED_LIGHTNING);

                ForkedLightning_Timer = 5000+rand()%10000; //blizzlike
            }else ForkedLightning_Timer -= diff;

            //EnchantedElemental_Timer
            if(EnchantedElemental_Timer < diff)
            {
                Creature *Elemental;
                Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_CORPSE_DESPAWN, 0);

                if(Elemental)
                {
                    //go to lady vashj
                    Elemental->Relocate(MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
                    Elemental->SendMoveToPacket(MIDDLE_X, MIDDLE_Y, MIDDLE_Z, true);
                }

                if(EnchantedElemental_Pos == 7)
                    EnchantedElemental_Pos = 0;
                else
                    EnchantedElemental_Pos++;

                EnchantedElemental_Timer = 10000+rand()%10000;
            }else EnchantedElemental_Timer -= diff;

            //TaintedElemental_Timer
            if(TaintedElemental_Timer < diff)
            {
                Creature *Tain_Elemental;
                uint32 pos = rand()%8;
                Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 180000);

                TaintedElemental_Timer = 180000; //if this elemental isn't killed or despawn, respawn a new one in 3 minutes
            }else TaintedElemental_Timer -= diff;

            //CoilfangElite_Timer
            if(CoilfangElite_Timer < diff)
            {
                Creature *CoilfangElite;
                uint32 pos = rand()%3;
                CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                if(CoilfangElite)
                {
                    Unit *target = NULL;
                    target = SelectUnit(SELECT_TARGET_RANDOM, 0);
                    if(target)
                        CoilfangElite->AI()->AttackStart(target);
                }

                CoilfangElite_Timer = 45000+rand()%5000; //wowwiki says 50 seconds, bosskillers says 45
            }else CoilfangElite_Timer -= diff;

            //CoilfangStrider_Timer
            if(CoilfangStrider_Timer < diff)
            {
                Creature *CoilfangStrider;
                uint32 pos = rand()%3;
                CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                if(CoilfangStrider)
                {
                    Unit *target = NULL;
                    target = SelectUnit(SELECT_TARGET_RANDOM, 0);
                    if(target)
                        CoilfangStrider->AI()->AttackStart(target);
                }

                CoilfangStrider_Timer = 60000+rand()%10000; //wowwiki says 60 seconds, bosskillers says 60-70
            }else CoilfangStrider_Timer -= diff;

            //Check_Timer
            if(Check_Timer < diff)
            {
                //Start Phase 3
                if(pInstance && pInstance->GetData("CanStartPhase3"))
                {
                    //set life 50%
                    m_creature->SetHealth(m_creature->GetMaxHealth()/2);

                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);

                    DoPlaySoundToSet(m_creature, SOUND_PHASE3);
                    DoYell(SAY_PHASE3, LANG_UNIVERSAL, NULL);

                    Phase = 3;

                    //return to the tank
                    m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature->getVictim()));
                }
                Check_Timer = 1000;
            }else Check_Timer -= diff;
        }
    }
};

//Enchanted Elemental
//If one of them reaches Vashj he will increase her damage done by 5%.
struct MANGOS_DLL_DECL mob_enchanted_elementalAI : public ScriptedAI
{
    mob_enchanted_elementalAI(Creature *c) : ScriptedAI(c)
    {
        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
        EnterEvadeMode();
    }

    ScriptedInstance *pInstance;

    uint32 Check_Timer;

    void EnterEvadeMode()
    {
        Check_Timer = 1000;

        m_creature->RemoveAllAuras();
        m_creature->DeleteThreatList();
        m_creature->CombatStop();
        DoGoHome();
    }

    void AttackStart(Unit *who) { return; }

    void MoveInLineOfSight(Unit *who) { return; }

    void UpdateAI(const uint32 diff)
    {
        if(!pInstance)
            return;

        if(Check_Timer < diff)
        {
            Unit *Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64("LadyVashj"));

            if(Vashj && Vashj->IsWithinDistInMap(m_creature, 5))
            {
                //increase lady vashj damage
                /*float mindmg = cInfo->mindmg;
                float maxdmg = cInfo->maxdmg;
                Vashj->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (mindmg +((mindmg/100) * 5 * times)));
                Vashj->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (maxdmg +((maxdmg/100) * 5 * times)));*/

                //despawn
                m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);
            }
            Check_Timer = 1000;
        }else Check_Timer -= diff;
    }
};

//Tainted Elemental
//This mob has 7,900 life, doesn't move, and shoots Poison Bolts at one person anywhere in the area, doing 3,000 nature damage and placing a posion doing 2,000 damage every 2 seconds. He will switch targets often, or sometimes just hang on a single player, but there is nothing you can do about it except heal the damage and kill the Tainted Elemental
struct MANGOS_DLL_DECL mob_tainted_elementalAI : public ScriptedAI
{
    mob_tainted_elementalAI(Creature *c) : ScriptedAI(c)
    {
        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
        EnterEvadeMode();
    }

    ScriptedInstance *pInstance;

    uint32 PoisonBolt_Timer;

    void EnterEvadeMode()
    {
        PoisonBolt_Timer = 5000+rand()%5000;

        m_creature->RemoveAllAuras();
        m_creature->DeleteThreatList();
        m_creature->CombatStop();
        DoGoHome();
    }
    void AttackStart(Unit *who)
    {
        if(!who && who != m_creature)
        return;

        if (who->isTargetableForAttack() && who!= m_creature)
        {
            m_creature->AddThreat(who, 0.1f);
        }
    }

    void JustDied(Unit *victim)
    {
        if(pInstance)
        {
            Creature *Vashj = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64("LadyVashj")));

            if(Vashj)
                ((boss_lady_vashjAI*)Vashj->AI())->EventTaintedElementalDeath();
        }
    }

    void MoveInLineOfSight(Unit *who)
    {
        if (!who || m_creature->getVictim())
            return;

        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
        {
            float attackRadius = m_creature->GetAttackDistance(who);
            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
            {
                if(who->HasStealthAura())
                who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);

                m_creature->AddThreat(who, 0.1f);
            }
        }
    }

    void UpdateAI(const uint32 diff)
    {
        //PoisonBolt_Timer
        if(PoisonBolt_Timer < diff)
        {
            Unit *target = NULL;
            target = SelectUnit(SELECT_TARGET_RANDOM, 0);

            if(target && target->IsWithinDistInMap(m_creature, 30))
                DoCast(target, SPELL_POISON_BOLT);

            PoisonBolt_Timer = 5000+rand()%5000;
        }else PoisonBolt_Timer -= diff;
    }
};

//Coilfang Elite
//It's an elite Naga mob with 170,000 HP. It does about 5000 damage on plate, and has a nasty cleave hitting for about 7500 damage
CreatureAI* GetAI_mob_coilfang_eliteAI(Creature *_Creature)
{
    SimpleAI* ai = new SimpleAI (_Creature);

    ai->Spell[0].Enabled = true;
    ai->Spell[0].Spell_Id = 31345;           //Cleave
    ai->Spell[0].Cooldown = 15000;
    ai->Spell[0].CooldownRandomAddition = 5000;
    ai->Spell[0].First_Cast = 5000;
    ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_RANDOM;

    ai->EnterEvadeMode();

    return ai;
}

//Coilfang Strifer
//It hits plate for about 8000 damage, has a Mind Blast spell doing about 3000 shadow damage, and a Psychic Scream Aura, which fears everybody in a 8 yard range of it every 2-3 seconds , for 5 seconds and increasing their movement speed by 150% during the fear.
CreatureAI* GetAI_mob_coilfang_striderAI(Creature *_Creature)
{
    SimpleAI* ai = new SimpleAI (_Creature);

    ai->Spell[0].Enabled = true;
    ai->Spell[0].Spell_Id = 41374;           //Mind Blast
    ai->Spell[0].Cooldown = 30000;
    ai->Spell[0].CooldownRandomAddition = 10000;
    ai->Spell[0].First_Cast = 8000;
    ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_TARGET;

    //Scream aura not implemented

    ai->EnterEvadeMode();

    return ai;
}

CreatureAI* GetAI_boss_lady_vashjAI(Creature *_Creature)
{
    return new boss_lady_vashjAI (_Creature);
}
CreatureAI* GetAI_mob_enchanted_elementalAI(Creature *_Creature)
{
    return new mob_enchanted_elementalAI (_Creature);
}
CreatureAI* GetAI_mob_tainted_elementalAI(Creature *_Creature)
{
    return new mob_tainted_elementalAI (_Creature);
}

bool GOHello_go_shield_generator(Player *player, GameObject* _GO)
{
    if(!_GO->GetInstanceData())
    {
        _GO->Say("Error: instance data not initialized", LANG_UNIVERSAL, NULL);
        return true;
    }

    ScriptedInstance* pInstance = (ScriptedInstance*)(_GO->GetInstanceData());

    //get identifier
    char *identifier;
    switch(_GO->GetEntry())
    {
        case 185052:
        identifier = "ShieldGenerator1";
        break;

        case 185053:
        identifier = "ShieldGenerator2";
        break;

        case 185051:
        identifier = "ShieldGenerator3";
        break;

        case 185054:
        identifier = "ShieldGenerator4";
        break;
    }

    //if player doesn't have Taunted Core
    if(!player->HasItemCount(31088, 1))
    {
        player->GetSession()->SendNotification("Requires Tainted Core");
        return true;
    }

    //if this gameobject is already deactivated
    if(pInstance->GetData(identifier))
    {
        player->GetSession()->SendNotification("Already deactivated");
        return true;
    }

    //remove the item
    player->RemoveItemCount(31088, 1, true);

    //send this to instance script
    pInstance->SetData(identifier, 1);

    return true;
}

void AddSC_boss_lady_vashj()
{
    Script *newscript;
    newscript = new Script;
    newscript->Name="boss_lady_vashj";
    newscript->GetAI = GetAI_boss_lady_vashjAI;
    m_scripts[nrscripts++] = newscript;

    newscript = new Script;
    newscript->Name="mob_enchanted_elemental";
    newscript->GetAI = GetAI_mob_enchanted_elementalAI;
    m_scripts[nrscripts++] = newscript;

    newscript = new Script;
    newscript->Name="mob_tainted_elemental";
    newscript->GetAI = GetAI_mob_tainted_elementalAI;
    m_scripts[nrscripts++] = newscript;

    newscript = new Script;
    newscript->Name="mob_coilfang_elite";
    newscript->GetAI = GetAI_mob_coilfang_eliteAI;
    m_scripts[nrscripts++] = newscript;

    newscript = new Script;
    newscript->Name="mob_coilfang_strider";
    newscript->GetAI = GetAI_mob_coilfang_striderAI;
    m_scripts[nrscripts++] = newscript;

    newscript = new Script;
    newscript->Name="go_shield_generator";
    newscript->pGOHello = &GOHello_go_shield_generator;
    m_scripts[nrscripts++] = newscript;
}