mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Scripts/Halls of Origination: modernized scripting models to current standard
* dropped a deprecated hack spellscript from Anraphet
This commit is contained in:
1
sql/updates/world/master/2023_12_25_00_world.sql
Normal file
1
sql/updates/world/master/2023_12_25_00_world.sql
Normal file
@@ -0,0 +1 @@
|
||||
DELETE FROM `spell_script_names` WHERE `ScriptName`= 'spell_anraphet_omega_stance_spider_effect';
|
||||
@@ -132,442 +132,347 @@ Position const BrannIntroWaypoint[MAX_BRANN_WAYPOINTS_INTRO] =
|
||||
{-35.04861f, 366.6563f, 89.77447f, 0.0f},
|
||||
};
|
||||
|
||||
class boss_anraphet : public CreatureScript
|
||||
struct boss_anraphet : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_anraphet() : CreatureScript("boss_anraphet") { }
|
||||
boss_anraphet(Creature* creature) : BossAI(creature, BOSS_ANRAPHET) { }
|
||||
|
||||
struct boss_anraphetAI : public BossAI
|
||||
void ScheduleCombatEvents()
|
||||
{
|
||||
boss_anraphetAI(Creature* creature) : BossAI(creature, BOSS_ANRAPHET) { }
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 8s, 0, PHASE_COMBAT);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, 10s, 0, PHASE_COMBAT);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, 35s, 0, PHASE_COMBAT);
|
||||
}
|
||||
|
||||
void ScheduleCombatEvents()
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 8s, 0, PHASE_COMBAT);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, 10s, 0, PHASE_COMBAT);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, 35s, 0, PHASE_COMBAT);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
me->SetWalk(false);
|
||||
events.SetPhase(PHASE_INTRO);
|
||||
if (instance->GetData(DATA_DEAD_ELEMENTALS) == 4)
|
||||
{
|
||||
// Set to combat automatically, Brann's event won't repeat
|
||||
me->SetUninteractible(false);
|
||||
events.SetPhase(PHASE_COMBAT);
|
||||
ScheduleCombatEvents();
|
||||
me->SetHomePosition(AnraphetActivatePos);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
|
||||
Talk(ANRAPHET_SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
Talk(ANRAPHET_SAY_DEATH);
|
||||
|
||||
if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRANN_0_GUID)))
|
||||
brann->AI()->DoAction(ACTION_ANRAPHET_DIED);
|
||||
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(ANRAPHET_SAY_KILL);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(BOSS_ANRAPHET, FAIL);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == ACTION_ANRAPHET_INTRO)
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_APPEAR, 6s, 0, PHASE_INTRO);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (point == POINT_ANRAPHET_ACTIVATE)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_ACTIVATE, 1500ms, 0, PHASE_INTRO);
|
||||
me->SetHomePosition(AnraphetActivatePos);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if ((events.GetPhaseMask() & PHASE_MASK_COMBAT) && (!UpdateVictim() || !CheckInRoom()))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ANRAPHET_APPEAR:
|
||||
me->SetWalk(true);
|
||||
me->GetMotionMaster()->MovePoint(POINT_ANRAPHET_ACTIVATE, AnraphetActivatePos);
|
||||
break;
|
||||
case EVENT_ANRAPHET_ACTIVATE:
|
||||
me->SetWalk(false);
|
||||
Talk(ANRAPHET_SAY_INTRO);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_DESTROY, 17500ms, 0, PHASE_INTRO);
|
||||
return;
|
||||
case EVENT_ANRAPHET_DESTROY:
|
||||
DoCastAOE(SPELL_DESTRUCTION_PROTOCOL);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_READY, 6s, 0, PHASE_INTRO);
|
||||
break;
|
||||
case EVENT_ANRAPHET_READY:
|
||||
me->SetUninteractible(false);
|
||||
events.SetPhase(PHASE_COMBAT);
|
||||
ScheduleCombatEvents();
|
||||
break;
|
||||
case EVENT_ANRAPHET_NEMESIS_STRIKE:
|
||||
DoCastVictim(SPELL_NEMESIS_STRIKE);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 21500ms, 0, PHASE_COMBAT);
|
||||
break;
|
||||
case EVENT_ANRAPHET_ALPHA_BEAMS:
|
||||
DoCast(me, SPELL_ALPHA_BEAMS);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 12500ms, 0, PHASE_COMBAT);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, 40s, 45s, 0, PHASE_COMBAT);
|
||||
break;
|
||||
case EVENT_ANRAPHET_OMEGA_STANCE:
|
||||
DoCast(me, SPELL_OMEGA_STANCE_SUMMON);
|
||||
DoCast(me, SPELL_OMEGA_STANCE);
|
||||
Talk(ANRAPHET_SAY_OMEGA_STANCE);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, 45s, 50s, 0, PHASE_COMBAT);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 13s, 0, PHASE_COMBAT);
|
||||
break;
|
||||
case EVENT_ANRAPHET_CRUMBLING_RUIN:
|
||||
DoCast(me, SPELL_CRUMBLING_RUIN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (events.GetPhaseMask() & PHASE_MASK_COMBAT)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void Reset() override
|
||||
{
|
||||
return GetHallsOfOriginationAI<boss_anraphetAI>(creature);
|
||||
_Reset();
|
||||
me->SetWalk(false);
|
||||
events.SetPhase(PHASE_INTRO);
|
||||
if (instance->GetData(DATA_DEAD_ELEMENTALS) == 4)
|
||||
{
|
||||
// Set to combat automatically, Brann's event won't repeat
|
||||
me->SetUninteractible(false);
|
||||
events.SetPhase(PHASE_COMBAT);
|
||||
ScheduleCombatEvents();
|
||||
me->SetHomePosition(AnraphetActivatePos);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
|
||||
Talk(ANRAPHET_SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
Talk(ANRAPHET_SAY_DEATH);
|
||||
|
||||
if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRANN_0_GUID)))
|
||||
brann->AI()->DoAction(ACTION_ANRAPHET_DIED);
|
||||
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(ANRAPHET_SAY_KILL);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(BOSS_ANRAPHET, FAIL);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == ACTION_ANRAPHET_INTRO)
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_APPEAR, 6s, 0, PHASE_INTRO);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (point == POINT_ANRAPHET_ACTIVATE)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_ACTIVATE, 1500ms, 0, PHASE_INTRO);
|
||||
me->SetHomePosition(AnraphetActivatePos);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if ((events.GetPhaseMask() & PHASE_MASK_COMBAT) && (!UpdateVictim() || !CheckInRoom()))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ANRAPHET_APPEAR:
|
||||
me->SetWalk(true);
|
||||
me->GetMotionMaster()->MovePoint(POINT_ANRAPHET_ACTIVATE, AnraphetActivatePos);
|
||||
break;
|
||||
case EVENT_ANRAPHET_ACTIVATE:
|
||||
me->SetWalk(false);
|
||||
Talk(ANRAPHET_SAY_INTRO);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_DESTROY, 17500ms, 0, PHASE_INTRO);
|
||||
return;
|
||||
case EVENT_ANRAPHET_DESTROY:
|
||||
DoCastAOE(SPELL_DESTRUCTION_PROTOCOL);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_READY, 6s, 0, PHASE_INTRO);
|
||||
break;
|
||||
case EVENT_ANRAPHET_READY:
|
||||
me->SetUninteractible(false);
|
||||
events.SetPhase(PHASE_COMBAT);
|
||||
ScheduleCombatEvents();
|
||||
break;
|
||||
case EVENT_ANRAPHET_NEMESIS_STRIKE:
|
||||
DoCastVictim(SPELL_NEMESIS_STRIKE);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 21500ms, 0, PHASE_COMBAT);
|
||||
break;
|
||||
case EVENT_ANRAPHET_ALPHA_BEAMS:
|
||||
DoCast(me, SPELL_ALPHA_BEAMS);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 12500ms, 0, PHASE_COMBAT);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, 40s, 45s, 0, PHASE_COMBAT);
|
||||
break;
|
||||
case EVENT_ANRAPHET_OMEGA_STANCE:
|
||||
DoCast(me, SPELL_OMEGA_STANCE_SUMMON);
|
||||
DoCast(me, SPELL_OMEGA_STANCE);
|
||||
Talk(ANRAPHET_SAY_OMEGA_STANCE);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, 45s, 50s, 0, PHASE_COMBAT);
|
||||
events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 13s, 0, PHASE_COMBAT);
|
||||
break;
|
||||
case EVENT_ANRAPHET_CRUMBLING_RUIN:
|
||||
DoCast(me, SPELL_CRUMBLING_RUIN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (events.GetPhaseMask() & PHASE_MASK_COMBAT)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
class npc_omega_stance : public CreatureScript
|
||||
struct npc_omega_stance : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_omega_stance() : CreatureScript("npc_omega_stance") { }
|
||||
npc_omega_stance(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
struct npc_omega_stanceAI : public ScriptedAI
|
||||
{
|
||||
npc_omega_stanceAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
void IsSummonedBy(WorldObject* /*who*/) override
|
||||
{
|
||||
DoCast(me, SPELL_OMEGA_STANCE_SPIDER_TRIGGER, true);
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* /*who*/) override
|
||||
{
|
||||
DoCast(me, SPELL_OMEGA_STANCE_SPIDER_TRIGGER, true);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override { }
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetHallsOfOriginationAI<npc_omega_stanceAI>(creature);
|
||||
}
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override { }
|
||||
};
|
||||
|
||||
class npc_alpha_beam : public CreatureScript
|
||||
struct npc_alpha_beam : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_alpha_beam() : CreatureScript("npc_alpha_beam") { }
|
||||
npc_alpha_beam(Creature* creature) : ScriptedAI(creature), _instance(nullptr) { }
|
||||
|
||||
struct npc_alpha_beamAI : public ScriptedAI
|
||||
void InitializeAI() override
|
||||
{
|
||||
_instance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* /*summoner*/) override
|
||||
{
|
||||
if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_ANRAPHET_GUID)))
|
||||
anraphet->CastSpell(me, SPELL_ALPHA_BEAMS_BACK_CAST);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override { } // Never evade
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
struct npc_brann_bronzebeard_anraphet : public CreatureAI
|
||||
{
|
||||
npc_brann_bronzebeard_anraphet(Creature* creature) : CreatureAI(creature), _currentPoint(0), _instance(nullptr) { }
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
_instance = me->GetInstanceScript();
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* /*player*/, uint32 menuId, uint32 action) override
|
||||
{
|
||||
if (_instance->GetBossState(BOSS_VAULT_OF_LIGHTS) == DONE)
|
||||
return true;
|
||||
|
||||
if (menuId == GOSSIP_MENU_START_INTRO && !action)
|
||||
{
|
||||
npc_alpha_beamAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
|
||||
_instance->SetBossState(BOSS_VAULT_OF_LIGHTS, IN_PROGRESS);
|
||||
_currentPoint = 0;
|
||||
events.Reset();
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
me->SetWalk(true);
|
||||
Talk(BRANN_SAY_DOOR_INTRO);
|
||||
events.ScheduleEvent(EVENT_BRANN_UNLOCK_DOOR, 7500ms);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void IsSummonedBy(WorldObject* /*summoner*/) override
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_ELEMENTAL_DIED:
|
||||
{
|
||||
uint32 dead = _instance->GetData(DATA_DEAD_ELEMENTALS);
|
||||
Talk(BRANN_1_ELEMENTAL_DEAD + dead - 1);
|
||||
if (dead == 4)
|
||||
{
|
||||
_instance->DoCastSpellOnPlayers(SPELL_VAULT_OF_LIGHTS_CREDIT);
|
||||
if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_ANRAPHET_GUID)))
|
||||
anraphet->CastSpell(me, SPELL_ALPHA_BEAMS_BACK_CAST);
|
||||
anraphet->AI()->DoAction(ACTION_ANRAPHET_INTRO);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override { } // Never evade
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetHallsOfOriginationAI<npc_alpha_beamAI>(creature);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
class npc_brann_bronzebeard_anraphet : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_brann_bronzebeard_anraphet() : CreatureScript("npc_brann_bronzebeard_anraphet") { }
|
||||
|
||||
struct npc_brann_bronzebeard_anraphetAI : public CreatureAI
|
||||
{
|
||||
npc_brann_bronzebeard_anraphetAI(Creature* creature) : CreatureAI(creature), _currentPoint(0), _instance(creature->GetInstanceScript()) { }
|
||||
|
||||
bool OnGossipSelect(Player* /*player*/, uint32 menuId, uint32 action) override
|
||||
{
|
||||
if (_instance->GetBossState(BOSS_VAULT_OF_LIGHTS) == DONE)
|
||||
return true;
|
||||
|
||||
if (menuId == GOSSIP_MENU_START_INTRO && !action)
|
||||
{
|
||||
_instance->SetBossState(BOSS_VAULT_OF_LIGHTS, IN_PROGRESS);
|
||||
_currentPoint = 0;
|
||||
events.Reset();
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
me->SetWalk(true);
|
||||
Talk(BRANN_SAY_DOOR_INTRO);
|
||||
events.ScheduleEvent(EVENT_BRANN_UNLOCK_DOOR, 7500ms);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_ELEMENTAL_DIED:
|
||||
{
|
||||
uint32 dead = _instance->GetData(DATA_DEAD_ELEMENTALS);
|
||||
Talk(BRANN_1_ELEMENTAL_DEAD + dead - 1);
|
||||
if (dead == 4)
|
||||
{
|
||||
_instance->DoCastSpellOnPlayers(SPELL_VAULT_OF_LIGHTS_CREDIT);
|
||||
if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_ANRAPHET_GUID)))
|
||||
anraphet->AI()->DoAction(ACTION_ANRAPHET_INTRO);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACTION_ANRAPHET_DIED:
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BRANN_MOVE_INTRO:
|
||||
if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO)
|
||||
me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]);
|
||||
break;
|
||||
case EVENT_BRANN_UNLOCK_DOOR:
|
||||
Talk(BRANN_SAY_UNLOCK_DOOR);
|
||||
_instance->SetBossState(BOSS_VAULT_OF_LIGHTS, DONE);
|
||||
_instance->TriggerGameEvent(ACHIEV_VAULT_OF_LIGHTS_EVENT);
|
||||
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 3500ms);
|
||||
break;
|
||||
case EVENT_BRANN_THINK:
|
||||
Talk(BRANN_SAY_THINK);
|
||||
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_1, 6s);
|
||||
break;
|
||||
case EVENT_BRANN_SET_ORIENTATION_1:
|
||||
me->SetFacingTo(5.445427f);
|
||||
Talk(BRANN_SAY_MIRRORS);
|
||||
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_2, 1s);
|
||||
break;
|
||||
case EVENT_BRANN_SET_ORIENTATION_2:
|
||||
me->SetFacingTo(0.6283185f);
|
||||
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_3, 2500ms);
|
||||
break;
|
||||
case EVENT_BRANN_SET_ORIENTATION_3:
|
||||
me->SetFacingTo(0.01745329f);
|
||||
events.ScheduleEvent(EVENT_BRANN_SAY_ELEMENTALS, 200ms);
|
||||
break;
|
||||
case EVENT_BRANN_SAY_ELEMENTALS:
|
||||
Talk(BRANN_SAY_ELEMENTALS);
|
||||
events.ScheduleEvent(EVENT_BRANN_SAY_GET_IT, 3500ms);
|
||||
break;
|
||||
case EVENT_BRANN_SAY_GET_IT:
|
||||
Talk(BRANN_SAY_GET_IT);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
break;
|
||||
case EVENT_BRANN_SET_ORIENTATION_4:
|
||||
me->SetFacingTo(3.141593f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 movementType, uint32 pointId) override
|
||||
{
|
||||
if (movementType != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
_currentPoint = pointId + 1;
|
||||
Milliseconds delay = 1ms;
|
||||
|
||||
switch (pointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(BRANN_SAY_TROGGS);
|
||||
events.ScheduleEvent(EVENT_BRANN_THINK, 15s);
|
||||
return;
|
||||
case 1:
|
||||
Talk(BRANN_SAY_ANRAPHET_DIED);
|
||||
delay = 1s;
|
||||
break;
|
||||
case 14:
|
||||
Talk(BRANN_SAY_MOMENT);
|
||||
delay = 2200ms;
|
||||
break;
|
||||
case 16:
|
||||
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_4, 6s);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay);
|
||||
}
|
||||
|
||||
protected:
|
||||
EventMap events;
|
||||
uint32 _currentPoint;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetHallsOfOriginationAI<npc_brann_bronzebeard_anraphetAI>(creature);
|
||||
case ACTION_ANRAPHET_DIED:
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1s);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class spell_anraphet_alpha_beams : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_anraphet_alpha_beams() : SpellScriptLoader("spell_anraphet_alpha_beams") { }
|
||||
|
||||
class spell_anraphet_alpha_beams_SpellScript : public SpellScript
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
if (targets.empty())
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BRANN_MOVE_INTRO:
|
||||
if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO)
|
||||
me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]);
|
||||
break;
|
||||
case EVENT_BRANN_UNLOCK_DOOR:
|
||||
Talk(BRANN_SAY_UNLOCK_DOOR);
|
||||
_instance->SetBossState(BOSS_VAULT_OF_LIGHTS, DONE);
|
||||
_instance->TriggerGameEvent(ACHIEV_VAULT_OF_LIGHTS_EVENT);
|
||||
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 3500ms);
|
||||
break;
|
||||
case EVENT_BRANN_THINK:
|
||||
Talk(BRANN_SAY_THINK);
|
||||
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_1, 6s);
|
||||
break;
|
||||
case EVENT_BRANN_SET_ORIENTATION_1:
|
||||
me->SetFacingTo(5.445427f);
|
||||
Talk(BRANN_SAY_MIRRORS);
|
||||
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_2, 1s);
|
||||
break;
|
||||
case EVENT_BRANN_SET_ORIENTATION_2:
|
||||
me->SetFacingTo(0.6283185f);
|
||||
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_3, 2500ms);
|
||||
break;
|
||||
case EVENT_BRANN_SET_ORIENTATION_3:
|
||||
me->SetFacingTo(0.01745329f);
|
||||
events.ScheduleEvent(EVENT_BRANN_SAY_ELEMENTALS, 200ms);
|
||||
break;
|
||||
case EVENT_BRANN_SAY_ELEMENTALS:
|
||||
Talk(BRANN_SAY_ELEMENTALS);
|
||||
events.ScheduleEvent(EVENT_BRANN_SAY_GET_IT, 3500ms);
|
||||
break;
|
||||
case EVENT_BRANN_SAY_GET_IT:
|
||||
Talk(BRANN_SAY_GET_IT);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
break;
|
||||
case EVENT_BRANN_SET_ORIENTATION_4:
|
||||
me->SetFacingTo(3.141593f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 movementType, uint32 pointId) override
|
||||
{
|
||||
if (movementType != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
_currentPoint = pointId + 1;
|
||||
Milliseconds delay = 1ms;
|
||||
|
||||
switch (pointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(BRANN_SAY_TROGGS);
|
||||
events.ScheduleEvent(EVENT_BRANN_THINK, 15s);
|
||||
return;
|
||||
|
||||
WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
targets.clear();
|
||||
targets.push_back(target);
|
||||
case 1:
|
||||
Talk(BRANN_SAY_ANRAPHET_DIED);
|
||||
delay = 1s;
|
||||
break;
|
||||
case 14:
|
||||
Talk(BRANN_SAY_MOMENT);
|
||||
delay = 2200ms;
|
||||
break;
|
||||
case 16:
|
||||
events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_4, 6s);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anraphet_alpha_beams_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay);
|
||||
}
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
protected:
|
||||
EventMap events;
|
||||
uint32 _currentPoint;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
class spell_anraphet_alpha_beams : public SpellScript
|
||||
{
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
return new spell_anraphet_alpha_beams_SpellScript();
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
Trinity::Containers::RandomResize(targets, 1);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anraphet_alpha_beams::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
// 77106 - Omega Stance (Summon)
|
||||
class spell_anraphet_omega_stance_summon : public SpellScriptLoader
|
||||
class spell_anraphet_omega_stance_summon : public SpellScript
|
||||
{
|
||||
public:
|
||||
spell_anraphet_omega_stance_summon() : SpellScriptLoader("spell_anraphet_omega_stance_summon") { }
|
||||
|
||||
class spell_anraphet_omega_stance_summon_SpellScript : public SpellScript
|
||||
void SetDest(SpellDestination& dest)
|
||||
{
|
||||
void SetDest(SpellDestination& dest)
|
||||
{
|
||||
dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f });
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_anraphet_omega_stance_summon_SpellScript::SetDest, EFFECT_0, TARGET_DEST_DEST);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_anraphet_omega_stance_summon_SpellScript();
|
||||
dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f });
|
||||
}
|
||||
};
|
||||
|
||||
// 77127 Omega Stance Spider Effect
|
||||
class spell_anraphet_omega_stance_spider_effect : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_anraphet_omega_stance_spider_effect() : SpellScriptLoader("spell_anraphet_omega_stance_spider_effect") { }
|
||||
|
||||
class spell_anraphet_omega_stance_spider_effect_SpellScript : public SpellScript
|
||||
void Register() override
|
||||
{
|
||||
void SetDest(SpellDestination& dest)
|
||||
{
|
||||
// Do our own calculations for the destination position.
|
||||
/// TODO: Remove this once we find a general rule for WorldObject::MovePosition (this spell shouldn't take the Z change into consideration)
|
||||
Unit* caster = GetCaster();
|
||||
float angle = rand_norm() * static_cast<float>(2 * M_PI);
|
||||
uint32 dist = caster->GetCombatReach() + GetSpellInfo()->GetEffect(EFFECT_0).CalcRadius(caster, SpellTargetIndex::TargetB) * rand_norm();
|
||||
|
||||
float x = caster->GetPositionX() + dist * std::cos(angle);
|
||||
float y = caster->GetPositionY() + dist * std::sin(angle);
|
||||
float z = caster->GetMap()->GetHeight(caster->GetPhaseShift(), x, y, caster->GetPositionZ());
|
||||
float o = dest._position.GetOrientation();
|
||||
|
||||
dest.Relocate({ x, y, z, o });
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_anraphet_omega_stance_spider_effect_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_RANDOM);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_anraphet_omega_stance_spider_effect_SpellScript();
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_anraphet_omega_stance_summon::SetDest, EFFECT_0, TARGET_DEST_DEST);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_anraphet()
|
||||
{
|
||||
new boss_anraphet();
|
||||
new spell_anraphet_alpha_beams();
|
||||
new npc_brann_bronzebeard_anraphet();
|
||||
new npc_alpha_beam();
|
||||
new spell_anraphet_omega_stance_summon();
|
||||
new spell_anraphet_omega_stance_spider_effect();
|
||||
new npc_omega_stance();
|
||||
RegisterHallsOfOriginationCreatureAI(boss_anraphet);
|
||||
RegisterHallsOfOriginationCreatureAI(npc_brann_bronzebeard_anraphet);
|
||||
RegisterHallsOfOriginationCreatureAI(npc_alpha_beam);
|
||||
RegisterHallsOfOriginationCreatureAI(npc_omega_stance);
|
||||
RegisterSpellScript(spell_anraphet_alpha_beams);
|
||||
RegisterSpellScript(spell_anraphet_omega_stance_summon);
|
||||
}
|
||||
|
||||
@@ -92,236 +92,203 @@ protected:
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
class boss_earthrager_ptah : public CreatureScript
|
||||
struct boss_earthrager_ptah : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_earthrager_ptah() : CreatureScript("boss_earthrager_ptah") { }
|
||||
boss_earthrager_ptah(Creature* creature) : BossAI(creature, BOSS_EARTHRAGER_PTAH), _summonDeaths(0), _hasDispersed(false) { }
|
||||
|
||||
struct boss_earthrager_ptahAI : public BossAI
|
||||
void Cleanup()
|
||||
{
|
||||
boss_earthrager_ptahAI(Creature* creature) : BossAI(creature, BOSS_EARTHRAGER_PTAH), _summonDeaths(0), _hasDispersed(false) { }
|
||||
std::list<Creature*> units;
|
||||
|
||||
void Cleanup()
|
||||
GetCreatureListWithEntryInGrid(units, me, NPC_DUSTBONE_HORROR, 100.0f);
|
||||
for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr)
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
|
||||
units.clear();
|
||||
GetCreatureListWithEntryInGrid(units, me, NPC_JEWELED_SCARAB, 100.0f);
|
||||
for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr)
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_summonDeaths = 0;
|
||||
_hasDispersed = false;
|
||||
Cleanup();
|
||||
_Reset();
|
||||
events.SetPhase(PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_RAGING_SMASH, 7s, 12s, 0, PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_FLAME_BOLT, 15s, 0, PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_EARTH_SPIKE, 16s, 21s, 0, PHASE_NORMAL);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(50, damage) && (events.GetPhaseMask() & PHASE_MASK_NORMAL) && !_hasDispersed)
|
||||
{
|
||||
std::list<Creature*> units;
|
||||
events.SetPhase(PHASE_DISPERSE);
|
||||
_hasDispersed = true;
|
||||
|
||||
GetCreatureListWithEntryInGrid(units, me, NPC_DUSTBONE_HORROR, 100.0f);
|
||||
for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr)
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
me->AttackStop();
|
||||
DoCast(me, SPELL_SANDSTORM);
|
||||
me->GetMap()->SetZoneWeather(AREA_TOMB_OF_THE_EARTHRAGER, WEATHER_STATE_LIGHT_SANDSTORM, 1.0f);
|
||||
events.ScheduleEvent(EVENT_PTAH_EXPLODE, 6s, 0, PHASE_DISPERSE);
|
||||
events.ScheduleEvent(EVENT_QUICKSAND, 10s, 0, PHASE_DISPERSE);
|
||||
|
||||
units.clear();
|
||||
GetCreatureListWithEntryInGrid(units, me, NPC_JEWELED_SCARAB, 100.0f);
|
||||
for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr)
|
||||
(*itr)->DespawnOrUnsummon();
|
||||
}
|
||||
std::list<Creature*> stalkers;
|
||||
GetCreatureListWithEntryInGrid(stalkers, me, NPC_BEETLE_STALKER, 100.0f);
|
||||
std::list<Creature*> beetlers = stalkers;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_summonDeaths = 0;
|
||||
_hasDispersed = false;
|
||||
Cleanup();
|
||||
_Reset();
|
||||
events.SetPhase(PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_RAGING_SMASH, 7s, 12s, 0, PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_FLAME_BOLT, 15s, 0, PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_EARTH_SPIKE, 16s, 21s, 0, PHASE_NORMAL);
|
||||
}
|
||||
Trinity::Containers::RandomResize(beetlers, 9); // Holds the summoners of Jeweled Scarab
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(50, damage) && (events.GetPhaseMask() & PHASE_MASK_NORMAL) && !_hasDispersed)
|
||||
for (std::list<Creature*>::iterator itr = beetlers.begin(); itr != beetlers.end(); ++itr)
|
||||
{
|
||||
events.SetPhase(PHASE_DISPERSE);
|
||||
_hasDispersed = true;
|
||||
stalkers.remove((*itr)); // Remove it to prevent a single trigger from spawning multiple npcs.
|
||||
(*itr)->CastSpell((*itr), SPELL_BEETLE_BURROW); // Cast visual
|
||||
// Summon after 5 seconds.
|
||||
(*itr)->m_Events.AddEventAtOffset(new SummonScarab((*itr), instance), 5s);
|
||||
}
|
||||
|
||||
me->AttackStop();
|
||||
DoCast(me, SPELL_SANDSTORM);
|
||||
me->GetMap()->SetZoneWeather(AREA_TOMB_OF_THE_EARTHRAGER, WEATHER_STATE_LIGHT_SANDSTORM, 1.0f);
|
||||
events.ScheduleEvent(EVENT_PTAH_EXPLODE, 6s, 0, PHASE_DISPERSE);
|
||||
events.ScheduleEvent(EVENT_QUICKSAND, 10s, 0, PHASE_DISPERSE);
|
||||
Trinity::Containers::RandomResize(stalkers, 2); // Holds the summoners of Dustbone Horror
|
||||
|
||||
std::list<Creature*> stalkers;
|
||||
GetCreatureListWithEntryInGrid(stalkers, me, NPC_BEETLE_STALKER, 100.0f);
|
||||
std::list<Creature*> beetlers = stalkers;
|
||||
for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
|
||||
(*itr)->CastSpell((*itr), SPELL_SUMMON_DUSTBONE_HORROR);
|
||||
}
|
||||
}
|
||||
|
||||
Trinity::Containers::RandomResize(beetlers, 9); // Holds the summoners of Jeweled Scarab
|
||||
|
||||
for (std::list<Creature*>::iterator itr = beetlers.begin(); itr != beetlers.end(); ++itr)
|
||||
{
|
||||
stalkers.remove((*itr)); // Remove it to prevent a single trigger from spawning multiple npcs.
|
||||
(*itr)->CastSpell((*itr), SPELL_BEETLE_BURROW); // Cast visual
|
||||
// Summon after 5 seconds.
|
||||
(*itr)->m_Events.AddEventAtOffset(new SummonScarab((*itr), instance), 5s);
|
||||
}
|
||||
|
||||
Trinity::Containers::RandomResize(stalkers, 2); // Holds the summoners of Dustbone Horror
|
||||
|
||||
for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
|
||||
(*itr)->CastSpell((*itr), SPELL_SUMMON_DUSTBONE_HORROR);
|
||||
void SetData(uint32 index, uint32 /*value*/) override
|
||||
{
|
||||
if (index == DATA_SUMMON_DEATHS)
|
||||
{
|
||||
++_summonDeaths;
|
||||
if (_summonDeaths == 11) // All summons died
|
||||
{
|
||||
me->GetMap()->SetZoneWeather(AREA_TOMB_OF_THE_EARTHRAGER, WEATHER_STATE_FOG, 0.0f);
|
||||
me->RemoveAurasDueToSpell(SPELL_PTAH_EXPLOSION);
|
||||
events.SetPhase(PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_RAGING_SMASH, 7s, 12s, 0, PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_FLAME_BOLT, 15s, 0, PHASE_NORMAL);
|
||||
events.ScheduleEvent(EVENT_EARTH_SPIKE, 16s, 21s, 0, PHASE_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 index, uint32 /*value*/) override
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(BOSS_EARTHRAGER_PTAH, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() || !CheckInRoom())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
if (index == DATA_SUMMON_DEATHS)
|
||||
switch (eventId)
|
||||
{
|
||||
++_summonDeaths;
|
||||
if (_summonDeaths == 11) // All summons died
|
||||
{
|
||||
me->GetMap()->SetZoneWeather(AREA_TOMB_OF_THE_EARTHRAGER, WEATHER_STATE_FOG, 0.0f);
|
||||
me->RemoveAurasDueToSpell(SPELL_PTAH_EXPLOSION);
|
||||
events.SetPhase(PHASE_NORMAL);
|
||||
case EVENT_RAGING_SMASH:
|
||||
DoCastVictim(SPELL_RAGING_SMASH);
|
||||
events.ScheduleEvent(EVENT_RAGING_SMASH, 7s, 12s, 0, PHASE_NORMAL);
|
||||
break;
|
||||
case EVENT_FLAME_BOLT:
|
||||
DoCast(me, SPELL_FLAME_BOLT);
|
||||
events.ScheduleEvent(EVENT_FLAME_BOLT, 15s, 0, PHASE_NORMAL);
|
||||
break;
|
||||
case EVENT_EARTH_SPIKE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||
DoCast(target, SPELL_EARTH_SPIKE_WARN);
|
||||
events.ScheduleEvent(EVENT_EARTH_SPIKE, 16s, 21s, 0, PHASE_NORMAL);
|
||||
}
|
||||
break;
|
||||
case EVENT_PTAH_EXPLODE:
|
||||
DoCast(me, SPELL_PTAH_EXPLOSION);
|
||||
break;
|
||||
case EVENT_QUICKSAND:
|
||||
// Spell not in DBC, it is not cast either, according to sniffs
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||
if (Creature* quicksand = me->SummonCreature(NPC_QUICKSAND, *target))
|
||||
quicksand->SetCreatedBySpell(SPELL_SUMMON_QUICKSAND);
|
||||
events.ScheduleEvent(EVENT_QUICKSAND, 10s, 0, PHASE_DISPERSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
if (events.GetPhaseMask() & PHASE_MASK_NORMAL) // Do not melee in the disperse phase
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
Cleanup();
|
||||
}
|
||||
protected:
|
||||
uint8 _summonDeaths;
|
||||
bool _hasDispersed;
|
||||
};
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(BOSS_EARTHRAGER_PTAH, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() || !CheckInRoom())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_RAGING_SMASH:
|
||||
DoCastVictim(SPELL_RAGING_SMASH);
|
||||
events.ScheduleEvent(EVENT_RAGING_SMASH, 7s, 12s, 0, PHASE_NORMAL);
|
||||
break;
|
||||
case EVENT_FLAME_BOLT:
|
||||
DoCast(me, SPELL_FLAME_BOLT);
|
||||
events.ScheduleEvent(EVENT_FLAME_BOLT, 15s, 0, PHASE_NORMAL);
|
||||
break;
|
||||
case EVENT_EARTH_SPIKE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||
DoCast(target, SPELL_EARTH_SPIKE_WARN);
|
||||
events.ScheduleEvent(EVENT_EARTH_SPIKE, 16s, 21s, 0, PHASE_NORMAL);
|
||||
break;
|
||||
case EVENT_PTAH_EXPLODE:
|
||||
DoCast(me, SPELL_PTAH_EXPLOSION);
|
||||
break;
|
||||
case EVENT_QUICKSAND:
|
||||
// Spell not in DBC, it is not cast either, according to sniffs
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
|
||||
if (Creature* quicksand = me->SummonCreature(NPC_QUICKSAND, *target))
|
||||
quicksand->SetCreatedBySpell(SPELL_SUMMON_QUICKSAND);
|
||||
events.ScheduleEvent(EVENT_QUICKSAND, 10s, 0, PHASE_DISPERSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (events.GetPhaseMask() & PHASE_MASK_NORMAL) // Do not melee in the disperse phase
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8 _summonDeaths;
|
||||
bool _hasDispersed;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
class spell_earthrager_ptah_flame_bolt : public SpellScript
|
||||
{
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
return GetHallsOfOriginationAI<boss_earthrager_ptahAI>(creature);
|
||||
Trinity::Containers::RandomResize(targets, GetCaster()->GetMap()->IsHeroic() ? 3 : 2);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_earthrager_ptah_flame_bolt::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_earthrager_ptah_flame_bolt : public SpellScriptLoader
|
||||
class spell_earthrager_ptah_explosion : public AuraScript
|
||||
{
|
||||
public:
|
||||
spell_earthrager_ptah_flame_bolt() : SpellScriptLoader("spell_earthrager_ptah_flame_bolt") { }
|
||||
|
||||
class spell_earthrager_ptah_flame_bolt_SpellScript : public SpellScript
|
||||
{
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
Trinity::Containers::RandomResize(targets, GetCaster()->GetMap()->IsHeroic() ? 3 : 2);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_earthrager_ptah_flame_bolt_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_earthrager_ptah_flame_bolt_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_earthrager_ptah_explosion : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_earthrager_ptah_explosion() : SpellScriptLoader("spell_earthrager_ptah_explosion") { }
|
||||
|
||||
class spell_earthrager_ptah_explosion_AuraScript : public AuraScript
|
||||
void SetFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
void SetFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
if (Unit* ptah = GetCaster())
|
||||
{
|
||||
if (Unit* ptah = GetCaster())
|
||||
{
|
||||
ptah->SetUninteractible(true);
|
||||
ptah->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
|
||||
ptah->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
|
||||
}
|
||||
ptah->SetUninteractible(true);
|
||||
ptah->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
|
||||
ptah->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* ptah = GetCaster())
|
||||
{
|
||||
ptah->SetUninteractible(false);
|
||||
ptah->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
|
||||
ptah->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_earthrager_ptah_explosion_AuraScript::SetFlags, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_earthrager_ptah_explosion_AuraScript::RemoveFlags, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
void RemoveFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
return new spell_earthrager_ptah_explosion_AuraScript();
|
||||
if (Unit* ptah = GetCaster())
|
||||
{
|
||||
ptah->SetUninteractible(false);
|
||||
ptah->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
|
||||
ptah->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_earthrager_ptah_explosion::SetFlags, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_earthrager_ptah_explosion::RemoveFlags, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_earthrager_ptah()
|
||||
{
|
||||
new boss_earthrager_ptah();
|
||||
new spell_earthrager_ptah_flame_bolt();
|
||||
new spell_earthrager_ptah_explosion();
|
||||
RegisterHallsOfOriginationCreatureAI(boss_earthrager_ptah);
|
||||
RegisterSpellScript(spell_earthrager_ptah_flame_bolt);
|
||||
RegisterSpellScript(spell_earthrager_ptah_explosion);
|
||||
}
|
||||
|
||||
@@ -74,309 +74,265 @@ enum Actions
|
||||
ACTION_DISABLE_BEACON,
|
||||
};
|
||||
|
||||
class boss_temple_guardian_anhuur : public CreatureScript
|
||||
struct boss_temple_guardian_anhuur : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_temple_guardian_anhuur() : CreatureScript("boss_temple_guardian_anhuur") { }
|
||||
|
||||
struct boss_temple_guardian_anhuurAI : public BossAI
|
||||
boss_temple_guardian_anhuur(Creature* creature) : BossAI(creature, BOSS_TEMPLE_GUARDIAN_ANHUUR)
|
||||
{
|
||||
boss_temple_guardian_anhuurAI(Creature* creature) : BossAI(creature, BOSS_TEMPLE_GUARDIAN_ANHUUR)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_phase = PHASE_FIRST_SHIELD;
|
||||
_oldPhase = PHASE_FIRST_SHIELD;
|
||||
_beacons = 0;
|
||||
}
|
||||
void Initialize()
|
||||
{
|
||||
_phase = PHASE_FIRST_SHIELD;
|
||||
_oldPhase = PHASE_FIRST_SHIELD;
|
||||
_beacons = 0;
|
||||
}
|
||||
|
||||
void CleanStalkers()
|
||||
void CleanStalkers()
|
||||
{
|
||||
std::list<Creature*> stalkers;
|
||||
GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f);
|
||||
for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
|
||||
{
|
||||
std::list<Creature*> stalkers;
|
||||
GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f);
|
||||
for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
|
||||
(*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_RIGHT);
|
||||
(*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
_Reset();
|
||||
CleanStalkers();
|
||||
me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT);
|
||||
events.ScheduleEvent(EVENT_DIVINE_RECKONING, 10s, 12s);
|
||||
events.ScheduleEvent(EVENT_BURNING_LIGHT, 12s);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
{
|
||||
if ((me->HealthBelowPctDamaged(66, damage) && _phase == PHASE_FIRST_SHIELD) ||
|
||||
(me->HealthBelowPctDamaged(33, damage) && _phase == PHASE_SECOND_SHIELD))
|
||||
{
|
||||
_beacons = 2;
|
||||
_phase++; // Increase the phase
|
||||
_oldPhase = _phase;
|
||||
|
||||
_phase = PHASE_SHIELDED;
|
||||
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
me->AttackStop();
|
||||
DoCast(me, SPELL_TELEPORT);
|
||||
|
||||
DoCast(me, SPELL_SHIELD_OF_LIGHT);
|
||||
|
||||
DoCastAOE(SPELL_ACTIVATE_BEACONS);
|
||||
|
||||
GameObject* door = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ANHUUR_DOOR));
|
||||
if (door)
|
||||
{
|
||||
(*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_RIGHT);
|
||||
(*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_LEFT);
|
||||
std::list<Creature*> stalkers;
|
||||
GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f);
|
||||
|
||||
stalkers.remove_if(Trinity::HeightDifferenceCheck(door, 0.0f, false)); // Target only the bottom ones
|
||||
for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetPositionX() > door->GetPositionX())
|
||||
{
|
||||
(*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_LEFT, true);
|
||||
(*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_LEFT, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_RIGHT, true);
|
||||
(*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_RIGHT, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DoCast(me, SPELL_REVERBERATING_HYMN);
|
||||
|
||||
Talk(EMOTE_SHIELD);
|
||||
Talk(SAY_SHIELD);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == ACTION_DISABLE_BEACON)
|
||||
{
|
||||
--_beacons;
|
||||
if (!_beacons)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT);
|
||||
Talk(EMOTE_UNSHIELD);
|
||||
_phase = _oldPhase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
_Reset();
|
||||
CleanStalkers();
|
||||
me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT);
|
||||
events.ScheduleEvent(EVENT_DIVINE_RECKONING, 10s, 12s);
|
||||
events.ScheduleEvent(EVENT_BURNING_LIGHT, 12s);
|
||||
}
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(BOSS_TEMPLE_GUARDIAN_ANHUUR, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() || !CheckInRoom() || me->GetCurrentSpell(CURRENT_CHANNELED_SPELL) || _phase == PHASE_SHIELDED)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
if ((me->HealthBelowPctDamaged(66, damage) && _phase == PHASE_FIRST_SHIELD) ||
|
||||
(me->HealthBelowPctDamaged(33, damage) && _phase == PHASE_SECOND_SHIELD))
|
||||
switch (eventId)
|
||||
{
|
||||
_beacons = 2;
|
||||
_phase++; // Increase the phase
|
||||
_oldPhase = _phase;
|
||||
|
||||
_phase = PHASE_SHIELDED;
|
||||
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
me->AttackStop();
|
||||
DoCast(me, SPELL_TELEPORT);
|
||||
|
||||
DoCast(me, SPELL_SHIELD_OF_LIGHT);
|
||||
|
||||
DoCastAOE(SPELL_ACTIVATE_BEACONS);
|
||||
|
||||
GameObject* door = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ANHUUR_DOOR));
|
||||
if (door)
|
||||
case EVENT_DIVINE_RECKONING:
|
||||
DoCastVictim(SPELL_DIVINE_RECKONING);
|
||||
events.ScheduleEvent(EVENT_DIVINE_RECKONING, 10s, 12s);
|
||||
break;
|
||||
case EVENT_BURNING_LIGHT:
|
||||
{
|
||||
Unit* unit = SelectTarget(SelectTargetMethod::Random, 0, NonTankTargetSelector(me));
|
||||
if (!unit)
|
||||
unit = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
|
||||
DoCast(unit, SPELL_BURNING_LIGHT);
|
||||
events.ScheduleEvent(EVENT_SEAR, 2s);
|
||||
events.ScheduleEvent(EVENT_BURNING_LIGHT, 12s);
|
||||
break;
|
||||
}
|
||||
case EVENT_SEAR:
|
||||
{
|
||||
Unit* target = me->FindNearestCreature(NPC_SEARING_LIGHT, 100.0f);
|
||||
if (!target)
|
||||
break;
|
||||
|
||||
std::list<Creature*> stalkers;
|
||||
GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f);
|
||||
stalkers.remove_if(Trinity::HeightDifferenceCheck(ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ANHUUR_DOOR)), 5.0f, true));
|
||||
|
||||
stalkers.remove_if(Trinity::HeightDifferenceCheck(door, 0.0f, false)); // Target only the bottom ones
|
||||
for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->GetPositionX() > door->GetPositionX())
|
||||
{
|
||||
(*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_LEFT, true);
|
||||
(*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_LEFT, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_RIGHT, true);
|
||||
(*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_RIGHT, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stalkers.empty())
|
||||
break;
|
||||
|
||||
DoCast(me, SPELL_REVERBERATING_HYMN);
|
||||
stalkers.sort(Trinity::ObjectDistanceOrderPred(target));
|
||||
|
||||
Talk(EMOTE_SHIELD);
|
||||
Talk(SAY_SHIELD);
|
||||
}
|
||||
}
|
||||
// Get the closest statue face (any of its eyes)
|
||||
Creature* eye1 = stalkers.front();
|
||||
stalkers.remove(eye1); // Remove the eye.
|
||||
stalkers.sort(Trinity::ObjectDistanceOrderPred(eye1)); // Find the second eye.
|
||||
Creature* eye2 = stalkers.front();
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == ACTION_DISABLE_BEACON)
|
||||
{
|
||||
--_beacons;
|
||||
if (!_beacons)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT);
|
||||
Talk(EMOTE_UNSHIELD);
|
||||
_phase = _oldPhase;
|
||||
eye1->CastSpell(eye1, SPELL_SEARING_LIGHT, true);
|
||||
eye2->CastSpell(eye2, SPELL_SEARING_LIGHT, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
|
||||
Talk(SAY_AGGRO);
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
}
|
||||
private:
|
||||
uint8 _phase;
|
||||
uint8 _oldPhase;
|
||||
uint8 _beacons;
|
||||
};
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
_JustReachedHome();
|
||||
instance->SetBossState(BOSS_TEMPLE_GUARDIAN_ANHUUR, FAIL);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() || !CheckInRoom() || me->GetCurrentSpell(CURRENT_CHANNELED_SPELL) || _phase == PHASE_SHIELDED)
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_DIVINE_RECKONING:
|
||||
DoCastVictim(SPELL_DIVINE_RECKONING);
|
||||
events.ScheduleEvent(EVENT_DIVINE_RECKONING, 10s, 12s);
|
||||
break;
|
||||
case EVENT_BURNING_LIGHT:
|
||||
{
|
||||
Unit* unit = SelectTarget(SelectTargetMethod::Random, 0, NonTankTargetSelector(me));
|
||||
if (!unit)
|
||||
unit = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true);
|
||||
DoCast(unit, SPELL_BURNING_LIGHT);
|
||||
events.ScheduleEvent(EVENT_SEAR, 2s);
|
||||
events.ScheduleEvent(EVENT_BURNING_LIGHT, 12s);
|
||||
break;
|
||||
}
|
||||
case EVENT_SEAR:
|
||||
{
|
||||
Unit* target = me->FindNearestCreature(NPC_SEARING_LIGHT, 100.0f);
|
||||
if (!target)
|
||||
break;
|
||||
|
||||
std::list<Creature*> stalkers;
|
||||
GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f);
|
||||
stalkers.remove_if(Trinity::HeightDifferenceCheck(ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ANHUUR_DOOR)), 5.0f, true));
|
||||
|
||||
if (stalkers.empty())
|
||||
break;
|
||||
|
||||
stalkers.sort(Trinity::ObjectDistanceOrderPred(target));
|
||||
|
||||
// Get the closest statue face (any of its eyes)
|
||||
Creature* eye1 = stalkers.front();
|
||||
stalkers.remove(eye1); // Remove the eye.
|
||||
stalkers.sort(Trinity::ObjectDistanceOrderPred(eye1)); // Find the second eye.
|
||||
Creature* eye2 = stalkers.front();
|
||||
|
||||
eye1->CastSpell(eye1, SPELL_SEARING_LIGHT, true);
|
||||
eye2->CastSpell(eye2, SPELL_SEARING_LIGHT, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _phase;
|
||||
uint8 _oldPhase;
|
||||
uint8 _beacons;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
class spell_anhuur_shield_of_light : public SpellScript
|
||||
{
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
return GetHallsOfOriginationAI<boss_temple_guardian_anhuurAI>(creature);
|
||||
if (InstanceScript* const script = GetCaster()->GetInstanceScript())
|
||||
{
|
||||
if (GameObject* go = ObjectAccessor::GetGameObject(*GetCaster(), script->GetGuidData(DATA_ANHUUR_DOOR)))
|
||||
{
|
||||
targets.remove_if(Trinity::HeightDifferenceCheck(go, 5.0f, false));
|
||||
targets.remove(GetCaster());
|
||||
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
|
||||
targets.resize(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anhuur_shield_of_light::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_anhuur_shield_of_light : public SpellScriptLoader
|
||||
class spell_anhuur_disable_beacon_beams : public SpellScript
|
||||
{
|
||||
public:
|
||||
spell_anhuur_shield_of_light() : SpellScriptLoader("spell_anhuur_shield_of_light") { }
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetHitUnit()->RemoveAurasDueToSpell(GetEffectValue());
|
||||
}
|
||||
|
||||
class spell_anhuur_shield_of_light_SpellScript : public SpellScript
|
||||
{
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (InstanceScript* const script = GetCaster()->GetInstanceScript())
|
||||
{
|
||||
if (GameObject* go = ObjectAccessor::GetGameObject(*GetCaster(), script->GetGuidData(DATA_ANHUUR_DOOR)))
|
||||
{
|
||||
targets.remove_if(Trinity::HeightDifferenceCheck(go, 5.0f, false));
|
||||
targets.remove(GetCaster());
|
||||
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
|
||||
targets.resize(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
void Notify(SpellEffIndex /*index*/)
|
||||
{
|
||||
GameObject* caster = GetGObjCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anhuur_shield_of_light_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
}
|
||||
};
|
||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
||||
if (Creature* anhuur = instance->GetCreature(BOSS_TEMPLE_GUARDIAN_ANHUUR))
|
||||
if (CreatureAI* ai = anhuur->AI())
|
||||
ai->DoAction(ACTION_DISABLE_BEACON);
|
||||
}
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_anhuur_shield_of_light_SpellScript();
|
||||
}
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_anhuur_disable_beacon_beams::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
OnEffectHit += SpellEffectFn(spell_anhuur_disable_beacon_beams::Notify, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_anhuur_disable_beacon_beams : public SpellScriptLoader
|
||||
class spell_anhuur_divine_reckoning : public AuraScript
|
||||
{
|
||||
public:
|
||||
spell_anhuur_disable_beacon_beams() : SpellScriptLoader("spell_anhuur_disable_beacon_beams") { }
|
||||
|
||||
class spell_anhuur_disable_beacon_beams_SpellScript : public SpellScript
|
||||
{
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetHitUnit()->RemoveAurasDueToSpell(GetEffectValue());
|
||||
}
|
||||
|
||||
void Notify(SpellEffIndex /*index*/)
|
||||
{
|
||||
GameObject* caster = GetGObjCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
|
||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
||||
if (Creature* anhuur = instance->GetCreature(BOSS_TEMPLE_GUARDIAN_ANHUUR))
|
||||
if (CreatureAI* ai = anhuur->AI())
|
||||
ai->DoAction(ACTION_DISABLE_BEACON);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_anhuur_disable_beacon_beams_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
OnEffectHit += SpellEffectFn(spell_anhuur_disable_beacon_beams_SpellScript::Notify, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_anhuur_disable_beacon_beams_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_anhuur_divine_reckoning : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_anhuur_divine_reckoning() : SpellScriptLoader("spell_anhuur_divine_reckoning") { }
|
||||
|
||||
class spell_anhuur_divine_reckoning_AuraScript : public AuraScript
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
CastSpellExtraArgs args;
|
||||
args.AddSpellMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount());
|
||||
caster->CastSpell(GetTarget(), aurEff->GetSpellEffectInfo().TriggerSpell, args);
|
||||
}
|
||||
CastSpellExtraArgs args;
|
||||
args.AddSpellMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount());
|
||||
caster->CastSpell(GetTarget(), aurEff->GetSpellEffectInfo().TriggerSpell, args);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_anhuur_divine_reckoning_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
void Register() override
|
||||
{
|
||||
return new spell_anhuur_divine_reckoning_AuraScript();
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_anhuur_divine_reckoning::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_temple_guardian_anhuur()
|
||||
{
|
||||
new boss_temple_guardian_anhuur();
|
||||
new spell_anhuur_shield_of_light();
|
||||
new spell_anhuur_disable_beacon_beams();
|
||||
new spell_anhuur_divine_reckoning();
|
||||
RegisterHallsOfOriginationCreatureAI(boss_temple_guardian_anhuur);
|
||||
RegisterSpellScript(spell_anhuur_shield_of_light);
|
||||
RegisterSpellScript(spell_anhuur_disable_beacon_beams);
|
||||
RegisterSpellScript(spell_anhuur_divine_reckoning);
|
||||
}
|
||||
|
||||
@@ -122,4 +122,6 @@ inline AI* GetHallsOfOriginationAI(Creature* creature)
|
||||
return GetInstanceAI<AI>(creature, HoOScriptName);
|
||||
}
|
||||
|
||||
#define RegisterHallsOfOriginationCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetHallsOfOriginationAI)
|
||||
|
||||
#endif // HALLS_OF_ORIGINATION_H
|
||||
|
||||
Reference in New Issue
Block a user