/* Copyright (C) 2006,2007 ScriptDev2
* 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
*/
/******************************
* Another Script still *
* under development! *
******************************/
//Todo: Confirmation on Timers, see UpdateAI.
#include "../../../sc_defines.h"
#include "../../../../../../game/Player.h"
#include "../../../../../../game/GossipDef.h"
#define SOUND_INCOMING 11008 //Stay alert! Another wave approaches!
#define SOUND_DEATH 11010 //I did... My best.
#define SOUND_RALLY_ONE 11006 //Don't give up! We must prevail!
#define SOUND_RALLY_TWO 11050 //Hold them back as long as possible!
#define SOUND_RALLY_THREE 11051 //We must hold strong!
#define SOUND_ATTACKED_ONE 11007 //I'm in jeopardy! Help me if you can!
#define SOUND_ATTACKED_TWO 11049 //They've broken through!
#define SOUND_RETREAT 11009 //We are lost! Fall back!
#define SOUND_WIN 11011 //We have won valuable time! Now we must pull back!
#define GOSSIP_ITEM "Start first encounter "
#define GOSSIP_ITEM_TWO "Start second encounter "
#define GOSSIP_ITEM_THREE "Vanish Alliance NPCs "
#define CREATURE_ABOMINATION 17898
#define CREATURE_GHOUL 17895
#define CREATURE_SHADOWY_NECROMANCER 17899
#define CREATURE_CRYPT_FIEND 17897
//Todo: The other mobs for other encounter
#define CREATURE_RAGE_WINTERCHILL 17767
//Alot of coords, as we use random spots for spawning...
#define SPAWN_MIN_X 4900
#define SPAWN_MIN_Y -1675
//...btw, we use diff to simplify the rand() function...
#define SPAWN_DIFF_X 20
#define SPAWN_DIFF_Y 20
#define SPAWN_Z 1322
#define SPAWN_ORIENTATION 5.800
//...and we move to the camp (see void SpawnMonster()).
#define CAMP_MIN_X 5018
#define CAMP_MIN_Y -1745
#define CAMP_DIFF_X 17
#define CAMP_DIFF_Y 13
#define CAMP_Z 1324
//Todo: Spells for Jaina
//#define SPELL_SHADOWBOLT 21077
struct MANGOS_DLL_DECL npc_jaina_proudmooreAI : public ScriptedAI
{
npc_jaina_proudmooreAI(Creature *c) : ScriptedAI(c) {EnterEvadeMode();}
uint32 WaveTimer;
uint32 RageWinterchillGUID
uint32 TrashWave;
uint32 BossEncounter;
void EnterEvadeMode()
{
m_creature->RemoveAllAuras();
m_creature->DeleteThreatList();
m_creature->CombatStop();
DoGoHome();
if (BossEncounter != 1 && BossEncounter != 2 && BossEncounter != 3)
{
//No Encounter active, so we can talk to start first encounter.
BossEncounter = 0;
}
if (TrashWave != 10)
{
RageWinterchillGUID = 0;
}
}
void BeginEncounter(uint32 Encounter)
{
//10 secs before we start to spawn
WaveTimer = 10000;
//First trash wave coming up!
TrashWave = 1;
BossEncounter == Encounter;
}
void SpawnMonster(uint32 CreatureEntry)
{
Creature* Spawned = NULL;
//Use "random coords" to not let all mobs spawn at the same place
float SpawnX = (rand()%SPAWN_DIFF_X) + SPAWN_MIN_X;
float SpawnY = (rand()%SPAWN_DIFF_Y) + SPAWN_MIN_Y;
float SpawnZ = SPAWN_Z;
float SpawnOrientation = SPAWN_ORIENTATION;
Spawned = m_creature->SummonCreature(CreatureEntry,SpawnX,SpawnY,SpawnZ,SpawnOrientation,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000);
//Be sure to setFaction(1720) <--Hyjal Invaders
Spawned->setFaction(1720);
//Make them move towards the camp (random coords again)!
float CampX = (rand()%CAMP_DIFF_X) + CAMP_MIN_X;
float CampY = (rand()%CAMP_DIFF_Y) + CAMP_MIN_Y;
float CampZ = CAMP_Z;
//Oh wait, let's do some maths to calculate the time we need, thanks draenei script
float dx = CampX - SpawnX;
float dy = CampY - SpawnY;
float dz = CampZ - SpawnZ;
double dist = ::sqrt((dx*dx) + (dy*dy) + (dz*dz));
double speed = Spawned->GetSpeed(MOVE_RUN);
if(speed<=0)
speed = 2.5f;
speed *= 0.001f;
uint32 TotalTime = static_cast( dist/speed + 0.5 );
Spawned->SendMonsterMove(CampX,CampY,CampZ,0,true,TotalTime);
}
void AttackStart(Unit *who)
{
if (!who)
return;
if (who->isTargetableForAttack() && who!= m_creature)
{
//Begin melee attack if we are within range
DoStartMeleeAttack(who);
}
}
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 JustDied(Unit* Killer)
{
DoPlaySoundToSet(m_creature,SOUND_DEATH);
//Despawn all monsters
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//Check if we're gonna spawn a trash wave
if (WaveTimer < diff)
{
if (BossEncounter == 1)
{
switch (TrashWave)
{
case 1:
//First Wave, 10 Ghouls
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
TrashWave++;
WaveTimer = 85000;
break;
case 2:
//Second Wave, 10 Ghouls, 2 Crypt Fiends
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
DoPlaySoundToSet(m_creature,SOUND_INCOMING);
TrashWave++;
WaveTimer = 85000;
break;
case 3:
//Third Wave, 6 Ghouls, 6 Crypt Fiends
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
DoPlaySoundToSet(m_creature,SOUND_INCOMING);
TrashWave++;
WaveTimer = 100000;
break;
case 4:
//Fourth Wave, 6 Ghouls, 4 Crypt Fiends, 2 Necromancers
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
DoPlaySoundToSet(m_creature,SOUND_INCOMING);
TrashWave++;
WaveTimer = 115000;
break;
case 5:
//Fifth Wave, 2 Ghouls, 6 Crypt Fiends, 4 Necromancers
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
DoPlaySoundToSet(m_creature,SOUND_INCOMING);
TrashWave++;
WaveTimer = 125000;
break;
case 6:
//Sixth Wave, 6 Ghouls, 6 Abominations
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
DoPlaySoundToSet(m_creature,SOUND_INCOMING);
TrashWave++;
WaveTimer = 135000;
break;
case 7:
//Seventh Wave, 4 Ghouls, 4 Necromancers, 4 Abominations
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
DoPlaySoundToSet(m_creature,SOUND_INCOMING);
TrashWave++;
WaveTimer = 125000;
break;
case 8:
//Eigth Wave, 6 Ghouls, 4 Crypt Fiends, 2 Abominations, 2 Necromancers
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_GHOUL);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_CRYPT_FIEND);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_ABOMINATION);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
SpawnMonster(CREATURE_SHADOWY_NECROMANCER);
DoPlaySoundToSet(m_creature,SOUND_INCOMING);
TrashWave++;
//Totally unsure about this Timer, let's be nice and give players 2:30min
WaveTimer = 150000;
break;
case 9:
//Ninth "Wave", Rage Winterchill!
Creature* RageWinterchillSpawn = NULL;
RageWinterchillSpawn = SpawnMonster(CREATURE_RAGE_WINTERCHILL);
RageWinterchillGUID = RageWinterchillSpawn->GetGUID();
TrashWave = 10;
WaveTimer = 0;
break;
}
}
else if (BossEncounter == 3)
{
//Anetheron part here
}
}else WaveTimer -= diff;
if (BossEncounter == 1 && TrashWave == 10)
{
Unit* RageWinterchill = NULL;
RageWinterchill = Unit::GetUnit((*m_creature),RageWinterchillGUID);
if(!RageWinterchill || !RageWinterchill->isAlive())
{
RageWinterchillGUID = 0;
BossEncounter = 3;
TrashWave = 0;
}
}
}
};
CreatureAI* GetAI_npc_jaina_proudmoore(Creature *_Creature)
{
return new npc_jaina_proudmooreAI (_Creature);
}
bool GossipSelect_npc_jaina_proudmoore(Player *player, Creature *_Creature, uint32 sender, uint32 action )
{
if (action == GOSSIP_ACTION_INFO_DEF + 1)//Fight time
{
player->PlayerTalkClass->CloseGossip();
((npc_jaina_proudmooreAI*)_Creature->AI())->BeginEncounter(1);
}
else if (action == GOSSIP_ACTION_INFO_DEF + 2)//Fight time
{
player->PlayerTalkClass->CloseGossip();
((npc_jaina_proudmooreAI*)_Creature->AI())->BeginEncounter(3);
}
return true;
}
bool GossipHello_npc_jaina_proudmoore(Player *player, Creature *_Creature)
{
if (((npc_jaina_proudmooreAI*)_Creature->AI())->BossEncounter == 0)
{
//ADD_GOSSIP_ITEM points to AddMenuItem
player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
//first in fuction points to npc_text table
player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());
}
else if (((npc_jaina_proudmooreAI*)_Creature->AI())->BossEncounter == 3)
{
//ADD_GOSSIP_ITEM points to AddMenuItem
player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM_TWO , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
//first in fuction points to npc_text table
player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());
}
else if (((npc_jaina_proudmooreAI*)_Creature->AI())->BossEncounter == 5)
{
//ADD_GOSSIP_ITEM points to AddMenuItem
player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM_THREE , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
//first in fuction points to npc_text table
player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID());
}
return true;
}
void AddSC_npc_jaina_proudmoore()
{
Script *newscript;
newscript = new Script;
newscript->Name="npc_jaina_proudmoore";
newscript->GetAI = GetAI_npc_jaina_proudmoore;
newscript->pGossipHello = &GossipHello_npc_jaina_proudmoore;
newscript->pGossipSelect = &GossipSelect_npc_jaina_proudmoore;
m_scripts[nrscripts++] = newscript;
}