All pastes #985813 Raw Edit

Untitled

public text v1 · immutable
·published 2008-04-15 10:06 UTC
rendered paste body
/* Copyright (C) 2006 - 2008 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, MA  02111-1307  USA
*/

/* ScriptData
SDName: Boss_moroes
SD%Complete: 100
SDComment:
EndScriptData */

#include "def_karazhan.h"
#include "../../../../../game/TargetedMovementGenerator.h"
#include "../../../../../game/IdleMovementGenerator.h"


#define SAY_AGGRO           "Hmm, unannounced visitors? Preparations must be made."
#define SOUND_AGGRO         9211

#define SAY_SPECIAL_1       "Now, where was I? Oh yes..."
#define SOUND_SPECIAL_1     9215

#define SAY_SPECIAL_2       "You rang?"
#define SOUND_SPECIAL_2     9316

#define SAY_KILL_1          "One more for dinner this evening"
#define SOUND_KILL_1        9214

#define SAY_KILL_2          "Time... Never enough time."
#define SOUND_KILL_2        9314

#define SAY_KILL_3          "I've gone and made a mess."
#define SOUND_KILL_3        9315

#define SAY_DEATH           "How terribly clumsy of me..."
#define SOUND_DEATH         9213

#define SPELL_VANISH        41476
#define SPELL_GARROTE       37066
#define SPELL_BLIND         34654
#define SPELL_GOUGE         28456
#define SPELL_ENRAGE        19953

#define ORIENT              4.5784

#define SPAWN1_X            -10976.27929
#define SPAWN1_Y            -1878.17358
#define SPAWN1_Z            81.73

#define SPAWN2_X            -10979.7587
#define SPAWN2_Y            -1877.8706
#define SPAWN2_Z            81.73

#define SPAWN3_X            -10985.665
#define SPAWN3_Y            -1877.2458
#define SPAWN3_Z            81.73

#define SPAWN4_X            -10989.136719
#define SPAWN4_Y            -1876.8309
#define SPAWN4_Z            81.73

uint32 Adds[6] = {19875, 19874, 19872, 17007, 19876, 19873};
uint64 AddGuid[4] = {0,0,0,0};
uint32 AddType[4] = {0,0,0,0};


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

    ScriptedInstance *pInstance;

    uint32 Vanish_Timer;
    uint32 Blind_Timer;
    uint32 Gouge_Timer;
    uint32 Wait_Timer;
    uint32 CheckAdds_Timer;

    bool InCombat;
    bool InVanish;
    bool Enrage;

    void Reset()
    {
        Vanish_Timer = 52000;
        Blind_Timer = 35000;
        Gouge_Timer = 23000;
        Wait_Timer = 999999999;
        CheckAdds_Timer = 5000;
        InCombat = false;
        Enrage = false;
        InVanish = false;
        DeSpawnAdds();
        SpawnAdds();

        if (pInstance)
            pInstance->SetData(DATA_MOROES_EVENT, 0);
    }

    void StartEvent()
    {
        if (!pInstance)
            return;

        DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
        DoPlaySoundToSet(m_creature, SOUND_AGGRO);

        if (pInstance)
            pInstance->SetData(DATA_MOROES_EVENT, 1);
    }

    void Aggro(Unit *who)
    {
        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);

                DoStartMeleeAttack(who);

                if (!InCombat)
                {
                    DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL);
                    DoPlaySoundToSet(m_creature, SOUND_AGGRO);
                    InCombat = true;
                    AddsAttack();
                }
            }
        }
    }

    void KilledUnit(Unit *victim)
    {
        switch (rand()%3)
        {
        case 0:
            DoYell(SAY_KILL_1, LANG_UNIVERSAL, NULL);
            DoPlaySoundToSet(victim, SOUND_KILL_1);
            break;
        case 1:
            DoYell(SAY_KILL_2, LANG_UNIVERSAL, NULL);
            DoPlaySoundToSet(victim, SOUND_KILL_2);
            break;
        case 2:
            DoYell(SAY_KILL_3, LANG_UNIVERSAL, NULL);
            DoPlaySoundToSet(victim, SOUND_KILL_3);
            break;
        }
    }

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

        if (pInstance)
            pInstance->SetData(DATA_MOROES_EVENT, 0);
        DeSpawnAdds();
    }

    void SpawnAdds()
    {
        uint32 i1;
        uint32 i2;
        uint32 i3;
        uint32 i = rand()%6;
        Unit *pCreature;

        if (AddType[0])
        {
            pCreature = m_creature->SummonCreature(AddType[0], SPAWN1_X, SPAWN1_Y, SPAWN1_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
            i1 = i;
        }
        else
        {
            pCreature = m_creature->SummonCreature(Adds[i], SPAWN1_X, SPAWN1_Y, SPAWN1_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
            AddType[0] = Adds[i];
        }
        AddGuid[0] = pCreature->GetGUID();


        while (i == i1)
        {
            i = rand()%6;
        }

        if (AddType[1])
            pCreature = m_creature->SummonCreature(AddType[1], SPAWN2_X, SPAWN2_Y, SPAWN2_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
        else
        {
            pCreature = m_creature->SummonCreature(Adds[i], SPAWN2_X, SPAWN2_Y, SPAWN2_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
            AddType[1] = Adds[i];
        }
        AddGuid[1] = pCreature->GetGUID();
        i2 = i;

        while (i == i1 || i == i2)
        {
            i = rand()%6;
        }

        if (AddType[2])
            pCreature = m_creature->SummonCreature(AddType[2], SPAWN3_X, SPAWN3_Y, SPAWN3_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
        else
        {
            pCreature = m_creature->SummonCreature(Adds[i], SPAWN3_X, SPAWN3_Y, SPAWN3_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
            AddType[2] = Adds[i];
        }
        AddGuid[2] = pCreature->GetGUID();
        i3 = i;

        while (i == i1 || i == i2 || i == i3)
        {
            i = rand()%6;
        }

        if (AddType[3])
            pCreature = m_creature->SummonCreature(AddType[3], SPAWN4_X, SPAWN4_Y, SPAWN4_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
        else
        {
            pCreature = m_creature->SummonCreature(Adds[i], SPAWN4_X, SPAWN4_Y, SPAWN4_Z, ORIENT, TEMPSUMMON_CORPSE_DESPAWN, 60000);
            AddType[3] = Adds[i];
        }
        AddGuid[3] = pCreature->GetGUID();
    }

    void DeSpawnAdds()
    {
        for (uint32 i =0;i<4;i++)
        {
            Unit *Temp;
            if (AddGuid[i])
            {
                Temp = Unit::GetUnit((*m_creature),AddGuid[i]);
                if (Temp)
                    Temp->DealDamage(Temp, Temp->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);
            }
        }
    }

    void AddsAttack()
    {
        if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 99)
            for (uint32 i =0;i<4;i++)
            {
                Unit *Temp;
                if (AddGuid[i])
                {
                    Temp = Unit::GetUnit((*m_creature),AddGuid[i]);
                    if (Temp && Temp->isAlive())
                        ((Creature*)Temp)->AI()->AttackStart(m_creature->getVictim());
                    else
                        EnterEvadeMode();
                }
            }
    }

    void UpdateAI(const uint32 diff)
    {
        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
            return;

        if (pInstance && !pInstance->GetData(DATA_MOROES_EVENT))
            EnterEvadeMode();

        if (!Enrage && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30)
        {
            DoCast(m_creature, SPELL_ENRAGE);
            Enrage = true;
        }

        if (CheckAdds_Timer < diff)
        {
            for (uint32 i =0;i<4;i++)
            {
                Unit *Temp;
                if (AddGuid[i])
                {
                    Temp = Unit::GetUnit((*m_creature),AddGuid[i]);
                    if (Temp && Temp->isAlive())
                        if (!Temp->SelectHostilTarget() || !Temp->getVictim() )
                            ((Creature*)Temp)->AI()->AttackStart(m_creature->getVictim());
                }
            }
            CheckAdds_Timer = 5000;
        }else CheckAdds_Timer -= diff;

        if (!Enrage)
        {
            //Cast Vanish, then Garrote random victim
            if (Vanish_Timer < diff)
            {
                m_creature->setFaction(35);
                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                DoCast(m_creature, SPELL_VANISH);
                InVanish = true;
                Vanish_Timer = 60000;
                Wait_Timer = 5000;
            }else Vanish_Timer -= diff;

            if (Wait_Timer < diff)
            {
                Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
                if (target)
                    target->CastSpell(target, SPELL_GARROTE, true);
                m_creature->setFaction(14);
                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                InVanish = false;
                Wait_Timer = 999999999;
            }else Wait_Timer -= diff;

            //Blind highest aggro, and attack second highest
            if (Gouge_Timer < diff)
            {
                DoCast(m_creature->getVictim(), SPELL_GOUGE);
                Unit *target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);
                if (target)
                    m_creature->getThreatManager().modifyThreatPercent(target,-100);
                Gouge_Timer = 40000;
            }else Gouge_Timer -= diff;

            if (Blind_Timer < diff)
            {
                Unit *target;
                std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
                std::vector<Unit *> target_list;
                for (std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                {
                    target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                    if (target && target->GetDistance2dSq(m_creature) < 25)
                        target_list.push_back(target);
                    target = NULL;
                }
                if (target_list.size())
                    target = *(target_list.begin()+rand()%target_list.size());

                DoCast(target, SPELL_BLIND);
                Blind_Timer = 40000;
            }else Blind_Timer -= diff;
        }
        if (!InVanish)
            DoMeleeAttackIfReady();
    }
};

#define SPELL_MANABURN       29405
#define SPELL_MINDFLY        29570
#define SPELL_SWPAIN         34441
#define SPELL_SHADOWFORM     29406

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

    ScriptedInstance *pInstance;

    uint32 ManaBurn_Timer;
    uint32 MindFlay_Timer;
    uint32 ShadowWordPain_Timer;
    bool InCombat;

    void Reset()
    {
        ManaBurn_Timer = 7000;
        MindFlay_Timer = 1000;
        ShadowWordPain_Timer = 6000;
        InCombat = false;

        if (pInstance)
            pInstance->SetData(DATA_MOROES_EVENT, 0);
    }

    void Aggro(Unit *who)
    {
        return;
    }

    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);

                DoStartMeleeAttack(who);
                if (!InCombat)
                {
                    InCombat=true;
                    DoCast(m_creature,SPELL_SHADOWFORM);
                    if (pInstance)
                        pInstance->SetData(DATA_MOROES_EVENT, 1);
                }
            }
        }
    }

    void KilledUnit(Unit *victim)
    {
    }

    void JustDied(Unit *victim)
    {
    }

    void UpdateAI(const uint32 diff)
    {
        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
            return;

        if (pInstance && !pInstance->GetData(DATA_MOROES_EVENT))
            EnterEvadeMode();

        if (MindFlay_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_MINDFLY);
            MindFlay_Timer = 12000; //3sec channeled
        }else MindFlay_Timer -= diff;

        if (ManaBurn_Timer < diff)
        {
            Unit *target;
            std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
            std::vector<Unit *> target_list;
            for (std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
            {
                target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                if (target && target->GetPower(POWER_MANA))
                {
                    DoCast(target,SPELL_MANABURN);
                    itr= t_list.end();
                }
            }
            ManaBurn_Timer = 5000; //3 sec cast
        }else ManaBurn_Timer -= diff;

        if (ShadowWordPain_Timer < diff)
        {
            Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
            if (target)
                DoCast(m_creature->getVictim(),SPELL_SWPAIN);
            ShadowWordPain_Timer = 7000;
        }else ShadowWordPain_Timer -= diff;

        DoMeleeAttackIfReady();
    }
};

CreatureAI* GetAI_boss_moroes(Creature *_Creature)
{
    return new boss_moroesAI (_Creature);
}
CreatureAI* GetAI_baroness_dorothea_millstipe(Creature *_Creature)
{
    return new boss_baroness_dorothea_millstipeAI (_Creature);
}
void AddSC_boss_moroes()
{
    Script *newscript;
    newscript = new Script;
    newscript->Name="boss_moroes";
    newscript->GetAI = GetAI_boss_moroes;
    m_scripts[nrscripts++] = newscript;

    newscript = new Script;
    newscript->Name="baroness_dorothea_millstipe";
    newscript->GetAI = GetAI_baroness_dorothea_millstipe;
    m_scripts[nrscripts++] = newscript;
}