mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
refactor(Scripts/HallOfLightning): modernize scripts (#23209)
This commit is contained in:
@@ -106,338 +106,318 @@ enum Yells
|
||||
EMOTE_BERSEKER_STANCE = 8,
|
||||
};
|
||||
|
||||
class boss_bjarngrim : public CreatureScript
|
||||
struct boss_bjarngrim : public npc_escortAI
|
||||
{
|
||||
public:
|
||||
boss_bjarngrim() : CreatureScript("boss_bjarngrim") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_bjarngrim(Creature* creature) : npc_escortAI(creature), summons(creature)
|
||||
{
|
||||
return GetHallsOfLightningAI<boss_bjarngrimAI>(creature);
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
|
||||
// Init waypoints
|
||||
AddWaypoint(1, 1262.18f, 99.3f, 33.5f, 0);
|
||||
AddWaypoint(2, 1281.6f, 99.5f, 33.5f, 0);
|
||||
AddWaypoint(3, 1311.7f, 99.4f, 40.1f, 0);
|
||||
AddWaypoint(4, 1332.5f, 99.7f, 40.18f, 0);
|
||||
AddWaypoint(5, 1311.7f, 99.4f, 40.1f, 0);
|
||||
AddWaypoint(6, 1281.6f, 99.5f, 33.5f, 0);
|
||||
AddWaypoint(7, 1262.18f, 99.3f, 33.5f, 0);
|
||||
AddWaypoint(8, 1262, -26.9f, 33.5f, 0);
|
||||
AddWaypoint(9, 1281.2f, -26.8f, 33.5f, 0);
|
||||
AddWaypoint(10, 1311.3f, -26.9f, 40.03f, 0);
|
||||
AddWaypoint(11, 1332, -26.6f, 40.18f, 0);
|
||||
AddWaypoint(12, 1311.3f, -26.9f, 40.03f, 0);
|
||||
AddWaypoint(13, 1281.2f, -26.8f, 33.5f, 0);
|
||||
AddWaypoint(14, 1262, -26.9f, 33.5f, 0);
|
||||
|
||||
Start(true, ObjectGuid::Empty, nullptr, false, true);
|
||||
}
|
||||
|
||||
struct boss_bjarngrimAI : public npc_escortAI
|
||||
void Reset() override
|
||||
{
|
||||
boss_bjarngrimAI(Creature* creature) : npc_escortAI(creature), summons(creature)
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
if (Creature* dwarf = me->SummonCreature(NPC_STORMFORGED_LIEUTENANT, me->GetPositionX() + urand(4, 12), me->GetPositionY() + urand(4, 12), me->GetPositionZ()))
|
||||
{
|
||||
dwarf->GetMotionMaster()->MoveFollow(me, 3, rand_norm() * 2 * 3.14f);
|
||||
summons.Summon(dwarf);
|
||||
}
|
||||
|
||||
me->RemoveAllAuras();
|
||||
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, NOT_STARTED);
|
||||
|
||||
me->CastSpell(me, SPELL_BATTLE_STANCE, true);
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
RollStance(STANCE_BATTLE);
|
||||
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_CHANGE_STANCE, 20s, 0);
|
||||
|
||||
// DEFENSIVE STANCE
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_REFLECTION, 8s, STANCE_DEFENSIVE);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_KNOCK, 16s, STANCE_DEFENSIVE);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_IRONFORM, 12s, STANCE_DEFENSIVE);
|
||||
|
||||
// BERSERKER STANCE
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_INTERCEPT, 23s, STANCE_BERSERKER);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_CLEAVE, 25s, STANCE_BERSERKER);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_WHIRLWIND, 26s, STANCE_BERSERKER);
|
||||
|
||||
// BATTLE STANCE
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_PUMMEL, 5s, STANCE_BATTLE);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_MORTAL_STRIKE, 24s, STANCE_BATTLE);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_SLAM, 30s, STANCE_BATTLE);
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, IN_PROGRESS);
|
||||
m_pInstance->SetData(DATA_BJARNGRIM_ACHIEVEMENT, me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE));
|
||||
}
|
||||
}
|
||||
|
||||
// Init waypoints
|
||||
AddWaypoint(1, 1262.18f, 99.3f, 33.5f, 0);
|
||||
AddWaypoint(2, 1281.6f, 99.5f, 33.5f, 0);
|
||||
AddWaypoint(3, 1311.7f, 99.4f, 40.1f, 0);
|
||||
AddWaypoint(4, 1332.5f, 99.7f, 40.18f, 0);
|
||||
AddWaypoint(5, 1311.7f, 99.4f, 40.1f, 0);
|
||||
AddWaypoint(6, 1281.6f, 99.5f, 33.5f, 0);
|
||||
AddWaypoint(7, 1262.18f, 99.3f, 33.5f, 0);
|
||||
AddWaypoint(8, 1262, -26.9f, 33.5f, 0);
|
||||
AddWaypoint(9, 1281.2f, -26.8f, 33.5f, 0);
|
||||
AddWaypoint(10, 1311.3f, -26.9f, 40.03f, 0);
|
||||
AddWaypoint(11, 1332, -26.6f, 40.18f, 0);
|
||||
AddWaypoint(12, 1311.3f, -26.9f, 40.03f, 0);
|
||||
AddWaypoint(13, 1281.2f, -26.8f, 33.5f, 0);
|
||||
AddWaypoint(14, 1262, -26.9f, 33.5f, 0);
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!victim->IsPlayer())
|
||||
return;
|
||||
|
||||
Start(true, ObjectGuid::Empty, nullptr, false, true);
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, DONE);
|
||||
}
|
||||
|
||||
void RemoveStanceAura(uint8 stance)
|
||||
{
|
||||
switch (stance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
me->RemoveAura(SPELL_DEFENSIVE_STANCE);
|
||||
me->RemoveAura(SPELL_DEFENSIVE_AURA);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
me->RemoveAura(SPELL_BERSERKER_STANCE);
|
||||
me->RemoveAura(SPELL_BERSERKER_AURA);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
me->RemoveAura(SPELL_BATTLE_STANCE);
|
||||
me->RemoveAura(SPELL_BATTLE_AURA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RollStance(uint8 stance, uint8 force = 0)
|
||||
{
|
||||
if (urand(0, 1))
|
||||
stance = (++stance == 4 ? 1 : stance);
|
||||
else
|
||||
stance = (--stance == 0 ? 3 : stance);
|
||||
|
||||
if (force)
|
||||
stance = force;
|
||||
|
||||
switch (stance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
Talk(SAY_DEFENSIVE_STANCE);
|
||||
|
||||
me->CastSpell(me, SPELL_DEFENSIVE_STANCE, true);
|
||||
me->CastSpell(me, SPELL_DEFENSIVE_AURA, true);
|
||||
|
||||
events.DelayEvents(20s, STANCE_BERSERKER);
|
||||
events.DelayEvents(20s, STANCE_BATTLE);
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
Talk(SAY_BERSERKER_STANCE);
|
||||
|
||||
me->CastSpell(me, SPELL_BERSERKER_STANCE, true);
|
||||
me->CastSpell(me, SPELL_BERSERKER_AURA, true);
|
||||
|
||||
events.DelayEvents(20s, STANCE_DEFENSIVE);
|
||||
events.DelayEvents(20s, STANCE_BATTLE);
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
Talk(SAY_BATTLE_STANCE);
|
||||
|
||||
me->CastSpell(me, SPELL_BATTLE_STANCE, true);
|
||||
me->CastSpell(me, SPELL_BATTLE_AURA, true);
|
||||
|
||||
events.DelayEvents(20s, STANCE_BERSERKER);
|
||||
events.DelayEvents(20s, STANCE_DEFENSIVE);
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
}
|
||||
|
||||
m_uiStance = stance;
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 Point) override
|
||||
{
|
||||
if (Point == 1 || Point == 8)
|
||||
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
|
||||
else if (Point == 7 || Point == 14)
|
||||
me->RemoveAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE);
|
||||
}
|
||||
|
||||
void UpdateEscortAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
return;
|
||||
|
||||
// Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_BJARNGRIM_CHANGE_STANCE:
|
||||
// roll new stance
|
||||
RemoveStanceAura(m_uiStance);
|
||||
RollStance(m_uiStance);
|
||||
events.Repeat(20s);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///// DEFENSIVE STANCE
|
||||
///////////////////////////////////////////////////////
|
||||
case EVENT_BJARNGRIM_REFLECTION:
|
||||
me->CastSpell(me, SPELL_BJARNGRIM_REFLETION, true);
|
||||
events.Repeat(8s, 9s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_PUMMEL:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PUMMEL, false);
|
||||
events.Repeat(10s, 11s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_KNOCK:
|
||||
me->CastSpell(me, SPELL_KNOCK_AWAY, false);
|
||||
events.Repeat(20s, 21s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_IRONFORM:
|
||||
me->CastSpell(me, SPELL_IRONFORM, true);
|
||||
events.Repeat(18s, 23s);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///// BERSERKER STANCE
|
||||
///////////////////////////////////////////////////////
|
||||
case EVENT_BJARNGRIM_MORTAL_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
|
||||
events.Repeat(10s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_WHIRLWIND:
|
||||
me->CastSpell(me, SPELL_WHIRLWIND, true);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///// BATTLE STANCE
|
||||
///////////////////////////////////////////////////////
|
||||
case EVENT_BJARNGRIM_INTERCEPT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
me->CastSpell(target, SPELL_INTERCEPT, true);
|
||||
|
||||
events.Repeat(30s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_SLAM:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SLAM, false);
|
||||
events.Repeat(10s, 12s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* m_pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint8 m_uiStance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
if (Creature* dwarf = me->SummonCreature(NPC_STORMFORGED_LIEUTENANT, me->GetPositionX() + urand(4, 12), me->GetPositionY() + urand(4, 12), me->GetPositionZ()))
|
||||
{
|
||||
dwarf->GetMotionMaster()->MoveFollow(me, 3, rand_norm() * 2 * 3.14f);
|
||||
summons.Summon(dwarf);
|
||||
}
|
||||
|
||||
me->RemoveAllAuras();
|
||||
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, NOT_STARTED);
|
||||
|
||||
me->CastSpell(me, SPELL_BATTLE_STANCE, true);
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
RollStance(STANCE_BATTLE);
|
||||
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_CHANGE_STANCE, 20s, 0);
|
||||
|
||||
// DEFENSIVE STANCE
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_REFLECTION, 8s, STANCE_DEFENSIVE);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_KNOCK, 16s, STANCE_DEFENSIVE);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_IRONFORM, 12s, STANCE_DEFENSIVE);
|
||||
|
||||
// BERSERKER STANCE
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_INTERCEPT, 23s, STANCE_BERSERKER);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_CLEAVE, 25s, STANCE_BERSERKER);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_WHIRLWIND, 26s, STANCE_BERSERKER);
|
||||
|
||||
// BATTLE STANCE
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_PUMMEL, 5s, STANCE_BATTLE);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_MORTAL_STRIKE, 24s, STANCE_BATTLE);
|
||||
events.ScheduleEvent(EVENT_BJARNGRIM_SLAM, 30s, STANCE_BATTLE);
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, IN_PROGRESS);
|
||||
m_pInstance->SetData(DATA_BJARNGRIM_ACHIEVEMENT, me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE));
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!victim->IsPlayer())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, DONE);
|
||||
}
|
||||
|
||||
void RemoveStanceAura(uint8 stance)
|
||||
{
|
||||
switch (stance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
me->RemoveAura(SPELL_DEFENSIVE_STANCE);
|
||||
me->RemoveAura(SPELL_DEFENSIVE_AURA);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
me->RemoveAura(SPELL_BERSERKER_STANCE);
|
||||
me->RemoveAura(SPELL_BERSERKER_AURA);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
me->RemoveAura(SPELL_BATTLE_STANCE);
|
||||
me->RemoveAura(SPELL_BATTLE_AURA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RollStance(uint8 stance, uint8 force = 0)
|
||||
{
|
||||
if (urand(0, 1))
|
||||
stance = (++stance == 4 ? 1 : stance);
|
||||
else
|
||||
stance = (--stance == 0 ? 3 : stance);
|
||||
|
||||
if (force)
|
||||
stance = force;
|
||||
|
||||
switch (stance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
Talk(SAY_DEFENSIVE_STANCE);
|
||||
|
||||
me->CastSpell(me, SPELL_DEFENSIVE_STANCE, true);
|
||||
me->CastSpell(me, SPELL_DEFENSIVE_AURA, true);
|
||||
|
||||
events.DelayEvents(20s, STANCE_BERSERKER);
|
||||
events.DelayEvents(20s, STANCE_BATTLE);
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
Talk(SAY_BERSERKER_STANCE);
|
||||
|
||||
me->CastSpell(me, SPELL_BERSERKER_STANCE, true);
|
||||
me->CastSpell(me, SPELL_BERSERKER_AURA, true);
|
||||
|
||||
events.DelayEvents(20s, STANCE_DEFENSIVE);
|
||||
events.DelayEvents(20s, STANCE_BATTLE);
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
Talk(SAY_BATTLE_STANCE);
|
||||
|
||||
me->CastSpell(me, SPELL_BATTLE_STANCE, true);
|
||||
me->CastSpell(me, SPELL_BATTLE_AURA, true);
|
||||
|
||||
events.DelayEvents(20s, STANCE_BERSERKER);
|
||||
events.DelayEvents(20s, STANCE_DEFENSIVE);
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
}
|
||||
|
||||
m_uiStance = stance;
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 Point) override
|
||||
{
|
||||
if (Point == 1 || Point == 8)
|
||||
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
|
||||
else if (Point == 7 || Point == 14)
|
||||
me->RemoveAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE);
|
||||
}
|
||||
|
||||
void UpdateEscortAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
return;
|
||||
|
||||
// Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_BJARNGRIM_CHANGE_STANCE:
|
||||
// roll new stance
|
||||
RemoveStanceAura(m_uiStance);
|
||||
RollStance(m_uiStance);
|
||||
events.Repeat(20s);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///// DEFENSIVE STANCE
|
||||
///////////////////////////////////////////////////////
|
||||
case EVENT_BJARNGRIM_REFLECTION:
|
||||
me->CastSpell(me, SPELL_BJARNGRIM_REFLETION, true);
|
||||
events.Repeat(8s, 9s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_PUMMEL:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PUMMEL, false);
|
||||
events.Repeat(10s, 11s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_KNOCK:
|
||||
me->CastSpell(me, SPELL_KNOCK_AWAY, false);
|
||||
events.Repeat(20s, 21s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_IRONFORM:
|
||||
me->CastSpell(me, SPELL_IRONFORM, true);
|
||||
events.Repeat(18s, 23s);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///// BERSERKER STANCE
|
||||
///////////////////////////////////////////////////////
|
||||
case EVENT_BJARNGRIM_MORTAL_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
|
||||
events.Repeat(10s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_WHIRLWIND:
|
||||
me->CastSpell(me, SPELL_WHIRLWIND, true);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
///// BATTLE STANCE
|
||||
///////////////////////////////////////////////////////
|
||||
case EVENT_BJARNGRIM_INTERCEPT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
me->CastSpell(target, SPELL_INTERCEPT, true);
|
||||
|
||||
events.Repeat(30s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.Repeat(25s);
|
||||
break;
|
||||
case EVENT_BJARNGRIM_SLAM:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SLAM, false);
|
||||
events.Repeat(10s, 12s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_stormforged_lieutenant : public CreatureScript
|
||||
struct npc_stormforged_lieutenant : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_stormforged_lieutenant() : CreatureScript("npc_stormforged_lieutenant") { }
|
||||
npc_stormforged_lieutenant(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void Reset() override
|
||||
{
|
||||
return GetHallsOfLightningAI<npc_stormforged_lieutenantAI>(creature);
|
||||
if (me->IsSummon())
|
||||
BjarngrimGUID = me->ToTempSummon()->GetSummonerGUID();
|
||||
else
|
||||
BjarngrimGUID.Clear();
|
||||
}
|
||||
|
||||
struct npc_stormforged_lieutenantAI : public ScriptedAI
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
npc_stormforged_lieutenantAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
events.ScheduleEvent(EVENT_ARC_WELD, 2s);
|
||||
events.ScheduleEvent(EVENT_RENEW_STEEL, 10s, 11s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_ARC_WELD:
|
||||
me->CastSpell(me->GetVictim(), SPELL_ARC_WELD, true);
|
||||
events.Repeat(20s);
|
||||
break;
|
||||
case EVENT_RENEW_STEEL:
|
||||
if (Creature* bjarngrim = ObjectAccessor::GetCreature(*me, BjarngrimGUID))
|
||||
if (bjarngrim->IsAlive())
|
||||
me->CastSpell(bjarngrim, me->GetMap()->IsHeroic() ? SPELL_RENEW_STEEL_H : SPELL_RENEW_STEEL_N, true);
|
||||
|
||||
events.Repeat(10s, 14s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
ObjectGuid BjarngrimGUID;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
if (me->IsSummon())
|
||||
BjarngrimGUID = me->ToTempSummon()->GetSummonerGUID();
|
||||
else
|
||||
BjarngrimGUID.Clear();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ARC_WELD, 2s);
|
||||
events.ScheduleEvent(EVENT_RENEW_STEEL, 10s, 11s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_ARC_WELD:
|
||||
me->CastSpell(me->GetVictim(), SPELL_ARC_WELD, true);
|
||||
events.Repeat(20s);
|
||||
break;
|
||||
case EVENT_RENEW_STEEL:
|
||||
if (Creature* bjarngrim = ObjectAccessor::GetCreature(*me, BjarngrimGUID))
|
||||
if (bjarngrim->IsAlive())
|
||||
me->CastSpell(bjarngrim, me->GetMap()->IsHeroic() ? SPELL_RENEW_STEEL_H : SPELL_RENEW_STEEL_N, true);
|
||||
|
||||
events.Repeat(10s, 14s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_bjarngrim()
|
||||
{
|
||||
new boss_bjarngrim();
|
||||
new npc_stormforged_lieutenant();
|
||||
RegisterHallOfLightningCreatureAI(boss_bjarngrim);
|
||||
RegisterHallOfLightningCreatureAI(npc_stormforged_lieutenant);
|
||||
}
|
||||
|
||||
@@ -68,211 +68,191 @@ enum IonarEvents
|
||||
EVENT_RESTORE = 5,
|
||||
};
|
||||
|
||||
class boss_ionar : public CreatureScript
|
||||
struct boss_ionar : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_ionar() : CreatureScript("boss_ionar") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_ionar(Creature* creature) : BossAI(creature, DATA_IONAR), summons(creature)
|
||||
{
|
||||
return GetHallsOfLightningAI<boss_ionarAI>(creature);
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
struct boss_ionarAI : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
boss_ionarAI(Creature* creature) : ScriptedAI(creature), summons(creature)
|
||||
HealthCheck = 50;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
me->SetVisible(true);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, NOT_STARTED);
|
||||
}
|
||||
|
||||
void ScheduleEvents(bool spark)
|
||||
{
|
||||
events.SetPhase(1);
|
||||
if (!spark)
|
||||
events.RescheduleEvent(EVENT_CHECK_HEALTH, 1s, 0, 1);
|
||||
|
||||
events.RescheduleEvent(EVENT_BALL_LIGHTNING, 10s, 0, 1);
|
||||
events.RescheduleEvent(EVENT_STATIC_OVERLOAD, 5s, 0, 1);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, IN_PROGRESS);
|
||||
|
||||
ScheduleEvents(false);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
summons.DespawnAll();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!victim->IsPlayer())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_DISPERSE)
|
||||
Split();
|
||||
}
|
||||
|
||||
void Split()
|
||||
{
|
||||
Talk(SAY_SPLIT);
|
||||
|
||||
Creature* spark;
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
{
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
if ((spark = me->SummonCreature(NPC_SPARK_OF_IONAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 20000)))
|
||||
{
|
||||
summons.Summon(spark);
|
||||
spark->CastSpell(spark, me->GetMap()->IsHeroic() ? SPELL_SPARK_VISUAL_TRIGGER_H : SPELL_SPARK_VISUAL_TRIGGER_N, true);
|
||||
spark->CastSpell(spark, SPELL_RANDOM_LIGHTNING, true);
|
||||
spark->SetUnitFlag(UNIT_FLAG_PACIFIED | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||
spark->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0);
|
||||
|
||||
if (Player* tgt = SelectTargetFromPlayerList(100))
|
||||
spark->GetMotionMaster()->MoveFollow(tgt, 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
}
|
||||
|
||||
me->SetVisible(false);
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
|
||||
events.SetPhase(2);
|
||||
events.ScheduleEvent(EVENT_CALL_SPARKS, 15s, 0, 2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_BALL_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
me->CastSpell(target, me->GetMap()->IsHeroic() ? SPELL_BALL_LIGHTNING_H : SPELL_BALL_LIGHTNING_N, false);
|
||||
|
||||
events.Repeat(10s, 11s);
|
||||
break;
|
||||
case EVENT_STATIC_OVERLOAD:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
me->CastSpell(target, me->GetMap()->IsHeroic() ? SPELL_STATIC_OVERLOAD_H : SPELL_STATIC_OVERLOAD_N, false);
|
||||
|
||||
events.Repeat(5s, 6s);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (HealthBelowPct(HealthCheck))
|
||||
me->CastSpell(me, SPELL_DISPERSE, false);
|
||||
|
||||
events.Repeat(1s);
|
||||
return;
|
||||
case EVENT_CALL_SPARKS:
|
||||
{
|
||||
EntryCheckPredicate pred(NPC_SPARK_OF_IONAR);
|
||||
summons.DoAction(ACTION_CALLBACK, pred);
|
||||
events.ScheduleEvent(EVENT_RESTORE, 2s, 0, 2);
|
||||
return;
|
||||
}
|
||||
case EVENT_RESTORE:
|
||||
EntryCheckPredicate pred(NPC_SPARK_OF_IONAR);
|
||||
summons.DoAction(ACTION_SPARK_DESPAWN, pred);
|
||||
|
||||
me->SetVisible(true);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
ScheduleEvents(true);
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* m_pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint8 HealthCheck;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
HealthCheck = 50;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
me->SetVisible(true);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, NOT_STARTED);
|
||||
}
|
||||
|
||||
void ScheduleEvents(bool spark)
|
||||
{
|
||||
events.SetPhase(1);
|
||||
if (!spark)
|
||||
events.RescheduleEvent(EVENT_CHECK_HEALTH, 1s, 0, 1);
|
||||
|
||||
events.RescheduleEvent(EVENT_BALL_LIGHTNING, 10s, 0, 1);
|
||||
events.RescheduleEvent(EVENT_STATIC_OVERLOAD, 5s, 0, 1);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, IN_PROGRESS);
|
||||
|
||||
ScheduleEvents(false);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
summons.DespawnAll();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!victim->IsPlayer())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_DISPERSE)
|
||||
Split();
|
||||
}
|
||||
|
||||
void Split()
|
||||
{
|
||||
Talk(SAY_SPLIT);
|
||||
|
||||
Creature* spark;
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
{
|
||||
if ((spark = me->SummonCreature(NPC_SPARK_OF_IONAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 20000)))
|
||||
{
|
||||
summons.Summon(spark);
|
||||
spark->CastSpell(spark, me->GetMap()->IsHeroic() ? SPELL_SPARK_VISUAL_TRIGGER_H : SPELL_SPARK_VISUAL_TRIGGER_N, true);
|
||||
spark->CastSpell(spark, SPELL_RANDOM_LIGHTNING, true);
|
||||
spark->SetUnitFlag(UNIT_FLAG_PACIFIED | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
|
||||
spark->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0);
|
||||
|
||||
if (Player* tgt = SelectTargetFromPlayerList(100))
|
||||
spark->GetMotionMaster()->MoveFollow(tgt, 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
}
|
||||
|
||||
me->SetVisible(false);
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
|
||||
events.SetPhase(2);
|
||||
events.ScheduleEvent(EVENT_CALL_SPARKS, 15s, 0, 2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_BALL_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
me->CastSpell(target, me->GetMap()->IsHeroic() ? SPELL_BALL_LIGHTNING_H : SPELL_BALL_LIGHTNING_N, false);
|
||||
|
||||
events.Repeat(10s, 11s);
|
||||
break;
|
||||
case EVENT_STATIC_OVERLOAD:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
me->CastSpell(target, me->GetMap()->IsHeroic() ? SPELL_STATIC_OVERLOAD_H : SPELL_STATIC_OVERLOAD_N, false);
|
||||
|
||||
events.Repeat(5s, 6s);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (HealthBelowPct(HealthCheck))
|
||||
me->CastSpell(me, SPELL_DISPERSE, false);
|
||||
|
||||
events.Repeat(1s);
|
||||
return;
|
||||
case EVENT_CALL_SPARKS:
|
||||
{
|
||||
EntryCheckPredicate pred(NPC_SPARK_OF_IONAR);
|
||||
summons.DoAction(ACTION_CALLBACK, pred);
|
||||
events.ScheduleEvent(EVENT_RESTORE, 2s, 0, 2);
|
||||
return;
|
||||
}
|
||||
case EVENT_RESTORE:
|
||||
EntryCheckPredicate pred(NPC_SPARK_OF_IONAR);
|
||||
summons.DoAction(ACTION_SPARK_DESPAWN, pred);
|
||||
|
||||
me->SetVisible(true);
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
ScheduleEvents(true);
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_spark_of_ionar : public CreatureScript
|
||||
struct npc_spark_of_ionar : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_spark_of_ionar() : CreatureScript("npc_spark_of_ionar") { }
|
||||
npc_spark_of_ionar(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void MoveInLineOfSight(Unit*) override { }
|
||||
void UpdateAI(uint32) override { }
|
||||
void AttackStart(Unit* /*who*/) override { }
|
||||
|
||||
void Reset() override { returning = false; }
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
return GetHallsOfLightningAI<npc_spark_of_ionarAI>(creature);
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
struct npc_spark_of_ionarAI : public ScriptedAI
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
npc_spark_of_ionarAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
if (param == ACTION_CALLBACK)
|
||||
{
|
||||
me->SetSpeed(MOVE_RUN, 2.5f);
|
||||
me->GetThreatMgr().ClearAllThreat();
|
||||
me->CombatStop(true);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
returning = true;
|
||||
}
|
||||
else if (param == ACTION_SPARK_DESPAWN)
|
||||
{
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
me->RemoveAllAuras();
|
||||
me->CastSpell(me, SPELL_SPARK_DESPAWN, true);
|
||||
me->DespawnOrUnsummon(1s);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool returning;
|
||||
|
||||
void MoveInLineOfSight(Unit*) override { }
|
||||
void UpdateAI(uint32) override { }
|
||||
void AttackStart(Unit* /*who*/) override { }
|
||||
|
||||
void Reset() override { returning = false; }
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_CALLBACK)
|
||||
{
|
||||
me->SetSpeed(MOVE_RUN, 2.5f);
|
||||
me->GetThreatMgr().ClearAllThreat();
|
||||
me->CombatStop(true);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
returning = true;
|
||||
}
|
||||
else if (param == ACTION_SPARK_DESPAWN)
|
||||
{
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
me->RemoveAllAuras();
|
||||
me->CastSpell(me, SPELL_SPARK_DESPAWN, true);
|
||||
me->DespawnOrUnsummon(1s);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// 52658, 59795 - Static Overload
|
||||
@@ -302,7 +282,7 @@ class spell_ionar_static_overload : public AuraScript
|
||||
|
||||
void AddSC_boss_ionar()
|
||||
{
|
||||
new boss_ionar();
|
||||
new npc_spark_of_ionar();
|
||||
RegisterHallOfLightningCreatureAI(boss_ionar);
|
||||
RegisterHallOfLightningCreatureAI(npc_spark_of_ionar);
|
||||
RegisterSpellScript(spell_ionar_static_overload);
|
||||
}
|
||||
|
||||
@@ -60,198 +60,187 @@ enum LokenEvents
|
||||
EVENT_AURA_REMOVE = 5
|
||||
};
|
||||
|
||||
class boss_loken : public CreatureScript
|
||||
struct boss_loken : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_loken() : CreatureScript("boss_loken") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_loken(Creature* creature) : BossAI(creature, DATA_LOKEN)
|
||||
{
|
||||
return GetHallsOfLightningAI<boss_lokenAI>(creature);
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
if (m_pInstance)
|
||||
isActive = m_pInstance->GetData(TYPE_LOKEN_INTRO);
|
||||
}
|
||||
|
||||
struct boss_lokenAI : public ScriptedAI
|
||||
void MoveInLineOfSight(Unit*) override { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
boss_lokenAI(Creature* creature) : ScriptedAI(creature)
|
||||
events.Reset();
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
if (m_pInstance)
|
||||
isActive = m_pInstance->GetData(TYPE_LOKEN_INTRO);
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
|
||||
m_pInstance->SetData(TYPE_LOKEN, NOT_STARTED);
|
||||
}
|
||||
|
||||
HealthCheck = 75;
|
||||
IntroTimer = 0;
|
||||
me->RemoveAllAuras();
|
||||
|
||||
if (!isActive)
|
||||
{
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_ARC_LIGHTNING, 10s);
|
||||
events.ScheduleEvent(EVENT_SHOCKWAVE, 3s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 15s);
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->SetData(TYPE_LOKEN, IN_PROGRESS);
|
||||
|
||||
if (me->GetMap()->IsHeroic())
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LOKEN, DONE);
|
||||
}
|
||||
|
||||
void LokenSpeach(bool hp)
|
||||
{
|
||||
if (hp)
|
||||
{
|
||||
switch (HealthCheck)
|
||||
{
|
||||
case 75:
|
||||
Talk(SAY_75HEALTH);
|
||||
break;
|
||||
case 50:
|
||||
Talk(SAY_50HEALTH);
|
||||
break;
|
||||
case 25:
|
||||
Talk(SAY_25HEALTH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
Talk(SAY_NOVA);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!victim->IsPlayer())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!isActive)
|
||||
{
|
||||
IntroTimer += diff;
|
||||
if (IntroTimer > 5000 && IntroTimer < 10000)
|
||||
{
|
||||
if (SelectTargetFromPlayerList(60))
|
||||
{
|
||||
Talk(SAY_INTRO_1);
|
||||
IntroTimer = 10000;
|
||||
}
|
||||
else
|
||||
IntroTimer = 0;
|
||||
}
|
||||
|
||||
if (IntroTimer >= 30000 && IntroTimer < 40000)
|
||||
{
|
||||
Talk(SAY_INTRO_2);
|
||||
IntroTimer = 40000;
|
||||
}
|
||||
if (IntroTimer >= 60000)
|
||||
{
|
||||
isActive = true;
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LOKEN_INTRO, 1);
|
||||
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
if (Player* target = SelectTargetFromPlayerList(80))
|
||||
AttackStart(target);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (HealthBelowPct(HealthCheck))
|
||||
{
|
||||
LokenSpeach(true);
|
||||
HealthCheck -= 25;
|
||||
}
|
||||
|
||||
events.Repeat(1s);
|
||||
break;
|
||||
case EVENT_LIGHTNING_NOVA:
|
||||
events.Repeat(15s);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_NOVA_VISUAL, true);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_NOVA_THUNDERS, true);
|
||||
|
||||
events.DelayEvents(5s);
|
||||
events.ScheduleEvent(EVENT_AURA_REMOVE, me->GetMap()->IsHeroic() ? 4s : 5s);
|
||||
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_LIGHTNING_NOVA_H : SPELL_LIGHTNING_NOVA_N, false);
|
||||
break;
|
||||
case EVENT_SHOCKWAVE:
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_PULSING_SHOCKWAVE_H : SPELL_PULSING_SHOCKWAVE_N, false);
|
||||
break;
|
||||
case EVENT_ARC_LIGHTNING:
|
||||
if (Unit* target = SelectTargetFromPlayerList(100, SPELL_ARC_LIGHTNING))
|
||||
me->CastSpell(target, SPELL_ARC_LIGHTNING, false);
|
||||
|
||||
events.Repeat(12s);
|
||||
break;
|
||||
case EVENT_AURA_REMOVE:
|
||||
me->RemoveAura(SPELL_LIGHTNING_NOVA_THUNDERS);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
InstanceScript* m_pInstance;
|
||||
EventMap events;
|
||||
|
||||
bool isActive;
|
||||
uint32 IntroTimer;
|
||||
uint8 HealthCheck;
|
||||
|
||||
void MoveInLineOfSight(Unit*) override { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
|
||||
m_pInstance->SetData(TYPE_LOKEN, NOT_STARTED);
|
||||
}
|
||||
|
||||
HealthCheck = 75;
|
||||
IntroTimer = 0;
|
||||
me->RemoveAllAuras();
|
||||
|
||||
if (!isActive)
|
||||
{
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_ARC_LIGHTNING, 10s);
|
||||
events.ScheduleEvent(EVENT_SHOCKWAVE, 3s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 15s);
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->SetData(TYPE_LOKEN, IN_PROGRESS);
|
||||
|
||||
if (me->GetMap()->IsHeroic())
|
||||
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LOKEN, DONE);
|
||||
}
|
||||
|
||||
void LokenSpeach(bool hp)
|
||||
{
|
||||
if (hp)
|
||||
{
|
||||
switch (HealthCheck)
|
||||
{
|
||||
case 75:
|
||||
Talk(SAY_75HEALTH);
|
||||
break;
|
||||
case 50:
|
||||
Talk(SAY_50HEALTH);
|
||||
break;
|
||||
case 25:
|
||||
Talk(SAY_25HEALTH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
Talk(SAY_NOVA);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!victim->IsPlayer())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!isActive)
|
||||
{
|
||||
IntroTimer += diff;
|
||||
if (IntroTimer > 5000 && IntroTimer < 10000)
|
||||
{
|
||||
if (SelectTargetFromPlayerList(60))
|
||||
{
|
||||
Talk(SAY_INTRO_1);
|
||||
IntroTimer = 10000;
|
||||
}
|
||||
else
|
||||
IntroTimer = 0;
|
||||
}
|
||||
|
||||
if (IntroTimer >= 30000 && IntroTimer < 40000)
|
||||
{
|
||||
Talk(SAY_INTRO_2);
|
||||
IntroTimer = 40000;
|
||||
}
|
||||
if (IntroTimer >= 60000)
|
||||
{
|
||||
isActive = true;
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LOKEN_INTRO, 1);
|
||||
|
||||
me->SetControlled(false, UNIT_STATE_STUNNED);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
if (Player* target = SelectTargetFromPlayerList(80))
|
||||
AttackStart(target);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (HealthBelowPct(HealthCheck))
|
||||
{
|
||||
LokenSpeach(true);
|
||||
HealthCheck -= 25;
|
||||
}
|
||||
|
||||
events.Repeat(1s);
|
||||
break;
|
||||
case EVENT_LIGHTNING_NOVA:
|
||||
events.Repeat(15s);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_NOVA_VISUAL, true);
|
||||
me->CastSpell(me, SPELL_LIGHTNING_NOVA_THUNDERS, true);
|
||||
|
||||
events.DelayEvents(5s);
|
||||
events.ScheduleEvent(EVENT_AURA_REMOVE, me->GetMap()->IsHeroic() ? 4s : 5s);
|
||||
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_LIGHTNING_NOVA_H : SPELL_LIGHTNING_NOVA_N, false);
|
||||
break;
|
||||
case EVENT_SHOCKWAVE:
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_PULSING_SHOCKWAVE_H : SPELL_PULSING_SHOCKWAVE_N, false);
|
||||
break;
|
||||
case EVENT_ARC_LIGHTNING:
|
||||
if (Unit* target = SelectTargetFromPlayerList(100, SPELL_ARC_LIGHTNING))
|
||||
me->CastSpell(target, SPELL_ARC_LIGHTNING, false);
|
||||
|
||||
events.Repeat(12s);
|
||||
break;
|
||||
case EVENT_AURA_REMOVE:
|
||||
me->RemoveAura(SPELL_LIGHTNING_NOVA_THUNDERS);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_loken_pulsing_shockwave : public SpellScript
|
||||
@@ -276,6 +265,6 @@ class spell_loken_pulsing_shockwave : public SpellScript
|
||||
|
||||
void AddSC_boss_loken()
|
||||
{
|
||||
new boss_loken();
|
||||
RegisterHallOfLightningCreatureAI(boss_loken);
|
||||
RegisterSpellScript(spell_loken_pulsing_shockwave);
|
||||
}
|
||||
|
||||
@@ -78,23 +78,228 @@ enum Yells
|
||||
EMOTE_SHATTER = 6,
|
||||
};
|
||||
|
||||
class boss_volkhan : public CreatureScript
|
||||
struct boss_volkhan : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_volkhan() : CreatureScript("boss_volkhan") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_volkhan(Creature* creature) : BossAI(creature, DATA_VOLKHAN), summons(creature)
|
||||
{
|
||||
return GetHallsOfLightningAI<boss_volkhanAI>(creature);
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
struct boss_volkhanAI : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
boss_volkhanAI(Creature* creature) : ScriptedAI(creature), summons(creature)
|
||||
x = y = z = PointID = ShatteredCount = 0;
|
||||
HealthCheck = 100;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetSpeed(MOVE_RUN, 1.2f, true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, NOT_STARTED);
|
||||
m_pInstance->SetData(DATA_VOLKHAN_ACHIEVEMENT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, IN_PROGRESS);
|
||||
|
||||
ScheduleEvents(false);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
summons.DespawnAll();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, DONE);
|
||||
}
|
||||
|
||||
void GetNextPos()
|
||||
{
|
||||
if (me->GetPositionY() < -180)
|
||||
{
|
||||
if (me->GetPositionX() > 1330)
|
||||
x = 1355;
|
||||
else
|
||||
x = 1308;
|
||||
|
||||
y = -178;
|
||||
z = 52.5f;
|
||||
}
|
||||
else if (me->GetPositionY() < -145)
|
||||
{
|
||||
if (me->GetPositionX() > 1330)
|
||||
x = 1355;
|
||||
else
|
||||
x = 1308;
|
||||
|
||||
y = -137;
|
||||
z = 52.5f;
|
||||
}
|
||||
else if (me->GetPositionY() < -130)
|
||||
{
|
||||
if (me->GetPositionX() > 1330)
|
||||
x = 1343;
|
||||
else
|
||||
x = 1320;
|
||||
|
||||
y = -123;
|
||||
z = 56.7f;
|
||||
}
|
||||
else
|
||||
{
|
||||
PointID = POINT_ANVIL;
|
||||
x = 1327;
|
||||
y = -96;
|
||||
z = 56.7f;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!victim->IsPlayer())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void ScheduleEvents(bool anvil)
|
||||
{
|
||||
events.SetPhase(1);
|
||||
events.RescheduleEvent(EVENT_HEAT, 8s, 0, 1);
|
||||
events.RescheduleEvent(EVENT_SHATTER, 10s, 0, 1);
|
||||
events.RescheduleEvent(EVENT_CHECK_HEALTH, anvil ? 1s : 6s, 0, 1);
|
||||
events.RescheduleEvent(EVENT_POSITION, 4s, 0, 1);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (summon->GetEntry() == NPC_MOLTEN_GOLEM)
|
||||
{
|
||||
summon->SetFaction(me->GetFaction());
|
||||
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
summon->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_DESTROYED)
|
||||
{
|
||||
ShatteredCount++;
|
||||
if (ShatteredCount > 4)
|
||||
m_pInstance->SetData(DATA_VOLKHAN_ACHIEVEMENT, false);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (id == POINT_ANVIL)
|
||||
{
|
||||
me->SetSpeed(MOVE_RUN, 1.2f, true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->CastSpell(me, SPELL_TEMPER, false);
|
||||
PointID = 0;
|
||||
ScheduleEvents(true);
|
||||
|
||||
// update orientation at server
|
||||
me->SetOrientation(2.19f);
|
||||
|
||||
// and client
|
||||
WorldPacket data;
|
||||
me->BuildHeartBeatMsg(&data);
|
||||
me->SendMessageToSet(&data, false);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_ANVIL, 0ms, 0, 2);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* /*who*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_TEMPER)
|
||||
{
|
||||
me->CastSpell(me, SPELL_SUMMON_MOLTEN_GOLEM, true);
|
||||
me->CastSpell(me, SPELL_SUMMON_MOLTEN_GOLEM, true);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
void GoToAnvil()
|
||||
{
|
||||
events.SetPhase(2);
|
||||
HealthCheck -= 20;
|
||||
me->SetSpeed(MOVE_RUN, 4.0f, true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
|
||||
Talk(SAY_FORGE);
|
||||
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_ANVIL, 0ms, 0, 2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_HEAT:
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_HEAT_H : SPELL_HEAT_N, true);
|
||||
events.Repeat(8s);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (HealthBelowPct(HealthCheck))
|
||||
GoToAnvil();
|
||||
|
||||
events.Repeat(1s);
|
||||
return;
|
||||
case EVENT_SHATTER:
|
||||
{
|
||||
events.Repeat(10s);
|
||||
summons.DoAction(ACTION_SHATTER);
|
||||
break;
|
||||
}
|
||||
case EVENT_MOVE_TO_ANVIL:
|
||||
GetNextPos();
|
||||
me->GetMotionMaster()->MovePoint(PointID, x, y, z);
|
||||
return;
|
||||
case EVENT_POSITION:
|
||||
if (me->GetDistance(1331.9f, -106, 56) > 95)
|
||||
EnterEvadeMode();
|
||||
else
|
||||
events.Repeat(4s);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* m_pInstance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
@@ -102,312 +307,86 @@ public:
|
||||
float x, y, z;
|
||||
uint8 PointID;
|
||||
uint8 ShatteredCount;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
x = y = z = PointID = ShatteredCount = 0;
|
||||
HealthCheck = 100;
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->SetSpeed(MOVE_RUN, 1.2f, true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
if (m_pInstance)
|
||||
{
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, NOT_STARTED);
|
||||
m_pInstance->SetData(DATA_VOLKHAN_ACHIEVEMENT, true);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
me->SetInCombatWithZone();
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, IN_PROGRESS);
|
||||
|
||||
ScheduleEvents(false);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
summons.DespawnAll();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, DONE);
|
||||
}
|
||||
|
||||
void GetNextPos()
|
||||
{
|
||||
if (me->GetPositionY() < -180)
|
||||
{
|
||||
if (me->GetPositionX() > 1330)
|
||||
x = 1355;
|
||||
else
|
||||
x = 1308;
|
||||
|
||||
y = -178;
|
||||
z = 52.5f;
|
||||
}
|
||||
else if (me->GetPositionY() < -145)
|
||||
{
|
||||
if (me->GetPositionX() > 1330)
|
||||
x = 1355;
|
||||
else
|
||||
x = 1308;
|
||||
|
||||
y = -137;
|
||||
z = 52.5f;
|
||||
}
|
||||
else if (me->GetPositionY() < -130)
|
||||
{
|
||||
if (me->GetPositionX() > 1330)
|
||||
x = 1343;
|
||||
else
|
||||
x = 1320;
|
||||
|
||||
y = -123;
|
||||
z = 56.7f;
|
||||
}
|
||||
else
|
||||
{
|
||||
PointID = POINT_ANVIL;
|
||||
x = 1327;
|
||||
y = -96;
|
||||
z = 56.7f;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (!victim->IsPlayer())
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void ScheduleEvents(bool anvil)
|
||||
{
|
||||
events.SetPhase(1);
|
||||
events.RescheduleEvent(EVENT_HEAT, 8s, 0, 1);
|
||||
events.RescheduleEvent(EVENT_SHATTER, 10s, 0, 1);
|
||||
events.RescheduleEvent(EVENT_CHECK_HEALTH, anvil ? 1s : 6s, 0, 1);
|
||||
events.RescheduleEvent(EVENT_POSITION, 4s, 0, 1);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (summon->GetEntry() == NPC_MOLTEN_GOLEM)
|
||||
{
|
||||
summon->SetFaction(me->GetFaction());
|
||||
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
|
||||
summon->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_DESTROYED)
|
||||
{
|
||||
ShatteredCount++;
|
||||
if (ShatteredCount > 4)
|
||||
m_pInstance->SetData(DATA_VOLKHAN_ACHIEVEMENT, false);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (id == POINT_ANVIL)
|
||||
{
|
||||
me->SetSpeed(MOVE_RUN, 1.2f, true);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->CastSpell(me, SPELL_TEMPER, false);
|
||||
PointID = 0;
|
||||
ScheduleEvents(true);
|
||||
|
||||
// update orientation at server
|
||||
me->SetOrientation(2.19f);
|
||||
|
||||
// and client
|
||||
WorldPacket data;
|
||||
me->BuildHeartBeatMsg(&data);
|
||||
me->SendMessageToSet(&data, false);
|
||||
me->SetControlled(true, UNIT_STATE_ROOT);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_ANVIL, 0ms, 0, 2);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* /*who*/, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_TEMPER)
|
||||
{
|
||||
me->CastSpell(me, SPELL_SUMMON_MOLTEN_GOLEM, true);
|
||||
me->CastSpell(me, SPELL_SUMMON_MOLTEN_GOLEM, true);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
me->SetControlled(false, UNIT_STATE_ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
void GoToAnvil()
|
||||
{
|
||||
events.SetPhase(2);
|
||||
HealthCheck -= 20;
|
||||
me->SetSpeed(MOVE_RUN, 4.0f, true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
|
||||
Talk(SAY_FORGE);
|
||||
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
|
||||
events.ScheduleEvent(EVENT_MOVE_TO_ANVIL, 0ms, 0, 2);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_HEAT:
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_HEAT_H : SPELL_HEAT_N, true);
|
||||
events.Repeat(8s);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (HealthBelowPct(HealthCheck))
|
||||
GoToAnvil();
|
||||
|
||||
events.Repeat(1s);
|
||||
return;
|
||||
case EVENT_SHATTER:
|
||||
{
|
||||
events.Repeat(10s);
|
||||
summons.DoAction(ACTION_SHATTER);
|
||||
break;
|
||||
}
|
||||
case EVENT_MOVE_TO_ANVIL:
|
||||
GetNextPos();
|
||||
me->GetMotionMaster()->MovePoint(PointID, x, y, z);
|
||||
return;
|
||||
case EVENT_POSITION:
|
||||
if (me->GetDistance(1331.9f, -106, 56) > 95)
|
||||
EnterEvadeMode();
|
||||
else
|
||||
events.Repeat(4s);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class npc_molten_golem : public CreatureScript
|
||||
struct npc_molten_golem : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_molten_golem() : CreatureScript("npc_molten_golem") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
npc_molten_golem(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
return GetHallsOfLightningAI<npc_molten_golemAI>(creature);
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
struct npc_molten_golemAI : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
npc_molten_golemAI(Creature* creature) : ScriptedAI(creature)
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_BLAST, 7s);
|
||||
events.ScheduleEvent(EVENT_IMMOLATION, 3s);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& uiDamage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (me->GetEntry() == NPC_BRITTLE_GOLEM)
|
||||
{
|
||||
m_pInstance = creature->GetInstanceScript();
|
||||
uiDamage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* m_pInstance;
|
||||
|
||||
void Reset() override
|
||||
if (uiDamage >= me->GetHealth())
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_BLAST, 7s);
|
||||
events.ScheduleEvent(EVENT_IMMOLATION, 3s);
|
||||
me->UpdateEntry(NPC_BRITTLE_GOLEM, 0, false);
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
me->RemoveAllAuras();
|
||||
me->AttackStop();
|
||||
uiDamage = 0;
|
||||
|
||||
if (me->IsNonMeleeSpellCast(false))
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (me->GetEntry() == NPC_BRITTLE_GOLEM && param == ACTION_SHATTER)
|
||||
{
|
||||
if (Creature* volkhan = m_pInstance->GetCreature(DATA_VOLKHAN))
|
||||
volkhan->AI()->DoAction(ACTION_DESTROYED);
|
||||
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_SHATTER_H : SPELL_SHATTER_N, true);
|
||||
me->DespawnOrUnsummon(500ms);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target or if we are frozen
|
||||
if (!UpdateVictim() || me->GetEntry() == NPC_BRITTLE_GOLEM)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_BLAST:
|
||||
me->CastSpell(me, SPELL_BLAST_WAVE, false);
|
||||
events.Repeat(14s);
|
||||
break;
|
||||
case EVENT_IMMOLATION:
|
||||
me->CastSpell(me->GetVictim(), me->GetMap()->IsHeroic() ? SPELL_IMMOLATION_STRIKE_H : SPELL_IMMOLATION_STRIKE_N, false);
|
||||
events.Repeat(5s);
|
||||
break;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& uiDamage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (me->GetEntry() == NPC_BRITTLE_GOLEM)
|
||||
{
|
||||
uiDamage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (uiDamage >= me->GetHealth())
|
||||
{
|
||||
me->UpdateEntry(NPC_BRITTLE_GOLEM, 0, false);
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetHealth(me->GetMaxHealth());
|
||||
me->RemoveAllAuras();
|
||||
me->AttackStop();
|
||||
uiDamage = 0;
|
||||
|
||||
if (me->IsNonMeleeSpellCast(false))
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
me->SetControlled(true, UNIT_STATE_STUNNED);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (me->GetEntry() == NPC_BRITTLE_GOLEM && param == ACTION_SHATTER)
|
||||
{
|
||||
if (Creature* volkhan = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(TYPE_VOLKHAN)))
|
||||
volkhan->AI()->DoAction(ACTION_DESTROYED);
|
||||
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_SHATTER_H : SPELL_SHATTER_N, true);
|
||||
me->DespawnOrUnsummon(500ms);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target or if we are frozen
|
||||
if (!UpdateVictim() || me->GetEntry() == NPC_BRITTLE_GOLEM)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_BLAST:
|
||||
me->CastSpell(me, SPELL_BLAST_WAVE, false);
|
||||
events.Repeat(14s);
|
||||
break;
|
||||
case EVENT_IMMOLATION:
|
||||
me->CastSpell(me->GetVictim(), me->GetMap()->IsHeroic() ? SPELL_IMMOLATION_STRIKE_H : SPELL_IMMOLATION_STRIKE_N, false);
|
||||
events.Repeat(5s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
EventMap events;
|
||||
InstanceScript* m_pInstance;
|
||||
};
|
||||
|
||||
enum monumentSpells
|
||||
@@ -443,141 +422,127 @@ enum monumentEvents
|
||||
EVENT_UNFREEZE = 20,
|
||||
};
|
||||
|
||||
class npc_hol_monument : public CreatureScript
|
||||
struct npc_hol_monument : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_hol_monument() : CreatureScript("npc_hol_monument") {}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
npc_hol_monument(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
return GetHallsOfLightningAI<npc_hol_monumentAI>(creature);
|
||||
_attackGUID.Clear();
|
||||
_isActive = urand(0, 1);
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->CastSpell(me, SPELL_FREEZE_ANIM, true);
|
||||
}
|
||||
|
||||
struct npc_hol_monumentAI : public ScriptedAI
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
npc_hol_monumentAI(Creature* creature) : ScriptedAI(creature)
|
||||
if (_attackGUID)
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
else if (_isActive && who->IsPlayer())
|
||||
{
|
||||
_attackGUID.Clear();
|
||||
_isActive = urand(0, 1);
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->CastSpell(me, SPELL_FREEZE_ANIM, true);
|
||||
if ((who->GetPositionX() < me->GetPositionX() || who->GetPositionY() < -220.0f) && me->GetDistance2d(who) < 40)
|
||||
{
|
||||
_isActive = false;
|
||||
_attackGUID = who->GetGUID();
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_UNFREEZE, 5s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
events.Reset();
|
||||
if (me->GetEntry() == 28961) // NPC_TITANIUM_SIEGEBREAKER
|
||||
{
|
||||
events.ScheduleEvent(EVENT_PIERCING_HOWL, 10s, 25s);
|
||||
events.ScheduleEvent(EVENT_PENETRATING_STRIKE, 5s, 10s);
|
||||
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 20s, 28s);
|
||||
events.ScheduleEvent(EVENT_BLADE_TURNING, 12s);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.ScheduleEvent(EVENT_THROW, 10s, 25s);
|
||||
events.ScheduleEvent(EVENT_DEADLY_THROW, 15s, 30s);
|
||||
events.ScheduleEvent(EVENT_DEFLECTION, 15s);
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (!_attackGUID || !_isActive)
|
||||
return;
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!_isActive && !_attackGUID)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
uint32 eventId = events.ExecuteEvent();
|
||||
|
||||
if (eventId == EVENT_UNFREEZE)
|
||||
{
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->CastSpell(me, SPELL_AWAKEN, true);
|
||||
me->RemoveAllAuras();
|
||||
_isActive = true;
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*me, _attackGUID))
|
||||
AttackStart(target);
|
||||
return;
|
||||
}
|
||||
|
||||
//Return since we have no target or if we are disabled from fight
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_PIERCING_HOWL:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PIERCING_HOWL, false);
|
||||
events.Repeat(10s, 25s);
|
||||
break;
|
||||
case EVENT_PENETRATING_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PENETRATING_STRIKE, false);
|
||||
events.Repeat(5s, 10s);
|
||||
break;
|
||||
case EVENT_FRIGHTENING_SHOUT:
|
||||
me->CastSpell(me->GetVictim(), SPELL_FRIGHTENING_SHOUT, false);
|
||||
events.Repeat(20s, 28s);
|
||||
break;
|
||||
case EVENT_BLADE_TURNING:
|
||||
me->CastSpell(me->GetVictim(), me->GetMap()->IsHeroic() ? SPELL_BLADE_TURNING_H : SPELL_BLADE_TURNING_N, false);
|
||||
events.Repeat(12s);
|
||||
break;
|
||||
case EVENT_THROW:
|
||||
me->CastSpell(SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0), me->GetMap()->IsHeroic() ? SPELL_THROW_H : SPELL_THROW_N, true);
|
||||
events.Repeat(10s, 25s);
|
||||
break;
|
||||
case EVENT_DEADLY_THROW:
|
||||
me->CastSpell(SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0), me->GetMap()->IsHeroic() ? SPELL_DEADLY_THROW_H : SPELL_DEADLY_THROW_N, true);
|
||||
events.Repeat(15s, 30s);
|
||||
break;
|
||||
case EVENT_DEFLECTION:
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_DEFLECTION_H : SPELL_DEFLECTION_N, false);
|
||||
events.Repeat(15s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
bool _isActive;
|
||||
ObjectGuid _attackGUID;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (_attackGUID)
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
else if (_isActive && who->IsPlayer())
|
||||
{
|
||||
if ((who->GetPositionX() < me->GetPositionX() || who->GetPositionY() < -220.0f) && me->GetDistance2d(who) < 40)
|
||||
{
|
||||
_isActive = false;
|
||||
_attackGUID = who->GetGUID();
|
||||
events.Reset();
|
||||
events.RescheduleEvent(EVENT_UNFREEZE, 5s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
events.Reset();
|
||||
if (me->GetEntry() == 28961) // NPC_TITANIUM_SIEGEBREAKER
|
||||
{
|
||||
events.ScheduleEvent(EVENT_PIERCING_HOWL, 10s, 25s);
|
||||
events.ScheduleEvent(EVENT_PENETRATING_STRIKE, 5s, 10s);
|
||||
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 20s, 28s);
|
||||
events.ScheduleEvent(EVENT_BLADE_TURNING, 12s);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.ScheduleEvent(EVENT_THROW, 10s, 25s);
|
||||
events.ScheduleEvent(EVENT_DEADLY_THROW, 15s, 30s);
|
||||
events.ScheduleEvent(EVENT_DEFLECTION, 15s);
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (!_attackGUID || !_isActive)
|
||||
return;
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!_isActive && !_attackGUID)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
uint32 eventId = events.ExecuteEvent();
|
||||
|
||||
if (eventId == EVENT_UNFREEZE)
|
||||
{
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->CastSpell(me, SPELL_AWAKEN, true);
|
||||
me->RemoveAllAuras();
|
||||
_isActive = true;
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*me, _attackGUID))
|
||||
AttackStart(target);
|
||||
return;
|
||||
}
|
||||
|
||||
//Return since we have no target or if we are disabled from fight
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_PIERCING_HOWL:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PIERCING_HOWL, false);
|
||||
events.Repeat(10s, 25s);
|
||||
break;
|
||||
case EVENT_PENETRATING_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_PENETRATING_STRIKE, false);
|
||||
events.Repeat(5s, 10s);
|
||||
break;
|
||||
case EVENT_FRIGHTENING_SHOUT:
|
||||
me->CastSpell(me->GetVictim(), SPELL_FRIGHTENING_SHOUT, false);
|
||||
events.Repeat(20s, 28s);
|
||||
break;
|
||||
case EVENT_BLADE_TURNING:
|
||||
me->CastSpell(me->GetVictim(), me->GetMap()->IsHeroic() ? SPELL_BLADE_TURNING_H : SPELL_BLADE_TURNING_N, false);
|
||||
events.Repeat(12s);
|
||||
break;
|
||||
case EVENT_THROW:
|
||||
me->CastSpell(SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0), me->GetMap()->IsHeroic() ? SPELL_THROW_H : SPELL_THROW_N, true);
|
||||
events.Repeat(10s, 25s);
|
||||
break;
|
||||
case EVENT_DEADLY_THROW:
|
||||
me->CastSpell(SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0), me->GetMap()->IsHeroic() ? SPELL_DEADLY_THROW_H : SPELL_DEADLY_THROW_N, true);
|
||||
events.Repeat(15s, 30s);
|
||||
break;
|
||||
case EVENT_DEFLECTION:
|
||||
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_DEFLECTION_H : SPELL_DEFLECTION_N, false);
|
||||
events.Repeat(15s);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_volkhan()
|
||||
{
|
||||
new boss_volkhan();
|
||||
new npc_molten_golem();
|
||||
new npc_hol_monument();
|
||||
RegisterHallOfLightningCreatureAI(boss_volkhan);
|
||||
RegisterHallOfLightningCreatureAI(npc_molten_golem);
|
||||
RegisterHallOfLightningCreatureAI(npc_hol_monument);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
|
||||
#define HallsOfLightningScriptName "instance_halls_of_lightning"
|
||||
|
||||
enum BossIds
|
||||
{
|
||||
DATA_BJARNGRIM = 0,
|
||||
DATA_IONAR = 1,
|
||||
DATA_LOKEN = 2,
|
||||
DATA_VOLKHAN = 3,
|
||||
MAX_ENCOUNTERS
|
||||
};
|
||||
|
||||
enum HoLEvents
|
||||
{
|
||||
TYPE_BJARNGRIM = 0,
|
||||
@@ -60,4 +69,6 @@ inline AI* GetHallsOfLightningAI(T* obj)
|
||||
return GetInstanceAI<AI>(obj, HallsOfLightningScriptName);
|
||||
}
|
||||
|
||||
#define RegisterHallOfLightningCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetHallsOfLightningAI)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,35 +32,19 @@ public:
|
||||
|
||||
struct instance_halls_of_lightning_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_halls_of_lightning_InstanceMapScript(Map* pMap) : InstanceScript(pMap) { Initialize(); };
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
|
||||
ObjectGuid m_uiGeneralBjarngrimGUID;
|
||||
ObjectGuid m_uiIonarGUID;
|
||||
ObjectGuid m_uiLokenGUID;
|
||||
ObjectGuid m_uiVolkhanGUID;
|
||||
|
||||
ObjectGuid m_uiBjarngrimDoorGUID;
|
||||
ObjectGuid m_uiVolkhanDoorGUID;
|
||||
ObjectGuid m_uiIonarDoorGUID;
|
||||
ObjectGuid m_uiLokenDoorGUID;
|
||||
ObjectGuid m_uiLokenGlobeGUID;
|
||||
|
||||
bool volkhanAchievement;
|
||||
bool bjarngrimAchievement;
|
||||
|
||||
void Initialize() override
|
||||
instance_halls_of_lightning_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
volkhanAchievement = false;
|
||||
bjarngrimAchievement = false;
|
||||
}
|
||||
};
|
||||
|
||||
bool IsEncounterInProgress() const override
|
||||
{
|
||||
if (InstanceScript::IsEncounterInProgress())
|
||||
return true;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS && i != TYPE_LOKEN_INTRO)
|
||||
@@ -195,22 +179,22 @@ public:
|
||||
return m_auiEncounter[uiType];
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 uiData) const override
|
||||
{
|
||||
switch (uiData)
|
||||
{
|
||||
case TYPE_BJARNGRIM:
|
||||
return m_uiGeneralBjarngrimGUID;
|
||||
case TYPE_VOLKHAN:
|
||||
return m_uiVolkhanGUID;
|
||||
case TYPE_IONAR:
|
||||
return m_uiIonarGUID;
|
||||
case TYPE_LOKEN:
|
||||
return m_uiLokenGUID;
|
||||
}
|
||||
private:
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
ObjectGuid m_uiGeneralBjarngrimGUID;
|
||||
ObjectGuid m_uiIonarGUID;
|
||||
ObjectGuid m_uiLokenGUID;
|
||||
ObjectGuid m_uiVolkhanGUID;
|
||||
|
||||
ObjectGuid m_uiBjarngrimDoorGUID;
|
||||
ObjectGuid m_uiVolkhanDoorGUID;
|
||||
ObjectGuid m_uiIonarDoorGUID;
|
||||
ObjectGuid m_uiLokenDoorGUID;
|
||||
ObjectGuid m_uiLokenGlobeGUID;
|
||||
|
||||
bool volkhanAchievement;
|
||||
bool bjarngrimAchievement;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user