diff options
5 files changed, 603 insertions, 772 deletions
diff --git a/sql/updates/world/master/2023_12_25_00_world.sql b/sql/updates/world/master/2023_12_25_00_world.sql new file mode 100644 index 00000000000..83fb83b1fc2 --- /dev/null +++ b/sql/updates/world/master/2023_12_25_00_world.sql @@ -0,0 +1 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`= 'spell_anraphet_omega_stance_spider_effect'; diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp index 18f7fff34de..1d1d591aecc 100644 --- a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp @@ -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() + void Reset() override + { + _Reset(); + me->SetWalk(false); + events.SetPhase(PHASE_INTRO); + if (instance->GetData(DATA_DEAD_ELEMENTALS) == 4) { - 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); + // Set to combat automatically, Brann's event won't repeat + me->SetUninteractible(false); + events.SetPhase(PHASE_COMBAT); + ScheduleCombatEvents(); + me->SetHomePosition(AnraphetActivatePos); } + } - 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 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); - 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); - if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_BRANN_0_GUID))) - brann->AI()->DoAction(ACTION_ANRAPHET_DIED); + _JustDied(); + } - _JustDied(); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(ANRAPHET_SAY_KILL); + } - 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 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 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; - void MovementInform(uint32 type, uint32 point) override + if (point == POINT_ANRAPHET_ACTIVATE) { - if (type != POINT_MOTION_TYPE) - return; - - if (point == POINT_ANRAPHET_ACTIVATE) - { - events.ScheduleEvent(EVENT_ANRAPHET_ACTIVATE, 1500ms, 0, PHASE_INTRO); - me->SetHomePosition(AnraphetActivatePos); - } + 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; + void UpdateAI(uint32 diff) override + { + if ((events.GetPhaseMask() & PHASE_MASK_COMBAT) && (!UpdateVictim() || !CheckInRoom())) + return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - 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; - } + 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 - { - return GetHallsOfOriginationAI<boss_anraphetAI>(creature); + 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") { } - - struct npc_omega_stanceAI : public ScriptedAI - { - npc_omega_stanceAI(Creature* creature) : ScriptedAI(creature) { } + npc_omega_stance(Creature* creature) : ScriptedAI(creature) { } - void IsSummonedBy(WorldObject* /*who*/) override - { - DoCast(me, SPELL_OMEGA_STANCE_SPIDER_TRIGGER, true); - } - - void EnterEvadeMode(EvadeReason /*why*/) override { } - }; + void IsSummonedBy(WorldObject* /*who*/) override + { + DoCast(me, SPELL_OMEGA_STANCE_SPIDER_TRIGGER, true); + } - 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 - { - npc_alpha_beamAI(Creature* creature) : ScriptedAI(creature), _instance(creature->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 InitializeAI() override + { + _instance = me->GetInstanceScript(); + } - void EnterEvadeMode(EvadeReason /*why*/) override { } // Never evade + void IsSummonedBy(WorldObject* /*summoner*/) override + { + if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_ANRAPHET_GUID))) + anraphet->CastSpell(me, SPELL_ALPHA_BEAMS_BACK_CAST); + } - private: - InstanceScript* _instance; - }; + void EnterEvadeMode(EvadeReason /*why*/) override { } // Never evade - CreatureAI* GetAI(Creature* creature) const override - { - return GetHallsOfOriginationAI<npc_alpha_beamAI>(creature); - } +private: + InstanceScript* _instance; }; -class npc_brann_bronzebeard_anraphet : public CreatureScript +struct npc_brann_bronzebeard_anraphet : public CreatureAI { - public: - npc_brann_bronzebeard_anraphet() : CreatureScript("npc_brann_bronzebeard_anraphet") { } + npc_brann_bronzebeard_anraphet(Creature* creature) : CreatureAI(creature), _currentPoint(0), _instance(nullptr) { } - 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 InitializeAI() override + { + _instance = me->GetInstanceScript(); + } - 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; - } - } + bool OnGossipSelect(Player* /*player*/, uint32 menuId, uint32 action) override + { + if (_instance->GetBossState(BOSS_VAULT_OF_LIGHTS) == DONE) + return true; - 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; - } - } - } + 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 MovementInform(uint32 movementType, uint32 pointId) 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) { - 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); + _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; + } + } - protected: - EventMap events; - uint32 _currentPoint; - InstanceScript* _instance; - }; + void UpdateAI(uint32 diff) override + { + events.Update(diff); - CreatureAI* GetAI(Creature* creature) const override + while (uint32 eventId = events.ExecuteEvent()) { - return GetHallsOfOriginationAI<npc_brann_bronzebeard_anraphetAI>(creature); + 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; + } } -}; - -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 MovementInform(uint32 movementType, uint32 pointId) override { - void FilterTargets(std::list<WorldObject*>& targets) - { - if (targets.empty()) - return; + if (movementType != POINT_MOTION_TYPE) + return; - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } + _currentPoint = pointId + 1; + Milliseconds delay = 1ms; - void Register() override + switch (pointId) { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anraphet_alpha_beams_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + 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; } - }; - SpellScript* GetSpellScript() const override - { - return new spell_anraphet_alpha_beams_SpellScript(); + events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay); } + +protected: + EventMap events; + uint32 _currentPoint; + InstanceScript* _instance; }; -// 77106 - Omega Stance (Summon) -class spell_anraphet_omega_stance_summon : public SpellScriptLoader +class spell_anraphet_alpha_beams : public SpellScript { -public: - spell_anraphet_omega_stance_summon() : SpellScriptLoader("spell_anraphet_omega_stance_summon") { } - - class spell_anraphet_omega_stance_summon_SpellScript : public SpellScript + void FilterTargets(std::list<WorldObject*>& targets) { - void SetDest(SpellDestination& dest) - { - dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f }); - } + if (targets.empty()) + return; - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_anraphet_omega_stance_summon_SpellScript::SetDest, EFFECT_0, TARGET_DEST_DEST); - } - }; + Trinity::Containers::RandomResize(targets, 1); + } - SpellScript* GetSpellScript() const override + void Register() override { - return new spell_anraphet_omega_stance_summon_SpellScript(); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anraphet_alpha_beams::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); } }; -// 77127 Omega Stance Spider Effect -class spell_anraphet_omega_stance_spider_effect : public SpellScriptLoader +// 77106 - Omega Stance (Summon) +class spell_anraphet_omega_stance_summon : public SpellScript { -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 SetDest(SpellDestination& dest) { - 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); - } - }; + dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f }); + } - SpellScript* GetSpellScript() const override + void Register() 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); } diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp index f8f61e76706..19a2e2a74df 100644 --- a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp @@ -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) { } - - void Cleanup() - { - std::list<Creature*> units; + std::list<Creature*> units; - GetCreatureListWithEntryInGrid(units, me, NPC_DUSTBONE_HORROR, 100.0f); - for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr) - (*itr)->DespawnOrUnsummon(); + 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(); - } + 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 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 + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override + { + if (me->HealthBelowPctDamaged(50, damage) && (events.GetPhaseMask() & PHASE_MASK_NORMAL) && !_hasDispersed) { - if (me->HealthBelowPctDamaged(50, damage) && (events.GetPhaseMask() & PHASE_MASK_NORMAL) && !_hasDispersed) - { - events.SetPhase(PHASE_DISPERSE); - _hasDispersed = true; + events.SetPhase(PHASE_DISPERSE); + _hasDispersed = true; - 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); + 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); - std::list<Creature*> stalkers; - GetCreatureListWithEntryInGrid(stalkers, me, NPC_BEETLE_STALKER, 100.0f); - std::list<Creature*> beetlers = stalkers; + std::list<Creature*> stalkers; + GetCreatureListWithEntryInGrid(stalkers, me, NPC_BEETLE_STALKER, 100.0f); + std::list<Creature*> beetlers = stalkers; - Trinity::Containers::RandomResize(beetlers, 9); // Holds the summoners of Jeweled Scarab + 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); - } + 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 + 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); - } + 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 + void SetData(uint32 index, uint32 /*value*/) override + { + if (index == DATA_SUMMON_DEATHS) { - if (index == DATA_SUMMON_DEATHS) + ++_summonDeaths; + if (_summonDeaths == 11) // All summons died { - ++_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); - } + 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 JustEngagedWith(Unit* who) override - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); - Talk(SAY_AGGRO); - BossAI::JustEngagedWith(who); - } + 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 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 JustReachedHome() override + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + _JustReachedHome(); + instance->SetBossState(BOSS_EARTHRAGER_PTAH, FAIL); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() || !CheckInRoom()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() || !CheckInRoom()) + return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - 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; - } + 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 - { - return GetHallsOfOriginationAI<boss_earthrager_ptahAI>(creature); + if (events.GetPhaseMask() & PHASE_MASK_NORMAL) // Do not melee in the disperse phase + DoMeleeAttackIfReady(); } + +protected: + uint8 _summonDeaths; + bool _hasDispersed; }; -class spell_earthrager_ptah_flame_bolt : public SpellScriptLoader +class spell_earthrager_ptah_flame_bolt : public SpellScript { - 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); - } - }; + void FilterTargets(std::list<WorldObject*>& targets) + { + Trinity::Containers::RandomResize(targets, GetCaster()->GetMap()->IsHeroic() ? 3 : 2); + } - SpellScript* GetSpellScript() const override - { - return new spell_earthrager_ptah_flame_bolt_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_earthrager_ptah_flame_bolt::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } }; -class spell_earthrager_ptah_explosion : public SpellScriptLoader +class spell_earthrager_ptah_explosion : public AuraScript { -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); - } - } - - 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); - } + ptah->SetUninteractible(true); + ptah->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); + ptah->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); } + } - void Register() override + void RemoveFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Unit* ptah = GetCaster()) { - 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); + ptah->SetUninteractible(false); + ptah->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); + ptah->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH); } - }; + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_earthrager_ptah_explosion_AuraScript(); + 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); } diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp index 0c8c75c7df1..550dc6cb424 100644 --- a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp @@ -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") { } + boss_temple_guardian_anhuur(Creature* creature) : BossAI(creature, BOSS_TEMPLE_GUARDIAN_ANHUUR) + { + Initialize(); + } - struct boss_temple_guardian_anhuurAI : public BossAI + void Initialize() { - boss_temple_guardian_anhuurAI(Creature* creature) : BossAI(creature, BOSS_TEMPLE_GUARDIAN_ANHUUR) - { - Initialize(); - } + _phase = PHASE_FIRST_SHIELD; + _oldPhase = PHASE_FIRST_SHIELD; + _beacons = 0; + } - void Initialize() + 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) { - _phase = PHASE_FIRST_SHIELD; - _oldPhase = PHASE_FIRST_SHIELD; - _beacons = 0; + (*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_RIGHT); + (*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_LEFT); } + } - 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) - { - (*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 Reset() override + 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)) { - Initialize(); - _Reset(); - CleanStalkers(); - me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT); - events.ScheduleEvent(EVENT_DIVINE_RECKONING, 10s, 12s); - events.ScheduleEvent(EVENT_BURNING_LIGHT, 12s); - } + _beacons = 2; + _phase++; // Increase the phase + _oldPhase = _phase; - 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; - _phase = PHASE_SHIELDED; + me->InterruptNonMeleeSpells(true); + me->AttackStop(); + DoCast(me, SPELL_TELEPORT); - me->InterruptNonMeleeSpells(true); - me->AttackStop(); - DoCast(me, SPELL_TELEPORT); + DoCast(me, SPELL_SHIELD_OF_LIGHT); - DoCast(me, SPELL_SHIELD_OF_LIGHT); + DoCastAOE(SPELL_ACTIVATE_BEACONS); - DoCastAOE(SPELL_ACTIVATE_BEACONS); + GameObject* door = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ANHUUR_DOOR)); + if (door) + { + std::list<Creature*> stalkers; + GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f); - GameObject* door = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ANHUUR_DOOR)); - if (door) + 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) { - 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 { - 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); - } + (*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_RIGHT, true); + (*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_RIGHT, true); } } + } - DoCast(me, SPELL_REVERBERATING_HYMN); + DoCast(me, SPELL_REVERBERATING_HYMN); - Talk(EMOTE_SHIELD); - Talk(SAY_SHIELD); - } + Talk(EMOTE_SHIELD); + Talk(SAY_SHIELD); } + } - void DoAction(int32 action) override + void DoAction(int32 action) override + { + if (action == ACTION_DISABLE_BEACON) { - if (action == ACTION_DISABLE_BEACON) + --_beacons; + if (!_beacons) { - --_beacons; - if (!_beacons) - { - me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT); - Talk(EMOTE_UNSHIELD); - _phase = _oldPhase; - } + me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT); + Talk(EMOTE_UNSHIELD); + _phase = _oldPhase; } } + } - void JustEngagedWith(Unit* who) override - { - instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1); - Talk(SAY_AGGRO); - BossAI::JustEngagedWith(who); - } + 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(); - } + 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 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 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; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() || !CheckInRoom() || me->GetCurrentSpell(CURRENT_CHANNELED_SPELL) || _phase == PHASE_SHIELDED) + return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) + case EVENT_DIVINE_RECKONING: + DoCastVictim(SPELL_DIVINE_RECKONING); + events.ScheduleEvent(EVENT_DIVINE_RECKONING, 10s, 12s); + break; + case EVENT_BURNING_LIGHT: { - 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); + 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; - } - 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)); + 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; + if (stalkers.empty()) + break; - stalkers.sort(Trinity::ObjectDistanceOrderPred(target)); + 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(); + // 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; - } + 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 - { - return GetHallsOfOriginationAI<boss_temple_guardian_anhuurAI>(creature); + DoMeleeAttackIfReady(); } + +private: + uint8 _phase; + uint8 _oldPhase; + uint8 _beacons; }; -class spell_anhuur_shield_of_light : public SpellScriptLoader +class spell_anhuur_shield_of_light : public SpellScript { - public: - spell_anhuur_shield_of_light() : SpellScriptLoader("spell_anhuur_shield_of_light") { } - - class spell_anhuur_shield_of_light_SpellScript : public SpellScript + void FilterTargets(std::list<WorldObject*>& targets) + { + if (InstanceScript* const script = GetCaster()->GetInstanceScript()) { - void FilterTargets(std::list<WorldObject*>& targets) + if (GameObject* go = ObjectAccessor::GetGameObject(*GetCaster(), script->GetGuidData(DATA_ANHUUR_DOOR))) { - 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); - } - } + 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_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); - } - }; - - SpellScript* GetSpellScript() const override - { - return new spell_anhuur_shield_of_light_SpellScript(); } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anhuur_shield_of_light::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY); + } }; -class spell_anhuur_disable_beacon_beams : public SpellScriptLoader +class spell_anhuur_disable_beacon_beams : public SpellScript { - 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 HandleScript(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->RemoveAurasDueToSpell(GetEffectValue()); + } - 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); - } - }; + 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); + } - SpellScript* GetSpellScript() const override - { - return new spell_anhuur_disable_beacon_beams_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_divine_reckoning : public SpellScriptLoader +class spell_anhuur_divine_reckoning : public AuraScript { -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); - } - } - - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_anhuur_divine_reckoning_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + CastSpellExtraArgs args; + args.AddSpellMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount()); + caster->CastSpell(GetTarget(), aurEff->GetSpellEffectInfo().TriggerSpell, args); } - }; + } - 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); } diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h b/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h index 770a88e31b9..64d6a95dbbf 100644 --- a/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h +++ b/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h @@ -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 |