rendered paste bodyIndex: npc_victor_nefarius.cpp===================================================================--- npc_victor_nefarius.cpp (revision 134)+++ npc_victor_nefarius.cpp (working copy)@@ -17,12 +17,15 @@ #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>" @@ -31,9 +34,17 @@ #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@@ -52,7 +63,10 @@ #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@@ -62,125 +76,104 @@ //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) - {- NefarianGUID = 0;- EnterEvadeMode();- srand(time(NULL));- switch (rand()%20)- {- case 0:- DrakType1 = CREATURE_BRONZE_DRAKANOID;- DrakType2 = CREATURE_BLUE_DRAKANOID;- break;- case 1:- DrakType1 = CREATURE_BRONZE_DRAKANOID;- DrakType2 = CREATURE_RED_DRAKANOID;- break;- case 2:- DrakType1 = CREATURE_BRONZE_DRAKANOID;- DrakType2 = CREATURE_GREEN_DRAKANOID;- break;- case 3:- DrakType1 = CREATURE_BRONZE_DRAKANOID;- DrakType2 = CREATURE_BLACK_DRAKANOID;- break;- case 4:- DrakType1 = CREATURE_BLUE_DRAKANOID;- DrakType2 = CREATURE_BRONZE_DRAKANOID;- break;- case 5:- DrakType1 = CREATURE_BLUE_DRAKANOID;- DrakType2 = CREATURE_RED_DRAKANOID;- break;- case 6:- DrakType1 = CREATURE_BLUE_DRAKANOID;- DrakType2 = CREATURE_GREEN_DRAKANOID;- break;- case 7:- DrakType1 = CREATURE_BLUE_DRAKANOID;- DrakType2 = CREATURE_BLACK_DRAKANOID;- break;- case 8:- DrakType1 = CREATURE_RED_DRAKANOID;- DrakType2 = CREATURE_BRONZE_DRAKANOID;- break;- case 9:- DrakType1 = CREATURE_RED_DRAKANOID;- DrakType2 = CREATURE_BLUE_DRAKANOID;- break;- case 10:- DrakType1 = CREATURE_RED_DRAKANOID;- DrakType2 = CREATURE_GREEN_DRAKANOID;- break;- case 11:- DrakType1 = CREATURE_RED_DRAKANOID;- DrakType2 = CREATURE_BLACK_DRAKANOID;- break;- case 12:- DrakType1 = CREATURE_GREEN_DRAKANOID;- DrakType2 = CREATURE_BRONZE_DRAKANOID;- break;- case 13:- DrakType1 = CREATURE_GREEN_DRAKANOID;- DrakType2 = CREATURE_BLUE_DRAKANOID;- break;- case 14:- DrakType1 = CREATURE_GREEN_DRAKANOID;- DrakType2 = CREATURE_RED_DRAKANOID;- break;- case 15:- DrakType1 = CREATURE_GREEN_DRAKANOID;- DrakType2 = CREATURE_BLACK_DRAKANOID;- break;- case 16:- DrakType1 = CREATURE_BLACK_DRAKANOID;- DrakType2 = CREATURE_BRONZE_DRAKANOID;- break;- case 17:- DrakType1 = CREATURE_BLACK_DRAKANOID;- DrakType2 = CREATURE_BLUE_DRAKANOID;- break;- case 18:- DrakType1 = CREATURE_BLACK_DRAKANOID;- DrakType2 = CREATURE_GREEN_DRAKANOID;- break;- case 19:- DrakType1 = CREATURE_BLACK_DRAKANOID;- DrakType2 = CREATURE_RED_DRAKANOID;- break;- }- }+ boss_victor_nefariusAI(Creature *c) : ScriptedAI(c) { EnterEvadeMode(); } - uint32 SpawnedAdds;- uint32 AddSpawnTimer;- uint32 ShadowBoltTimer;- uint32 MindControlTimer;- uint32 ResetTimer;- uint32 DrakType1;- uint32 DrakType2;- uint64 NefarianGUID;- uint32 NefCheckTime;+ 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() {- SpawnedAdds = 0;- AddSpawnTimer = 10000;- ShadowBoltTimer = 5000;- ResetTimer = 60000; //On official it takes him 15 minutes(900 seconds) to reset. We are only doing 1 minute to make testing easier- NefarianGUID = 0;- NefCheckTime = 2000;+ 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();- DoGoHome();+ m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 9472); //Original One m_creature->SetUInt32Value(UNIT_NPC_FLAGS,1);- m_creature->setFaction(35);+ m_creature->setFaction(35); //Friendly m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);+ DoGoHome(); } void BeginEvent(Player* target)@@ -197,6 +190,7 @@ 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);@@ -206,13 +200,12 @@ void AttackStart(Unit *who) {- if (!who)+ if(!who) return; if (who->isTargetableForAttack() && who!= m_creature) {- //Begin melee attack if we are within range- DoStartMeleeAttack(who);+ DoStartMeleeAttack(who);// Don't think is needed for him since he never really attack. } } @@ -227,128 +220,186 @@ } } + + 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) {- //Return since we have no target- if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )+ if(!m_creature->isAlive()) return; - //Only do this if we haven't spawned nef yet- if (SpawnedAdds < 42)+ Unit* target;+ uint8 summonIndex;+ if(phase == 1) {- //ShadowBoltTimer- if (ShadowBoltTimer < diff)+ if( m_creature->SelectHostilTarget() && m_creature->getVictim()) {- //Cast- Unit* target = NULL;+ 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)- DoCast(target,SPELL_SHADOWBOLT);+ if(!target)+ return; - //Random time till recast between 3 and 10 seconds- ShadowBoltTimer = 3000 + (rand()%7000);- }else ShadowBoltTimer -= diff;+ 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; - //Add spawning mechanism- if (AddSpawnTimer < diff)- {- //Spawn 2 random types of creatures at the 2 locations- uint32 CreatureID;- Creature* Spawned = NULL;- Unit* target = NULL;+ if( shadowBoltTimer < diff ) //ShadowBoltTimer+ {+ DoCast(target,SPELL_SHADOWBOLT);+ shadowBoltTimer = irand(7000,10000);+ }else shadowBoltTimer -= diff; - //1 in 3 chance it will be a chromatic- if (rand()%3 == 0)- CreatureID = CREATURE_CHROMATIC_DRAKANOID;- else CreatureID = DrakType1;-- SpawnedAdds++;-- //Spawn creature and force it to start attacking a random target- Spawned = m_creature->SummonCreature(CreatureID,ADD_X1,ADD_Y1,ADD_Z1,5.000,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);- target = SelectUnit(SELECT_TARGET_RANDOM,0);- if (target && Spawned)+ if( mindControlTimer < diff ) //ShadowBoltTimer {- Spawned->AI()->AttackStart(target);- Spawned->setFaction(103);- }+ DoCast(target,SPELL_MINDCONTROL);+ mindControlTimer = irand(7000,10000);+ }else mindControlTimer -= diff; - //1 in 3 chance it will be a chromatic- if (rand()%3 == 0)- CreatureID = CREATURE_CHROMATIC_DRAKANOID;- else CreatureID = DrakType2;-- SpawnedAdds++;-- target = NULL;- Spawned = NULL;- Spawned = m_creature->SummonCreature(CreatureID,ADD_X2,ADD_Y2,ADD_Z2,5.000,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);- target = SelectUnit(SELECT_TARGET_RANDOM,0);- if (target && Spawned)+ Creature *summon;+ if( summonTimer < diff && m_summons[0] < MAX_SUMMON) //Add spawning mechanism {- Spawned->AI()->AttackStart(target);- Spawned->setFaction(103);- }+ 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; - //Begin phase 2 by spawning Nefarian and what not- if (SpawnedAdds >= 42)+ Unit* summonCheck;+ if(summonCheckTimer < diff) {- //Teleport Victor Nefarius way out of the map- //MapManager::Instance().GetMap(m_creature->GetMapId(), m_creature)->CreatureRelocation(m_creature,0,0,-5000,0);-- //Inturrupt any spell casting- m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);-- //Root self- DoCast(m_creature,33356);-- //Make super invis- DoCast(m_creature,8149);-- //Teleport self to a hiding spot (this causes errors in the mangos log but no real issues)- m_creature->Relocate(HIDE_X,HIDE_Y,HIDE_Z,0);- m_creature->SendMonsterMove(HIDE_X,HIDE_Y,HIDE_Z,0,true,0);- m_creature->addUnitState(UNIT_STAT_FLEEING);-- //Spawn nef and have him attack a random target- Creature* Nefarian = NULL;- Nefarian = m_creature->SummonCreature(CREATURE_NEFARIAN,NEF_X,NEF_Y,NEF_Z,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000);- target = NULL;- target = SelectUnit(SELECT_TARGET_RANDOM,0);- if (target && Nefarian)+ for(uint8 i = 1; i <= m_summons[0]; i++) {- Nefarian->AI()->AttackStart(target);- Nefarian->setFaction(103);- NefarianGUID = Nefarian->GetGUID();+ summonCheck = Unit::GetUnit((*m_creature),m_summons[i]);+ if(summonCheck && summonCheck->isAlive())+ {+ phase = 1;+ break;+ }+ else phase = 2; }- else DoYell("UNABLE TO SPAWN NEF PROPERLY",LANG_UNIVERSAL,NULL);- }+ summonCheckTimer = 2000;+ }else summonCheckTimer -= diff;+ }+ DoMeleeAttackIfReady();+ } - AddSpawnTimer = 5000;- }else AddSpawnTimer -= diff;- }- else if (NefarianGUID)+ if(phase == 2 || phase == 3) {- if (NefCheckTime < diff)+ if(!nefarianGUID) {- Unit* Nefarian = NULL;- Nefarian = Unit::GetUnit((*m_creature),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 - //If nef is dead then we die to so the players get out of combat- //and cannot repeat the event- if (!Nefarian || !Nefarian->isAlive())+ 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) {- NefarianGUID = 0;- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, 0, false);+ nefarian->AI()->AttackStart(target);+ nefarianGUID = nefarian->GetGUID(); }-- NefCheckTime = 2000;- }else NefCheckTime -= diff;-+ 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);@@ -356,7 +407,8 @@ bool GossipSelect_boss_victor_nefarius(Player *player, Creature *_Creature, uint32 sender, uint32 action ) {- if (action == GOSSIP_ACTION_INFO_DEF + 1)//Fight time+ //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);