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:
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user