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