All pastes #708536 Raw Edit

Anonymous

public text v1 · immutable
#708536 ·published 2007-09-23 22:24 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, MA  02111-1307  USA
*/

#include "../../sc_defines.h"
#include "../../../../../game/Player.h"
#include "../../../../../game/GossipDef.h"
#include "../../../../../game/TargetedMovementGenerator.h"

#define SAY_GAMESBEGIN          "Let the games begin!"
#define SAY_VAEL_INTRO          "<unknown>"
#define SAY_DEATH               "This cannot be! I am the Master here! You mortals are nothing to my kind! DO YOU HEAR? NOTHING!"

#define SOUND_GAMESBEGIN        8280
#define SOUND_VAEL_INTRO        8279
#define SOUND_DEATH             8292

#define GOSSIP_ITEM             "Start Event <Needs Gossip Text>"

#define CREATURE_BRONZE_DRAKANOID       14263
#define CREATURE_BLUE_DRAKANOID         14261
#define CREATURE_RED_DRAKANOID          14264
#define CREATURE_GREEN_DRAKANOID        14262
#define CREATURE_BLACK_DRAKANOID        14265
#define CREATURE_CHROMATIC_DRAKANOID    14302

#define SPELL_DRAKONOIDS_RED        22655                          //Summon
#define SPELL_DRAKONOIDS_GREEN      22656
#define SPELL_DRAKONOIDS_BRONZE     22657
#define SPELL_DRAKONOIDS_BLUE       22658
#define SPELL_DRAKONOIDS_BLACK      22654
#define SPELL_DRAKONOIDS_CHROMATIC  22680



#define CREATURE_NEFARIAN               11583

#define ADD_X1 -7591.151855
#define ADD_X2 -7514.598633
#define ADD_Y1 -1204.051880
#define ADD_Y2 -1150.448853
#define ADD_Z1 476.800476
#define ADD_Z2 476.796570

#define NEF_X   -7445
#define NEF_Y   -1332
#define NEF_Z   536

#define HIDE_X  -7592
#define HIDE_Y  -1264
#define HIDE_Z  481

#define SPELL_SHADOWBOLT        21077
#define SPELL_MINDCONTROL       56 // Replaced By a Stunt Since Not Possible to MindControl

#define MAX_SUMMON             17 // Normal = 42, Lower to 15
#define TIMER_RESET            
//This script is complicated
//Instead of morphing Victor Nefarius we will have him control phase 1
//And then have him spawn "Nefarian" for phase 2
//When phase 2 starts Victor Nefarius will go into hiding and stop attacking
//If Nefarian despawns because he killed the players then this guy will EnterEvadeMode
//and allow players to start the event over
//If nefarian dies then he will kill himself then he will kill himself in his hiding place
//To prevent players from doing the event twice

struct MANGOS_DLL_DECL boss_victor_nefariusAI : public ScriptedAI
{
    boss_victor_nefariusAI(Creature *c) : ScriptedAI(c) { EnterEvadeMode(); }

    int32 shadowBoltTimer;
    int32 mindControlTimer;
    int32 summonTimer;
    int32 summonCheckTimer;
    int32 sleep;
    uint8 phase;
    
    bool respawnSummon;
    uint32 summonId[3];
    uint64 m_summons[MAX_SUMMON+1];
    float x[2], y[2], z[2], o[2];
    uint32 mapId;
    uint64 nefarianGUID;

    int32 resetTimer;

    void EnterEvadeMode()
    {
        nefarianGUID = 0;
        resetTimer = 0;        //On official it takes him 15 minutes(900 seconds) to reset. We are only doing 1 minute to make testing easier
        mindControlTimer = 1000;
        shadowBoltTimer = 5000;
        summonTimer = 4000;
        summonCheckTimer = 2000;
        sleep = 0;
        phase = 0;

        respawnSummon = false;
        for(uint8 n = 0; n < MAX_SUMMON+1; ++n)
            m_summons[n] = 0;               //Index 0 Gave us the Count
        summonId[0] = 14302;
        summonId[1] = 0;
        summonId[2] = 0;
        uint8 n = 1;
        while(summonId[2]==0)
        {
            srand(time(NULL));
            switch(irand(0,4))
            {
                case 0:
                {                                                   //red
                    if(n == 2 && summonId[1] == 14264)
                        break;
                    summonId[n] = 14264;
                    n = 2;
                    break;
                }
                case 1:
                {                                                  //Green
                    if(n == 2 && summonId[1] == 14262)
                        break;
                    summonId[n] = 14262;
                    n = 2;
                    break;
                }
                case 2:
                {                                                  //Bronze
                    if(n == 2 && summonId[1] == 14263)
                        break;
                    summonId[n] = 14263;
                    n = 2;
                    break;
                }
                case 3:
                {                                                  //Blue
                    if(n == 2 && summonId[1] == 14261)
                        break;
                    summonId[n] = 14264;
                    n = 2;
                    break;
                }
                case 4:
                {                                                  //Black
                    if(n == 2 && summonId[1] == 14265)
                        break;
                    summonId[n] = 14265;
                    n = 2;
                    break;
                }
            }
        }
        mapId = 469;
        x[0] = -7593.2585; 
        y[0] = -1200.5969; z[0] = 476.7811; o[0] = 5.314193; //Sud
        x[1] = -7517.3140; y[1] = -1147.3402; z[1] = 476.7811; o[1] = 5.1314;   //Nord

        m_creature->RemoveAllAuras();
        m_creature->DeleteThreatList();
        m_creature->CombatStop();
        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 9472);     //Original One
        m_creature->SetUInt32Value(UNIT_NPC_FLAGS,1);
        m_creature->setFaction(35);                         //Friendly
        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
        DoGoHome();
    }

    void BeginEvent(Player* target)
    {
        DoYell(SAY_GAMESBEGIN,LANG_UNIVERSAL,NULL);
        DoPlaySoundToSet(m_creature,SOUND_GAMESBEGIN);

        //MaNGOS::Singleton<MapManager>::Instance().GetMap(m_creature->GetMapId(), m_creature)->GetPlayers().begin();
        /*
        list <Player*>::iterator i = MapManager::Instance().GetMap(m_creature->GetMapId(), m_creature)->GetPlayers().begin();

        for (i = MapManager::Instance().GetMap(m_creature->GetMapId(), m_creature)->GetPlayers().begin(); i != MapManager::Instance().GetMap(m_creature->GetMapId(), m_creature)->GetPlayers().end(); ++i)
        {
        AttackStart((*i));            
        }
        */
        phase = 1;
        m_creature->SetUInt32Value(UNIT_NPC_FLAGS,0);
        m_creature->setFaction(103);
        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
        AttackStart(target);

    }

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

        if (who->isTargetableForAttack() && who!= m_creature)
        {
            DoStartMeleeAttack(who);// Don't think is needed for him since he never really attack.
        }
    }

    void MoveInLineOfSight(Unit *who)
    {
        //We simply use this function to find players until we can use Map->GetPlayers()

        if (who && who->GetTypeId() == TYPEID_PLAYER && m_creature->IsHostileTo(who))
        {
            //Add them to our threat list
            m_creature->AddThreat(who,0.0f);
        }
    }

   
    void DamageTaken(Unit* Victim, uint32 &damage)
    {
        if(phase != 3)
            damage = 0;
        if( m_creature->GetHealth() < damage)
        {
            DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL);
            DoPlaySoundToSet(m_creature, SOUND_DEATH);
        }
    }

    void UpdateAI(const uint32 diff)
    {
        if(!m_creature->isAlive())
            return;

        Unit* target;
        uint8 summonIndex;
        if(phase == 1)
        {
            if( m_creature->SelectHostilTarget() && m_creature->getVictim())
            {
                if(!(m_creature->GetUInt32Value(UNIT_FIELD_FLAGS) & UNIT_FLAG_NOT_SELECTABLE))
                    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);

                target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if(!target)
                    return;

                if(sleep < diff)                                       //Changing Random target
                {
                    if(target->isInAccessablePlaceFor(m_creature))
                    {
                        m_creature->GetMotionMaster()->Clear();
                        m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>((*target),6.0f,PET_FOLLOW_ANGLE));
                    }
                    sleep = irand(3000,5000);
                }else sleep -= diff;

                if( shadowBoltTimer < diff )                           //ShadowBoltTimer
                {
                    DoCast(target,SPELL_SHADOWBOLT);
                    shadowBoltTimer = irand(7000,10000);
                }else shadowBoltTimer -= diff;

                if( mindControlTimer < diff )                          //ShadowBoltTimer
                {
                    DoCast(target,SPELL_MINDCONTROL);
                    mindControlTimer = irand(7000,10000);
                }else mindControlTimer -= diff;

                Creature *summon;
                if( summonTimer < diff && m_summons[0] < MAX_SUMMON)            //Add spawning mechanism
                {
                    srand(time(NULL));
                    if(irand(1,100) > 42)
                    {
                        summonIndex = irand(0,1);
                        summon = m_creature->SummonCreature(summonId[0],x[summonIndex],y[summonIndex],z[summonIndex],o[summonIndex],TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,3600000);
                        srand(time(NULL));
                        target = SelectUnit(SELECT_TARGET_RANDOM,0);
                        if(summon && target)
                        {
                            summon->AI()->AttackStart(target);
                            m_summons[++m_summons[0]] = summon->GetGUID();
                        }
                    }
                    else
                    {
                        for(summonIndex = 0; summonIndex < 1; summonIndex++)
                        {   
                            summon = m_creature->SummonCreature(summonId[summonIndex+1],x[summonIndex],y[summonIndex],z[summonIndex],o[summonIndex],TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,3600000);
                            srand(time(NULL));
                            target = SelectUnit(SELECT_TARGET_RANDOM,0);
                            if(summon && target)
                            {   
                                summon->AI()->AttackStart(target);
                                m_summons[++m_summons[0]] = summon->GetGUID();
                            }
                            
                        }
                    }
                    summonTimer = irand(3000,5000);
                }else summonTimer -= diff;

                Unit* summonCheck;
                if(summonCheckTimer < diff)
                {
                    for(uint8 i = 1; i <= m_summons[0]; i++)
                    {
                         summonCheck = Unit::GetUnit((*m_creature),m_summons[i]);
                         if(summonCheck && summonCheck->isAlive())
                         {
                            phase = 1;
                            break;
                         }
                         else phase = 2;
                    }
                    summonCheckTimer = 2000;
                 }else summonCheckTimer -= diff;
             }
            DoMeleeAttackIfReady();
        }

        if(phase == 2 || phase == 3)
        {
            if(!nefarianGUID)
            {
                m_creature->GetMotionMaster()->Clear();
                m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
                m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);    //Invisible for event start
                DoCast(m_creature,8149);                                    //Make super invis
                //DoCast(m_creature,33356);                                 //Root self

                Creature* nefarian = m_creature->SummonCreature(CREATURE_NEFARIAN,NEF_X,NEF_Y,NEF_Z,0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,3600000);
                target = SelectUnit(SELECT_TARGET_TOPAGGRO,0);
                if(target && nefarian)
                {
                    nefarian->AI()->AttackStart(target);
                    nefarianGUID = nefarian->GetGUID();
                }
                else 
                    DoYell("UNABLE TO SPAWN NEF PROPERLY",LANG_UNIVERSAL,NULL);
                m_creature->CombatStop();
            }
            else
            {
                if(summonCheckTimer < diff && !(phase == 3))
                {
                    Unit* nefarian = Unit::GetUnit((*m_creature),nefarianGUID);
                    if(!nefarian || !nefarian->isAlive())
                    {
                        m_creature->Relocate(-7588.438477f,-1261.883789f,482.1f,0.849401f);
                        m_creature->SendMonsterMove(-7588.438477f,-1261.883789f,482.1f,0.849401f,true,0);
                        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 9472);     //Original DisplayId
                        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                        nefarianGUID = 0;
                        phase = 3;
                        m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);
                        phase = 0;
                        EnterEvadeMode();
                    }
                    else if( AIHPPercent(nefarian) < 21 && !respawnSummon)
                    {
                        respawnSummon = true;
                        Creature *summon;
                        srand(time(NULL));
                        for(uint8 n = 0; n < MAX_SUMMON; ++n)
                        {
                            if(irand(1,100) > 42)
                            {
                                summonIndex = irand(0,1);
                                summon = m_creature->SummonCreature(summonId[0],x[summonIndex],y[summonIndex],z[summonIndex],o[summonIndex],TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,3600000);
                                srand(time(NULL));
                                target = SelectUnit(SELECT_TARGET_RANDOM,0);
                                if(summon && target)
                                    summon->AI()->AttackStart(target);
                            }
                            else
                            {
                                for(summonIndex = 0; summonIndex < 1; summonIndex++)
                                {   
                                    summon = m_creature->SummonCreature(summonId[summonIndex+1],x[summonIndex],y[summonIndex],z[summonIndex],o[summonIndex],TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,3600000);
                                    srand(time(NULL));
                                    target = SelectUnit(SELECT_TARGET_RANDOM,0);
                                    if(summon && target)
                                        summon->AI()->AttackStart(target);
                                }
                            }
                        }
                    }
                    summonCheckTimer = 2000;
                }else summonCheckTimer -= diff;
            }
        }
    }
};


CreatureAI* GetAI_boss_victor_nefarius(Creature *_Creature)
{
    return new boss_victor_nefariusAI (_Creature);
}

bool GossipSelect_boss_victor_nefarius(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
    //Must have more text then that to tell
    if (action == GOSSIP_ACTION_INFO_DEF + 1)      //Fight time
    {
        player->PlayerTalkClass->CloseGossip();
        ((boss_victor_nefariusAI*)_Creature->AI())->BeginEvent(player);
    }

    return true;
}

bool GossipHello_boss_victor_nefarius(Player *player, Creature *_Creature)
{
    player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
    player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());

    return true;
}

void AddSC_boss_victor_nefarius()
{
    Script *newscript;
    newscript = new Script;
    newscript->Name="boss_victor_nefarius";
    newscript->GetAI = GetAI_boss_victor_nefarius;
    newscript->pGossipHello = &GossipHello_boss_victor_nefarius;
    newscript->pGossipSelect = &GossipSelect_boss_victor_nefarius;
    m_scripts[nrscripts++] = newscript;
}