Fix Script VoA/Emalon.

- fix handling of minions' list so the overcharge does not fail due to dead minion in the list.

--HG--
branch : trunk
This commit is contained in:
Trazom62
2010-01-24 21:57:33 +01:00
parent 523dae2f63
commit 41fb791f1f
@@ -29,7 +29,7 @@
#define MAX_TEMPEST_MINIONS 4 #define MAX_TEMPEST_MINIONS 4
float TempestMinions[4][4] = struct Position TempestMinions[MAX_TEMPEST_MINIONS] =
{ {
{-203.980103, -281.287720, 91.650223, 1.598807}, {-203.980103, -281.287720, 91.650223, 1.598807},
{-233.489410, -281.139282, 91.652412, 1.598807}, {-233.489410, -281.139282, 91.652412, 1.598807},
@@ -40,93 +40,57 @@ float TempestMinions[4][4] =
/*###### /*######
## Emalon the Storm Watcher ## Emalon the Storm Watcher
######*/ ######*/
struct TRINITY_DLL_DECL boss_emalonAI : public ScriptedAI struct TRINITY_DLL_DECL boss_emalonAI : public BossAI
{ {
boss_emalonAI(Creature *c) : ScriptedAI(c) boss_emalonAI(Creature *c) : BossAI(c, DATA_EMALON_EVENT)
{ {
pInstance = c->GetInstanceData();
} }
ScriptedInstance* pInstance;
EventMap events;
std::list<uint64> MinionList;
void Reset() void Reset()
{ {
events.Reset(); _Reset();
DespawnAllMinions();
for (uint8 i = 0; i < MAX_TEMPEST_MINIONS; ++i) for (uint8 i = 0; i < MAX_TEMPEST_MINIONS; ++i)
m_creature->SummonCreature(MOB_TEMPEST_MINION, TempestMinions[i][0], TempestMinions[i][1], TempestMinions[i][2], TempestMinions[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0); m_creature->SummonCreature(MOB_TEMPEST_MINION, TempestMinions[i], TEMPSUMMON_CORPSE_DESPAWN, 0);
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++)
{
Creature *Minion = Unit::GetCreature(*m_creature, *itr);
if(Minion && Minion->isAlive())
Minion->ForcedDespawn();
}
}
MinionList.clear();
} }
void JustSummoned(Creature *summoned) void JustSummoned(Creature *summoned)
{ {
MinionList.push_back(summoned->GetGUID()); BossAI::JustSummoned(summoned);
if(m_creature->getVictim()) if (m_creature->getVictim() && summoned->AI())
summoned->AI()->AttackStart(m_creature->getVictim()); summoned->AI()->AttackStart(m_creature->getVictim());
} }
void JustDied(Unit* Killer)
{
DespawnAllMinions();
if (pInstance)
pInstance->SetData(DATA_EMALON_EVENT, DONE);
}
void EnterCombat(Unit *who) void EnterCombat(Unit *who)
{ {
if(!MinionList.empty()) if (!summons.empty())
{ {
for (std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr) for (std::list<uint64>::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
{ {
Creature *Minion = Unit::GetCreature(*m_creature, *itr); Creature *minion = Unit::GetCreature(*m_creature, *itr);
if(Minion && Minion->isAlive() && !Minion->getVictim()) if (minion && minion->isAlive() && !minion->getVictim() && minion->AI())
Minion->AI()->AttackStart(who); minion->AI()->AttackStart(who);
} }
} }
DoZoneInCombat();
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5000); events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5000);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40000); events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40000);
events.ScheduleEvent(EVENT_BERSERK, 360000); events.ScheduleEvent(EVENT_BERSERK, 360000);
events.ScheduleEvent(EVENT_OVERCHARGE, 45000); events.ScheduleEvent(EVENT_OVERCHARGE, 45000);
if (pInstance) _EnterCombat();
pInstance->SetData(DATA_EMALON_EVENT, IN_PROGRESS);
} }
void UpdateAI(const uint32 diff) void UpdateAI(const uint32 diff)
{ {
//Return since we have no target //Return since we have no target
if(!UpdateVictim()) if (!UpdateVictim())
return; return;
events.Update(diff); events.Update(diff);
if(me->hasUnitState(UNIT_STAT_CASTING)) if (me->hasUnitState(UNIT_STAT_CASTING))
return; return;
while(uint32 eventId = events.ExecuteEvent()) while(uint32 eventId = events.ExecuteEvent())
@@ -137,30 +101,30 @@ struct TRINITY_DLL_DECL boss_emalonAI : public ScriptedAI
if(Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) if(Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
DoCast(pTarget, SPELL_CHAIN_LIGHTNING); DoCast(pTarget, SPELL_CHAIN_LIGHTNING);
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 25000); events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 25000);
return; break;
case EVENT_LIGHTNING_NOVA: case EVENT_LIGHTNING_NOVA:
DoCastAOE(SPELL_LIGHTNING_NOVA, false); DoCastAOE(SPELL_LIGHTNING_NOVA, false);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40000); events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40000);
return; break;
case EVENT_OVERCHARGE: case EVENT_OVERCHARGE:
if(!MinionList.empty()) if (!summons.empty())
{ {
std::list<uint64>::const_iterator itr = MinionList.begin(); std::list<uint64>::const_iterator itr = summons.begin();
std::advance(itr, rand() % MinionList.size()); std::advance(itr, urand(0, summons.size()-1));
Creature *Minion = Unit::GetCreature(*m_creature, *itr); Creature *minion = Unit::GetCreature(*m_creature, *itr);
if(Minion && Minion->isAlive()) if (minion && minion->isAlive())
{ {
Minion->CastSpell(me, SPELL_OVERCHARGED, true); minion->CastSpell(me, SPELL_OVERCHARGED, true);
Minion->SetHealth(Minion->GetMaxHealth()); minion->SetHealth(minion->GetMaxHealth());
DoScriptText(EMOTE_OVERCHARGE, m_creature); DoScriptText(EMOTE_OVERCHARGE, m_creature);
events.ScheduleEvent(EVENT_OVERCHARGE, 45000); events.ScheduleEvent(EVENT_OVERCHARGE, 45000);
} }
} }
return; break;
case EVENT_BERSERK: case EVENT_BERSERK:
DoCast(m_creature, SPELL_BERSERK); DoCast(m_creature, SPELL_BERSERK);
DoScriptText(EMOTE_BERSERK, m_creature); DoScriptText(EMOTE_BERSERK, m_creature);
return; break;
} }
} }
@@ -176,31 +140,31 @@ 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(); pInstance = c->GetInstanceData();
EmalonGUID = pInstance ? pInstance->GetData64(DATA_EMALON) : 0; uiEmalonGUID = pInstance ? pInstance->GetData64(DATA_EMALON) : 0;
Emalon = Unit::GetCreature(*m_creature, EmalonGUID); pEmalon = Unit::GetCreature(*m_creature, uiEmalonGUID);
} }
ScriptedInstance* pInstance; ScriptedInstance* pInstance;
EventMap events; EventMap events;
uint64 EmalonGUID; uint64 uiEmalonGUID;
Creature* Emalon; Creature* pEmalon;
uint32 OverchargedTimer; uint32 uiOverchargedTimer;
void Reset() void Reset()
{ {
events.Reset(); events.Reset();
OverchargedTimer = 0; uiOverchargedTimer = 0;
} }
void JustDied(Unit* Killer) void JustDied(Unit* Killer)
{ {
if(Emalon && Emalon->isAlive()) if (pEmalon && pEmalon->isAlive())
{ {
Emalon->SummonCreature(MOB_TEMPEST_MINION, Emalon->GetPositionX(), Emalon->GetPositionY(), Emalon->GetPositionZ(), Emalon->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0); pEmalon->SummonCreature(MOB_TEMPEST_MINION, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
DoScriptText(EMOTE_MINION_RESPAWN, m_creature); DoScriptText(EMOTE_MINION_RESPAWN, m_creature);
} }
} }
@@ -210,34 +174,34 @@ struct TRINITY_DLL_DECL mob_tempest_minionAI : public ScriptedAI
DoZoneInCombat(); DoZoneInCombat();
events.ScheduleEvent(EVENT_SHOCK, 20000); events.ScheduleEvent(EVENT_SHOCK, 20000);
if(Emalon && !Emalon->getVictim()) if (pEmalon && !pEmalon->getVictim() && pEmalon->AI())
Emalon->AI()->AttackStart(who); pEmalon->AI()->AttackStart(who);
} }
void UpdateAI(const uint32 diff) void UpdateAI(const uint32 diff)
{ {
//Return since we have no target //Return since we have no target
if(!UpdateVictim()) if (!UpdateVictim())
return; return;
events.Update(diff); events.Update(diff);
if(me->hasUnitState(UNIT_STAT_CASTING)) if (me->hasUnitState(UNIT_STAT_CASTING))
return; return;
if(Aura * OverchargedAura = m_creature->GetAura(SPELL_OVERCHARGED)) if (Aura *overchargedAura = m_creature->GetAura(SPELL_OVERCHARGED))
{ {
if(OverchargedAura->GetStackAmount() < 10) if (overchargedAura->GetStackAmount() < 10)
{ {
if (OverchargedTimer <= diff) if (uiOverchargedTimer <= diff)
{ {
DoCast(me, SPELL_OVERCHARGED); DoCast(me, SPELL_OVERCHARGED);
OverchargedTimer = 2000; uiOverchargedTimer = 2000;
} else OverchargedTimer -=diff; } else uiOverchargedTimer -=diff;
} }
else else
{ {
if(OverchargedAura->GetStackAmount() == 10) if (overchargedAura->GetStackAmount() == 10)
{ {
DoCast(me, SPELL_OVERCHARGED_BLAST); DoCast(me, SPELL_OVERCHARGED_BLAST);
m_creature->ForcedDespawn(); m_creature->ForcedDespawn();