*Update Emalon the Storm Watcher script. By riddick

--HG--
branch : trunk
This commit is contained in:
megamage
2009-08-15 14:36:15 -05:00
parent e03b7cd4d7
commit 3269f47b5b
3 changed files with 199 additions and 210 deletions

View File

@@ -1,108 +1,93 @@
#include "precompiled.h"
#include "def_vault_of_archavon.h"
#define EMOTE_OVERCHARGE_TEMPEST_MINION -1590000
#define EMOTE_MINION_RESPAWN -1590001
//Emalon spells
#define SPELL_CHAIN_LIGHTNING HEROIC(64213, 64215)
#define SPELL_LIGHTNING_NOVA HEROIC(64216, 65279)
#define SPELL_OVERCHARGE 64218 //Casted every 45 sec on a random Tempest Minion
#define SPELL_BERSERK 26662
//Spells Emalon
#define SPELL_CHAIN_LIGHTNING HEROIC(64213,64215)
#define SPELL_LIGHTNING_NOVA HEROIC(64216,65279)
#define SPELL_OVERCHARGE 64218
#define SPELL_BERSERK 47008
//Tempest Minion spells
#define SPELL_SHOCK 64363
#define SPELL_OVERCHARGED 64217
#define SPELL_OVERCHARGED_BLAST 64219 //Casted when Overcharged reaches 10 stacks. Mob dies after that
//Spells Tempest Minions
#define SPELL_OVERCHARGED 64217
#define SPELL_OVERCHARGED_BLAST 64219
#define SPELL_SHOCK 64363
//Emotes
#define EMOTE_OVERCHARGE -1590000
#define EMOTE_MINION_RESPAWN -1590001
#define EMOTE_BERSERK -1590002
//4 Warders spawned
#define TEMPEST_MINIONS 33998
//Events
#define EVENT_CHAIN_LIGHTNING 1
#define EVENT_LIGHTNING_NOVA 2
#define EVENT_OVERCHARGE 3
#define EVENT_BERSERK 4
#define EVENT_SHOCK 5
#define EVENT_CHAIN_LIGHTNING 1 //5s cd
#define EVENT_OVERCHARGE 2 //45s cd
#define EVENT_LIGHTNING_NOVA 3 //40s cd
#define EVENT_BERSERK 4 //360s cd
#define EVENT_SHOCK 5 //20s cd
//Creatures
#define MOB_TEMPEST_MINION 33998
struct Location
float TempestMinions[4][5] =
{
float x, y, z, o;
};
static Location MinionLocation[]=
{
-231.713,-281.96,91.466,1.53213,
-205.585,-281.549,91.4661,1.75204,
-205.651,-296.394,91.4661,1.69549,
-232.235,-296.433,91.4998,1.44417
{33998, -203.980103, -281.287720, 91.650223, 1.598807},
{33998, -233.489410, -281.139282, 91.652412, 1.598807},
{33998, -233.267578, -297.104645, 91.681915, 1.598807},
{33998, -203.842529, -297.097015, 91.745163, 1.598807}
};
/*######
## Emalon the Storm Watcher
######*/
struct TRINITY_DLL_DECL boss_emalonAI : public ScriptedAI
{
boss_emalonAI(Creature *c) : ScriptedAI(c)
boss_emalonAI(Creature *c) : ScriptedAI(c), summons(m_creature)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
EventMap events;
std::list<uint64> MinionList;
SummonList summons;
void Reset()
{
{
events.Reset();
DespawnAllMinions();
SummonAllMinions();
if (pInstance)
pInstance->SetData(DATA_EMALON_EVENT, NOT_STARTED);
}
void DespawnAllMinions()
{
if (!MinionList.empty())
{
for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); itr++)
{
if (Creature *Minion = Unit::GetCreature(*m_creature, (*itr)))
Minion->DisappearAndDie();
}
}
summons.DespawnAll();
MinionList.clear();
Creature* Minion;
for (uint32 i = 0; i < 4; ++i)
{
Minion = m_creature->SummonCreature(((uint32)TempestMinions[i][0]),TempestMinions[i][1],TempestMinions[i][2],TempestMinions[i][3],TempestMinions[i][4],TEMPSUMMON_DEAD_DESPAWN, 0);
MinionList.push_back(Minion->GetGUID());
if(Unit* target = m_creature->getVictim())
Minion->AI()->AttackStart(target);
}
if (pInstance)
pInstance->SetData(DATA_EMALON_EVENT, NOT_STARTED);
}
void JustSummoned(Creature *Summoned)
void JustSummoned(Creature* summoned)
{
MinionList.push_back(Summoned->GetGUID());
if (Unit* target = m_creature->getVictim())
Summoned->AI()->AttackStart(target);
summons.Summon(summoned);
}
void SummonAllMinions()
{
if (MinionList.empty())
for(uint8 i = 0; i < 4; ++i)
SummonMinion(m_creature, MinionLocation[i].x, MinionLocation[i].y, MinionLocation[i].z, MinionLocation[i].o);
}
static void SummonMinion(Creature *Summoner, float x, float y, float z, float o)
{
Summoner->SummonCreature(TEMPEST_MINIONS, x, y, z, o, TEMPSUMMON_DEAD_DESPAWN, 0);
}
void KilledUnit(Unit* Victim){}
void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);}
void JustDied(Unit* Killer)
{
DespawnAllMinions();
summons.DespawnAll();
if (pInstance)
pInstance->SetData(DATA_EMALON_EVENT, DONE);
}
void EnterCombat(Unit *who)
{
if (!MinionList.empty())
if(!MinionList.empty())
{
for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr)
{
@@ -113,69 +98,51 @@ struct TRINITY_DLL_DECL boss_emalonAI : public ScriptedAI
DoZoneInCombat();
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5000);
events.ScheduleEvent(EVENT_OVERCHARGE, 45000);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 30000);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40000);
events.ScheduleEvent(EVENT_BERSERK, 360000);
events.ScheduleEvent(EVENT_SHOCK, 20000);
events.ScheduleEvent(EVENT_OVERCHARGE, 45000);
if (pInstance)
pInstance->SetData(DATA_EMALON_EVENT, IN_PROGRESS);
pInstance->SetData(DATA_EMALON_EVENT, IN_PROGRESS);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
if(!UpdateVictim())
return;
events.Update(diff);
if (me->hasUnitState(UNIT_STAT_CASTING))
return;
if(me->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_CHAIN_LIGHTNING:
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_CHAIN_LIGHTNING);
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 20000);
return;
case EVENT_OVERCHARGE:
for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr)
{
Creature* Minion = (Unit::GetCreature(*m_creature, *itr));
if (Minion && Minion->isAlive() && !Minion->HasAura(SPELL_OVERCHARGED))
{
Minion->CastSpell(me, SPELL_OVERCHARGED, true);
Minion->SetHealth(Minion->GetMaxHealth());
DoScriptText(EMOTE_OVERCHARGE_TEMPEST_MINION, m_creature);
events.ScheduleEvent(EVENT_OVERCHARGE, 45000);
return;
}
}
case EVENT_LIGHTNING_NOVA:
DoCast(me->getVictim(), SPELL_LIGHTNING_NOVA);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 25000);
return;
case EVENT_SHOCK:
for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr)
{
Creature* Minion = (Unit::GetCreature(*m_creature, *itr));
if (Minion && Minion->isAlive())
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
Minion->CastSpell(target, SPELL_SHOCK, true);
events.ScheduleEvent(EVENT_SHOCK, 20000);
return;
}
}
}
case EVENT_BERSERK:
DoCast(m_creature, SPELL_BERSERK);
return;
case EVENT_CHAIN_LIGHTNING:
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_CHAIN_LIGHTNING);
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 25000);
return;
case EVENT_LIGHTNING_NOVA:
DoCastAOE(SPELL_LIGHTNING_NOVA, false);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40000);
return;
case EVENT_OVERCHARGE:
if(Creature* Minion = GetClosestCreatureWithEntry(me, MOB_TEMPEST_MINION, 1000.0f))
{
Minion->CastSpell(me, SPELL_OVERCHARGED, true);
Minion->SetHealth(Minion->GetMaxHealth());
DoScriptText(EMOTE_OVERCHARGE, m_creature);
}
events.ScheduleEvent(EVENT_OVERCHARGE, 45000);
return;
case EVENT_BERSERK:
DoCast(m_creature, SPELL_BERSERK);
DoScriptText(EMOTE_BERSERK, m_creature);
return;
}
}
@@ -184,11 +151,11 @@ struct TRINITY_DLL_DECL boss_emalonAI : public ScriptedAI
};
/*######
## Mob Tempest Minions
## Tempest Minion
######*/
struct TRINITY_DLL_DECL mob_tempest_minionAI : public ScriptedAI
{
mob_tempest_minionAI(Creature *c) : ScriptedAI(c)
mob_tempest_minionAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
EmalonGUID = pInstance ? pInstance->GetData64(DATA_EMALON) : 0;
@@ -196,74 +163,100 @@ struct TRINITY_DLL_DECL mob_tempest_minionAI : public ScriptedAI
}
ScriptedInstance* pInstance;
EventMap events;
uint64 EmalonGUID;
std::list<Creature*> MinionList;
Creature* Emalon;
uint32 SPELL_OVERCHARGED_Timer;
bool AlreadyOvercharged;
uint32 OverchargedTimer;
void Reset()
{
events.Reset();
AlreadyOvercharged = false;
SPELL_OVERCHARGED_Timer = 0;
OverchargedTimer = 0;
}
void JustDied(Unit* Killer)
{
Creature* Emalon;
Emalon = Unit::GetCreature(*m_creature, EmalonGUID);
float x,y,z;
Emalon->GetPosition(x,y,z);
Emalon->SummonCreature(MOB_TEMPEST_MINION,x,y,z,m_creature->GetOrientation(),TEMPSUMMON_DEAD_DESPAWN,0);
DoScriptText(EMOTE_MINION_RESPAWN, m_creature);
}
void EnterCombat(Unit *who)
{
DoZoneInCombat();
if (Emalon)
Emalon->AI()->AttackStart(who);
}
events.ScheduleEvent(EVENT_SHOCK, 20000);
void JustDied(Unit* Killer)
{
m_creature->DisappearAndDie();
if (Emalon)
{
boss_emalonAI::SummonMinion(Emalon, Emalon->GetPositionX(), Emalon->GetPositionY(), Emalon->GetPositionZ(), Emalon->GetOrientation());
DoScriptText(EMOTE_MINION_RESPAWN, m_creature);
}
if(Emalon)
Emalon->AI()->AttackStart(who);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if(!UpdateVictim())
return;
if (Aura *OverchargedAura = m_creature->GetAura(SPELL_OVERCHARGED))
events.Update(diff);
if(me->hasUnitState(UNIT_STAT_CASTING))
return;
if(Aura *OverchargedAura = m_creature->GetAura(SPELL_OVERCHARGED))
{
if (OverchargedAura->GetStackAmount() < 10)
if(OverchargedAura->GetStackAmount() < 10)
{
if (SPELL_OVERCHARGED_Timer < diff)
if(OverchargedTimer < diff)
{
DoCast(me, SPELL_OVERCHARGED);
SPELL_OVERCHARGED_Timer = 2000;
}else SPELL_OVERCHARGED_Timer -=diff;
OverchargedTimer = 2000;
}else OverchargedTimer -=diff;
}
else
{
if (OverchargedAura->GetStackAmount() == 10 && (AlreadyOvercharged == false))
if(OverchargedAura->GetStackAmount() == 10)
{
DoCast(me,SPELL_OVERCHARGED_BLAST);
AlreadyOvercharged = true;
m_creature->setDeathState(JUST_DIED);
Creature* Emalon;
Emalon = Unit::GetCreature(*m_creature, EmalonGUID);
float x,y,z;
Emalon->GetPosition(x,y,z);
Emalon->SummonCreature(MOB_TEMPEST_MINION,x,y,z,m_creature->GetOrientation(),TEMPSUMMON_DEAD_DESPAWN,0);
DoScriptText(EMOTE_MINION_RESPAWN, m_creature);
}
}
}
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_SHOCK:
DoCast(me->getVictim(), SPELL_SHOCK);
events.ScheduleEvent(EVENT_SHOCK, 20000);
return;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_tempest_minion(Creature* pCreature)
CreatureAI* GetAI_mob_tempest_minion(Creature *_Creature)
{
return new mob_tempest_minionAI (pCreature);
return new mob_tempest_minionAI (_Creature);
}
CreatureAI* GetAI_boss_emalon(Creature* pCreature)
CreatureAI* GetAI_boss_emalon(Creature *_Creature)
{
return new boss_emalonAI (pCreature);
return new boss_emalonAI (_Creature);
}
void AddSC_boss_emalon()

View File

@@ -1,13 +1,8 @@
#ifndef DEF_ARCHAVON_H
#define DEF_ARCHAVON_H
enum
{
DATA_ARCHAVON = 1,
DATA_EMALON = 2,
DATA_ARCHAVON_EVENT = 3,
DATA_EMALON_EVENT = 4
};
#define DATA_ARCHAVON_EVENT 1
#define DATA_EMALON_EVENT 2
#define DATA_EMALON 3
#define DATA_ARCHAVON 4
#endif

View File

@@ -1,116 +1,117 @@
#include "precompiled.h"
#include "def_vault_of_archavon.h"
#define NUMBER_OF_ENCOUNTERS 2
#define ENCOUNTERS 2
/* Vault of Archavon encounters:
1 - Archavon the Stone Watcher event
2 - Emalon the Storm Watcher event
*/
struct TRINITY_DLL_DECL instance_archavon : public ScriptedInstance
{
instance_archavon(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
instance_archavon(Map *Map) : ScriptedInstance(Map) {Initialize();};
uint32 Encounters[ENCOUNTERS];
std::string strInstData;
uint64 Archavon;
uint64 Emalon;
uint32 m_auiEncounter[NUMBER_OF_ENCOUNTERS];
void Initialize()
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
{
Archavon = 0;
Emalon = 0;
for(uint8 i = 0; i < ENCOUNTERS; i++)
Encounters[i] = NOT_STARTED;
}
bool IsEncounterInProgress() const
{
for(uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
return true;
for(uint8 i = 0; i < ENCOUNTERS; i++)
if(Encounters[i] == IN_PROGRESS) return true;
return false;
}
void OnCreatureCreate(Creature* pCreature, bool add)
void OnCreatureCreate(Creature *creature, bool add)
{
switch(pCreature->GetEntry())
switch(creature->GetEntry())
{
case 31125: Archavon = pCreature->GetGUID(); break;
case 33993: Emalon = pCreature->GetGUID(); break;
case 31125: Archavon = creature->GetGUID(); break;
case 33993: Emalon = creature->GetGUID(); break;
}
}
uint32 GetData(uint32 type)
{
switch(type)
{
case DATA_ARCHAVON_EVENT: return Encounters[0];
case DATA_EMALON_EVENT: return Encounters[1];
}
return 0;
}
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
case DATA_ARCHAVON: return Archavon;
case DATA_EMALON: return Emalon;
case DATA_ARCHAVON: return Archavon;
case DATA_EMALON: return Emalon;
}
return 0;
}
uint32 GetData(uint32 identifier)
void SetData(uint32 type, uint32 data)
{
switch(identifier)
switch(type)
{
case DATA_ARCHAVON_EVENT: return m_auiEncounter[0];
case DATA_EMALON_EVENT: return m_auiEncounter[1];
}
return 0;
}
void SetData(uint32 identifier, uint32 data)
{
switch(identifier)
{
case DATA_ARCHAVON_EVENT: m_auiEncounter[0] = data; break;
case DATA_EMALON_EVENT: m_auiEncounter[1] = data; break;
case DATA_ARCHAVON_EVENT: Encounters[0] = data; break;
case DATA_EMALON_EVENT: Encounters[1] = data; break;
}
if (data == DONE)
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1];
strInstData = saveStream.str();
if(data == DONE)
SaveToDB();
OUT_SAVE_INST_DATA_COMPLETE;
}
}
std::string GetSaveData()
{
return strInstData;
OUT_SAVE_INST_DATA;
std::ostringstream stream;
stream << Encounters[0] << " " << Encounters[1];
char* out = new char[stream.str().length() + 1];
strcpy(out, stream.str().c_str());
if(out)
{
OUT_SAVE_INST_DATA_COMPLETE;
return out;
}
return NULL;
}
void Load(const char* chrIn)
void Load(const char* in)
{
if (!chrIn)
if(!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(chrIn);
std::istringstream loadStream(chrIn);
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1];
for(uint8 i = 1; i < NUMBER_OF_ENCOUNTERS; ++i)
{
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
}
OUT_LOAD_INST_DATA(in);
std::istringstream stream(in);
stream >> Encounters[0] >> Encounters[1];
for(uint8 i = 0; i < ENCOUNTERS; ++i)
if(Encounters[i] == IN_PROGRESS)
Encounters[i] = NOT_STARTED;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_archavon(Map* pMap)
InstanceData* GetInstanceData_instance_archavon(Map* map)
{
return new instance_archavon(pMap);
return new instance_archavon(map);
}
void AddSC_instance_archavon()