aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp2725
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h1
2 files changed, 1239 insertions, 1487 deletions
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index dc587a42e96..95d59c34b71 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -32,7 +32,7 @@
#include "TemporarySummon.h"
#include "Vehicle.h"
-enum Texts
+enum HalionTexts
{
// Shared
SAY_REGENERATE = 0, // Without pressure in both realms, %s begins to regenerate.
@@ -57,7 +57,7 @@ enum Texts
EMOTE_WARN_LASER = 0 // The orbiting spheres pulse with dark energy!
};
-enum Spells
+enum HalionSpells
{
// Halion
SPELL_FLAME_BREATH = 74525,
@@ -119,7 +119,7 @@ enum Spells
SPELL_COPY_DAMAGE = 74810 // Aura not found in DBCs.
};
-enum Events
+enum HalionEvents
{
// Halion
EVENT_ACTIVATE_FIREWALL = 1,
@@ -148,7 +148,7 @@ enum Events
EVENT_EVADE_CHECK = 18
};
-enum Actions
+enum HalionActions
{
// Meteor Strike
ACTION_METEOR_STRIKE_BURN = 1,
@@ -163,7 +163,7 @@ enum Actions
ACTION_ACTIVATE_EMBERS = 6
};
-enum Phases
+enum HalionPhases
{
PHASE_ALL = 0,
PHASE_INTRO = 1,
@@ -172,7 +172,7 @@ enum Phases
PHASE_THREE = 4
};
-enum Misc
+enum HalionMisc
{
DATA_TWILIGHT_DAMAGE_TAKEN = 1,
DATA_MATERIAL_DAMAGE_TAKEN = 2,
@@ -223,1510 +223,1316 @@ CorporealityEntry const _corporealityReference[MAX_CORPOREALITY_STATE] =
{74831, 74836}
};
-class boss_halion : public CreatureScript
+// 39863 - Halion
+struct boss_halion : public BossAI
{
- public:
- boss_halion() : CreatureScript("boss_halion") { }
+ boss_halion(Creature* creature) : BossAI(creature, DATA_HALION) { }
- struct boss_halionAI : public BossAI
- {
- boss_halionAI(Creature* creature) : BossAI(creature, DATA_HALION) { }
+ void EnterEvadeMode(EvadeReason why) override
+ {
+ if (why == EVADE_REASON_BOUNDARY || events.IsInPhase(PHASE_ONE))
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->EnterEvadeMode(why);
+ }
- void EnterEvadeMode(EvadeReason why) override
- {
- if (why == EVADE_REASON_BOUNDARY || events.IsInPhase(PHASE_ONE))
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->EnterEvadeMode(why);
- }
+ void JustEngagedWith(Unit* who) override
+ {
+ Talk(SAY_AGGRO);
- void JustEngagedWith(Unit* who) override
- {
- Talk(SAY_AGGRO);
+ events.Reset();
+ events.SetPhase(PHASE_ONE);
- events.Reset();
- events.SetPhase(PHASE_ONE);
+ BossAI::JustEngagedWith(who);
+ me->AddAura(SPELL_TWILIGHT_PRECISION, me);
+ events.ScheduleEvent(EVENT_ACTIVATE_FIREWALL, 5s);
+ events.ScheduleEvent(EVENT_BREATH, randtime(Seconds(5), Seconds(15)));
+ events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(6), Seconds(10)));
+ events.ScheduleEvent(EVENT_TAIL_LASH, randtime(Seconds(7), Seconds(12)));
+ events.ScheduleEvent(EVENT_FIERY_COMBUSTION, randtime(Seconds(15), Seconds(18)));
+ events.ScheduleEvent(EVENT_METEOR_STRIKE, 18s);
- BossAI::JustEngagedWith(who);
- me->AddAura(SPELL_TWILIGHT_PRECISION, me);
- events.ScheduleEvent(EVENT_ACTIVATE_FIREWALL, 5s);
- events.ScheduleEvent(EVENT_BREATH, randtime(Seconds(5), Seconds(15)));
- events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(6), Seconds(10)));
- events.ScheduleEvent(EVENT_TAIL_LASH, randtime(Seconds(7), Seconds(12)));
- events.ScheduleEvent(EVENT_FIERY_COMBUSTION, randtime(Seconds(15), Seconds(18)));
- events.ScheduleEvent(EVENT_METEOR_STRIKE, 18s);
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
- instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_ONE);
+ }
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_ONE);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
+ Talk(SAY_DEATH);
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
- Talk(SAY_DEATH);
- instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ if (Creature* twilightHalion = instance->GetCreature(DATA_TWILIGHT_HALION))
+ if (twilightHalion->IsAlive())
+ twilightHalion->KillSelf();
- if (Creature* twilightHalion = instance->GetCreature(DATA_TWILIGHT_HALION))
- if (twilightHalion->IsAlive())
- twilightHalion->KillSelf();
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
+ if (controller->IsAlive())
+ controller->KillSelf();
+ }
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- if (controller->IsAlive())
- controller->KillSelf();
- }
+ Position const* GetMeteorStrikePosition() const { return &_meteorStrikePos; }
- Position const* GetMeteorStrikePosition() const { return &_meteorStrikePos; }
+ void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
+ damage = me->GetHealth() - 1;
- void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
- {
- if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
- damage = me->GetHealth() - 1;
-
- if (me->HealthBelowPctDamaged(75, damage) && events.IsInPhase(PHASE_ONE))
- {
- events.SetPhase(PHASE_TWO);
- Talk(SAY_PHASE_TWO);
+ if (me->HealthBelowPctDamaged(75, damage) && events.IsInPhase(PHASE_ONE))
+ {
+ events.SetPhase(PHASE_TWO);
+ Talk(SAY_PHASE_TWO);
- me->CastStop();
- me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
- DoCastSelf(SPELL_TWILIGHT_PHASING);
+ me->CastStop();
+ me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ DoCastSelf(SPELL_TWILIGHT_PHASING);
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_TWO);
- return;
- }
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->SetData(DATA_FIGHT_PHASE, PHASE_TWO);
+ return;
+ }
- if (events.IsInPhase(PHASE_THREE))
- {
- // Don't consider copied damage.
- if (!me->InSamePhase(attacker))
- return;
+ if (events.IsInPhase(PHASE_THREE))
+ {
+ // Don't consider copied damage.
+ if (!me->InSamePhase(attacker))
+ return;
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->SetData(DATA_MATERIAL_DAMAGE_TAKEN, damage);
- }
- }
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->SetData(DATA_MATERIAL_DAMAGE_TAKEN, damage);
+ }
+ }
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
- {
- if (spellInfo->Id == SPELL_TWILIGHT_MENDING)
- Talk(SAY_REGENERATE);
- }
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_TWILIGHT_MENDING)
+ Talk(SAY_REGENERATE);
+ }
- void UpdateAI(uint32 diff) override
- {
- if (events.IsInPhase(PHASE_TWO))
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ if (events.IsInPhase(PHASE_TWO))
+ return;
- if (!UpdateVictim())
- return;
+ if (!UpdateVictim())
+ 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)
+ {
+ case EVENT_CLEAVE:
+ DoCastVictim(SPELL_CLEAVE);
+ events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(8), Seconds(10)));
+ break;
+ case EVENT_TAIL_LASH:
+ DoCastAOE(SPELL_TAIL_LASH);
+ events.ScheduleEvent(EVENT_TAIL_LASH, randtime(Seconds(11), Seconds(16)));
+ break;
+ case EVENT_BREATH:
+ DoCastSelf(SPELL_FLAME_BREATH);
+ events.ScheduleEvent(EVENT_BREATH, randtime(Seconds(16), Seconds(25)));
+ break;
+ case EVENT_ACTIVATE_FIREWALL:
+ // Flame ring is activated 5 seconds after starting encounter, DOOR_TYPE_ROOM is only instant.
+ for (uint8 i = DATA_FLAME_RING; i <= DATA_TWILIGHT_FLAME_RING; ++i)
+ if (GameObject* flameRing = instance->GetGameObject(i))
+ instance->HandleGameObject(ObjectGuid::Empty, false, flameRing);
+ break;
+ case EVENT_METEOR_STRIKE:
{
- switch (eventId)
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
{
- case EVENT_CLEAVE:
- DoCastVictim(SPELL_CLEAVE);
- events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(8), Seconds(10)));
- break;
- case EVENT_TAIL_LASH:
- DoCastAOE(SPELL_TAIL_LASH);
- events.ScheduleEvent(EVENT_TAIL_LASH, randtime(Seconds(11), Seconds(16)));
- break;
- case EVENT_BREATH:
- DoCastSelf(SPELL_FLAME_BREATH);
- events.ScheduleEvent(EVENT_BREATH, randtime(Seconds(16), Seconds(25)));
- break;
- case EVENT_ACTIVATE_FIREWALL:
- // Flame ring is activated 5 seconds after starting encounter, DOOR_TYPE_ROOM is only instant.
- for (uint8 i = DATA_FLAME_RING; i <= DATA_TWILIGHT_FLAME_RING; ++i)
- if (GameObject* flameRing = instance->GetGameObject(i))
- instance->HandleGameObject(ObjectGuid::Empty, false, flameRing);
- break;
- case EVENT_METEOR_STRIKE:
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
- {
- _meteorStrikePos = target->GetPosition();
- me->CastSpell(_meteorStrikePos, SPELL_METEOR_STRIKE, me->GetGUID());
- Talk(SAY_METEOR_STRIKE);
- }
- events.ScheduleEvent(EVENT_METEOR_STRIKE, 38s);
- break;
- }
- case EVENT_FIERY_COMBUSTION:
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
- me->CastSpell(target, SPELL_FIERY_COMBUSTION, TRIGGERED_IGNORE_SET_FACING);
- events.ScheduleEvent(EVENT_FIERY_COMBUSTION, 25s);
- break;
- }
- default:
- break;
+ _meteorStrikePos = target->GetPosition();
+ me->CastSpell(_meteorStrikePos, SPELL_METEOR_STRIKE, me->GetGUID());
+ Talk(SAY_METEOR_STRIKE);
}
+ events.ScheduleEvent(EVENT_METEOR_STRIKE, 38s);
+ break;
}
-
- DoMeleeAttackIfReady();
+ case EVENT_FIERY_COMBUSTION:
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, -SPELL_TWILIGHT_REALM))
+ me->CastSpell(target, SPELL_FIERY_COMBUSTION, TRIGGERED_IGNORE_SET_FACING);
+ events.ScheduleEvent(EVENT_FIERY_COMBUSTION, 25s);
+ break;
+ }
+ default:
+ break;
}
+ }
- void SetData(uint32 index, uint32 value) override
- {
- if (index != DATA_FIGHT_PHASE)
- return;
+ DoMeleeAttackIfReady();
+ }
- events.SetPhase(value);
- }
+ void SetData(uint32 index, uint32 value) override
+ {
+ if (index != DATA_FIGHT_PHASE)
+ return;
- private:
- Position _meteorStrikePos;
- };
+ events.SetPhase(value);
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetRubySanctumAI<boss_halionAI>(creature);
- }
+private:
+ Position _meteorStrikePos;
};
-typedef boss_halion::boss_halionAI HalionAI;
+typedef boss_halion HalionAI;
-class boss_twilight_halion : public CreatureScript
+// 40142 - Halion
+struct boss_twilight_halion : public BossAI
{
- public:
- boss_twilight_halion() : CreatureScript("boss_twilight_halion") { }
-
- struct boss_twilight_halionAI : public BossAI
+ boss_twilight_halion(Creature* creature) : BossAI(creature, DATA_TWILIGHT_HALION)
+ {
+ Creature* halion = instance->GetCreature(DATA_HALION);
+ if (!halion)
+ return;
+
+ // Using AddAura because no spell cast packet in sniffs.
+ halion->AddAura(SPELL_COPY_DAMAGE, me); // We use explicit targeting here to avoid conditions + SPELL_ATTR6_CANT_TARGET_SELF.
+ me->AddAura(SPELL_COPY_DAMAGE, halion);
+ DoCastSelf(SPELL_DUSK_SHROUD, true);
+
+ me->SetHealth(halion->GetHealth());
+ me->SetPhaseMask(0x20, true);
+ me->SetReactState(REACT_DEFENSIVE);
+ me->SetUnitFlag(UNIT_FLAG_IN_COMBAT);
+ events.ScheduleEvent(EVENT_TAIL_LASH, 12s);
+ events.ScheduleEvent(EVENT_SOUL_CONSUMPTION, 15s);
+ }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ events.SetPhase(PHASE_TWO);
+
+ BossAI::JustEngagedWith(who);
+ me->AddAura(SPELL_TWILIGHT_PRECISION, me);
+ events.ScheduleEvent(EVENT_CLEAVE, 3s);
+ events.ScheduleEvent(EVENT_BREATH, 12s);
+
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 2);
+ }
+
+ void Reset() override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_KILL);
+
+ // Victims should not be in the Twilight Realm
+ me->CastSpell(victim, SPELL_LEAVE_TWILIGHT_REALM, true);
+ }
+
+ void JustDied(Unit* killer) override
+ {
+ if (Creature* halion = instance->GetCreature(DATA_HALION))
{
- boss_twilight_halionAI(Creature* creature) : BossAI(creature, DATA_TWILIGHT_HALION)
- {
- Creature* halion = instance->GetCreature(DATA_HALION);
- if (!halion)
- return;
-
- // Using AddAura because no spell cast packet in sniffs.
- halion->AddAura(SPELL_COPY_DAMAGE, me); // We use explicit targeting here to avoid conditions + SPELL_ATTR6_CANT_TARGET_SELF.
- me->AddAura(SPELL_COPY_DAMAGE, halion);
- DoCastSelf(SPELL_DUSK_SHROUD, true);
-
- me->SetHealth(halion->GetHealth());
- me->SetPhaseMask(0x20, true);
- me->SetReactState(REACT_DEFENSIVE);
- me->SetUnitFlag(UNIT_FLAG_IN_COMBAT);
- events.ScheduleEvent(EVENT_TAIL_LASH, 12s);
- events.ScheduleEvent(EVENT_SOUL_CONSUMPTION, 15s);
- }
-
- void JustEngagedWith(Unit* who) override
- {
- events.SetPhase(PHASE_TWO);
+ // Ensure looting
+ if (me->IsDamageEnoughForLootingAndReward())
+ halion->LowerPlayerDamageReq(halion->GetMaxHealth());
- BossAI::JustEngagedWith(who);
- me->AddAura(SPELL_TWILIGHT_PRECISION, me);
- events.ScheduleEvent(EVENT_CLEAVE, 3s);
- events.ScheduleEvent(EVENT_BREATH, 12s);
+ if (halion->IsAlive())
+ Unit::Kill(killer, halion);
+ }
- instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 2);
- }
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
+ if (controller->IsAlive())
+ controller->KillSelf();
- void Reset() override { }
- void EnterEvadeMode(EvadeReason /*why*/) override { }
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ }
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_KILL);
+ void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
+ {
+ if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
+ damage = me->GetHealth() - 1;
+ //Needed because we already have UNIT_FLAG_IN_COMBAT, otherwise JustEngagedWith won't ever be called
+ if (!events.IsInPhase(PHASE_TWO) && !events.IsInPhase(PHASE_THREE))
+ JustEngagedWith(attacker);
- // Victims should not be in the Twilight Realm
- me->CastSpell(victim, SPELL_LEAVE_TWILIGHT_REALM, true);
- }
+ if (me->HealthBelowPctDamaged(50, damage) && events.IsInPhase(PHASE_TWO))
+ {
+ events.SetPhase(PHASE_THREE);
+ me->CastStop();
+ DoCastSelf(SPELL_TWILIGHT_DIVISION);
+ Talk(SAY_PHASE_THREE);
+ return;
+ }
- void JustDied(Unit* killer) override
- {
- if (Creature* halion = instance->GetCreature(DATA_HALION))
- {
- // Ensure looting
- if (me->IsDamageEnoughForLootingAndReward())
- halion->LowerPlayerDamageReq(halion->GetMaxHealth());
+ if (events.IsInPhase(PHASE_THREE))
+ {
+ // Don't consider copied damage.
+ if (!me->InSamePhase(attacker))
+ return;
- if (halion->IsAlive())
- Unit::Kill(killer, halion);
- }
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->SetData(DATA_TWILIGHT_DAMAGE_TAKEN, damage);
+ }
+ }
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ switch (spellInfo->Id)
+ {
+ case SPELL_TWILIGHT_DIVISION:
if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- if (controller->IsAlive())
- controller->KillSelf();
-
- instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
- }
-
- void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override
- {
- if (damage >= me->GetHealth() && !events.IsInPhase(PHASE_THREE))
- damage = me->GetHealth() - 1;
- //Needed because we already have UNIT_FLAG_IN_COMBAT, otherwise JustEngagedWith won't ever be called
- if (!events.IsInPhase(PHASE_TWO) && !events.IsInPhase(PHASE_THREE))
- JustEngagedWith(attacker);
-
- if (me->HealthBelowPctDamaged(50, damage) && events.IsInPhase(PHASE_TWO))
- {
- events.SetPhase(PHASE_THREE);
- me->CastStop();
- DoCastSelf(SPELL_TWILIGHT_DIVISION);
- Talk(SAY_PHASE_THREE);
- return;
- }
-
- if (events.IsInPhase(PHASE_THREE))
- {
- // Don't consider copied damage.
- if (!me->InSamePhase(attacker))
- return;
-
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->SetData(DATA_TWILIGHT_DAMAGE_TAKEN, damage);
- }
- }
-
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
- {
- switch (spellInfo->Id)
- {
- case SPELL_TWILIGHT_DIVISION:
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->DoAction(ACTION_MONITOR_CORPOREALITY);
- break;
- case SPELL_TWILIGHT_MENDING:
- Talk(SAY_REGENERATE);
- break;
- default:
- break;
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ controller->AI()->DoAction(ACTION_MONITOR_CORPOREALITY);
+ break;
+ case SPELL_TWILIGHT_MENDING:
+ Talk(SAY_REGENERATE);
+ break;
+ default:
+ break;
+ }
+ }
- if (!UpdateVictim())
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- events.Update(diff);
+ if (!UpdateVictim())
+ return;
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_CLEAVE:
- DoCastVictim(SPELL_CLEAVE);
- events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(7), Seconds(10)));
- break;
- case EVENT_TAIL_LASH:
- DoCastAOE(SPELL_TAIL_LASH);
- events.ScheduleEvent(EVENT_TAIL_LASH, randtime(Seconds(12), Seconds(16)));
- break;
- case EVENT_BREATH:
- DoCastSelf(SPELL_DARK_BREATH);
- events.ScheduleEvent(EVENT_BREATH, randtime(Seconds(10), Seconds(14)));
- break;
- case EVENT_SOUL_CONSUMPTION:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, SPELL_TWILIGHT_REALM))
- me->CastSpell(target, SPELL_SOUL_CONSUMPTION, TRIGGERED_IGNORE_SET_FACING);
- events.ScheduleEvent(EVENT_SOUL_CONSUMPTION, 20s);
- break;
- default:
- break;
- }
- }
+ events.Update(diff);
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const override
+ while (uint32 eventId = events.ExecuteEvent())
{
- return GetRubySanctumAI<boss_twilight_halionAI>(creature);
+ switch (eventId)
+ {
+ case EVENT_CLEAVE:
+ DoCastVictim(SPELL_CLEAVE);
+ events.ScheduleEvent(EVENT_CLEAVE, randtime(Seconds(7), Seconds(10)));
+ break;
+ case EVENT_TAIL_LASH:
+ DoCastAOE(SPELL_TAIL_LASH);
+ events.ScheduleEvent(EVENT_TAIL_LASH, randtime(Seconds(12), Seconds(16)));
+ break;
+ case EVENT_BREATH:
+ DoCastSelf(SPELL_DARK_BREATH);
+ events.ScheduleEvent(EVENT_BREATH, randtime(Seconds(10), Seconds(14)));
+ break;
+ case EVENT_SOUL_CONSUMPTION:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 0.0f, true, true, SPELL_TWILIGHT_REALM))
+ me->CastSpell(target, SPELL_SOUL_CONSUMPTION, TRIGGERED_IGNORE_SET_FACING);
+ events.ScheduleEvent(EVENT_SOUL_CONSUMPTION, 20s);
+ break;
+ default:
+ break;
+ }
}
+
+ DoMeleeAttackIfReady();
+ }
};
-class npc_halion_controller : public CreatureScript
+// 40146 - Halion Controller
+struct npc_halion_controller : public ScriptedAI
{
- public:
- npc_halion_controller() : CreatureScript("npc_halion_controller") { }
-
- struct npc_halion_controllerAI : public ScriptedAI
+ npc_halion_controller(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript()), _summons(me)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ _materialCorporealityValue = 5;
+ _materialDamageTaken = 0;
+ _twilightDamageTaken = 0;
+ SetBoundary(_instance->GetBossBoundary(DATA_HALION));
+ }
+
+ void JustAppeared() override
+ {
+ if (_instance->GetGuidData(DATA_HALION) || _instance->GetBossState(DATA_GENERAL_ZARITHRIAN) != DONE)
+ return;
+
+ Reset();
+ me->GetMap()->SummonCreature(NPC_HALION, HalionRespawnPos);
+ }
+
+ void Reset() override
+ {
+ _summons.DespawnAll();
+ _events.Reset();
+ Initialize();
+
+ DoCastSelf(SPELL_CLEAR_DEBUFFS);
+ }
+
+ void JustSummoned(Creature* who) override
+ {
+ _summons.Summon(who);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ _events.Reset();
+ _summons.DespawnAll();
+
+ DoCastSelf(SPELL_CLEAR_DEBUFFS);
+ }
+
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ _twilightDamageTaken = 0;
+ _materialDamageTaken = 0;
+
+ _events.ScheduleEvent(EVENT_TRIGGER_BERSERK, 8min);
+ _events.ScheduleEvent(EVENT_EVADE_CHECK, 5s);
+ }
+
+ void JustExitedCombat() override
+ {
+ if (_instance->GetBossState(DATA_HALION) == DONE)
+ return;
+
+ if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
{
- npc_halion_controllerAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript()), _summons(me)
- {
- Initialize();
- }
-
- void Initialize()
- {
- _materialCorporealityValue = 5;
- _materialDamageTaken = 0;
- _twilightDamageTaken = 0;
- SetBoundary(_instance->GetBossBoundary(DATA_HALION));
- }
-
- void JustAppeared() override
- {
- if (_instance->GetGuidData(DATA_HALION) || _instance->GetBossState(DATA_GENERAL_ZARITHRIAN) != DONE)
- return;
-
- Reset();
- me->GetMap()->SummonCreature(NPC_HALION, HalionRespawnPos);
- }
+ twilightHalion->DespawnOrUnsummon();
+ _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, twilightHalion);
+ }
- void Reset() override
- {
- _summons.DespawnAll();
- _events.Reset();
- Initialize();
+ if (Creature* halion = _instance->GetCreature(DATA_HALION))
+ {
+ halion->DespawnOrUnsummon();
+ _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, halion);
+ }
- DoCastSelf(SPELL_CLEAR_DEBUFFS);
- }
+ _instance->SetBossState(DATA_HALION, FAIL);
+ _summons.DespawnAll();
- void JustSummoned(Creature* who) override
- {
- _summons.Summon(who);
- }
+ me->DespawnOrUnsummon(0s, 30s);
+ }
- void JustDied(Unit* /*killer*/) override
- {
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_INTRO_HALION:
_events.Reset();
- _summons.DespawnAll();
-
- DoCastSelf(SPELL_CLEAR_DEBUFFS);
- }
-
- void JustEngagedWith(Unit* /*who*/) override
- {
- _twilightDamageTaken = 0;
- _materialDamageTaken = 0;
-
- _events.ScheduleEvent(EVENT_TRIGGER_BERSERK, 8min);
- _events.ScheduleEvent(EVENT_EVADE_CHECK, 5s);
- }
-
- void JustExitedCombat() override
- {
- if (_instance->GetBossState(DATA_HALION) == DONE)
+ _events.SetPhase(PHASE_INTRO);
+ _events.ScheduleEvent(EVENT_START_INTRO, 2s);
+ break;
+ case ACTION_INTRO_HALION_2:
+ if (_instance->GetGuidData(DATA_HALION))
return;
- if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
- {
- twilightHalion->DespawnOrUnsummon();
- _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, twilightHalion);
- }
-
- if (Creature* halion = _instance->GetCreature(DATA_HALION))
- {
- halion->DespawnOrUnsummon();
- _instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, halion);
- }
-
- _instance->SetBossState(DATA_HALION, FAIL);
- _summons.DespawnAll();
-
- me->DespawnOrUnsummon(0s, 30s);
- }
-
- void DoAction(int32 action) override
+ for (uint8 i = DATA_BURNING_TREE_1; i <= DATA_BURNING_TREE_4; ++i)
+ if (GameObject* tree = _instance->GetGameObject(i))
+ _instance->HandleGameObject(ObjectGuid::Empty, true, tree);
+ me->GetMap()->SummonCreature(NPC_HALION, HalionRespawnPos);
+ break;
+ case ACTION_MONITOR_CORPOREALITY:
{
- switch (action)
+ for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
{
- case ACTION_INTRO_HALION:
- _events.Reset();
- _events.SetPhase(PHASE_INTRO);
- _events.ScheduleEvent(EVENT_START_INTRO, 2s);
- break;
- case ACTION_INTRO_HALION_2:
- if (_instance->GetGuidData(DATA_HALION))
- return;
-
- for (uint8 i = DATA_BURNING_TREE_1; i <= DATA_BURNING_TREE_4; ++i)
- if (GameObject* tree = _instance->GetGameObject(i))
- _instance->HandleGameObject(ObjectGuid::Empty, true, tree);
- me->GetMap()->SummonCreature(NPC_HALION, HalionRespawnPos);
- break;
- case ACTION_MONITOR_CORPOREALITY:
- {
- for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
- {
- Creature* halion = _instance->GetCreature(itr);
- if (!halion)
- continue;
-
- halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), false);
- halion->AI()->SetData(DATA_FIGHT_PHASE, PHASE_THREE);
+ Creature* halion = _instance->GetCreature(itr);
+ if (!halion)
+ continue;
- if (itr == DATA_TWILIGHT_HALION)
- continue;
+ halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), false);
+ halion->AI()->SetData(DATA_FIGHT_PHASE, PHASE_THREE);
- halion->RemoveAurasDueToSpell(SPELL_TWILIGHT_PHASING);
- halion->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
- }
+ if (itr == DATA_TWILIGHT_HALION)
+ continue;
- // Summon Twilight portals
- DoCastSelf(SPELL_SUMMON_EXIT_PORTALS);
-
- _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TOGGLE, 1);
- // Hardcoding doesn't really matter here.
- _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_MATERIAL, 50);
- _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TWILIGHT, 50);
-
- _events.ScheduleEvent(EVENT_CHECK_CORPOREALITY, 7s);
- break;
- }
- case ACTION_ACTIVATE_EMBERS:
- _events.ScheduleEvent(EVENT_ACTIVATE_EMBERS, 6s);
- break;
- default:
- break;
+ halion->RemoveAurasDueToSpell(SPELL_TWILIGHT_PHASING);
+ halion->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
}
- }
- void UpdateAI(uint32 diff) override
- {
- // The IsEngaged() check is needed because that check should be false when Halion is
- // not engaged, while it would return true without as UpdateVictim() checks for
- // combat state.
- if (me->IsEngaged() && !UpdateVictim())
- return;
+ // Summon Twilight portals
+ DoCastSelf(SPELL_SUMMON_EXIT_PORTALS);
- _events.Update(diff);
+ _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TOGGLE, 1);
+ // Hardcoding doesn't really matter here.
+ _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_MATERIAL, 50);
+ _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TWILIGHT, 50);
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_START_INTRO:
- DoCastSelf(SPELL_COSMETIC_FIRE_PILLAR, true);
- _events.ScheduleEvent(EVENT_INTRO_PROGRESS_1, Seconds(4));
- break;
- case EVENT_INTRO_PROGRESS_1:
- for (uint8 i = DATA_BURNING_TREE_3; i <= DATA_BURNING_TREE_4; ++i)
- if (GameObject* tree = _instance->GetGameObject(i))
- _instance->HandleGameObject(ObjectGuid::Empty, true, tree);
- _events.ScheduleEvent(EVENT_INTRO_PROGRESS_2, Seconds(4));
- break;
- case EVENT_INTRO_PROGRESS_2:
- for (uint8 i = DATA_BURNING_TREE_1; i <= DATA_BURNING_TREE_2; ++i)
- if (GameObject* tree = _instance->GetGameObject(i))
- _instance->HandleGameObject(ObjectGuid::Empty, true, tree);
- _events.ScheduleEvent(EVENT_INTRO_PROGRESS_3, Seconds(4));
- break;
- case EVENT_INTRO_PROGRESS_3:
- DoCastSelf(SPELL_FIERY_EXPLOSION);
- if (_instance->GetGuidData(DATA_HALION))
- return;
- if (Creature* halion = me->GetMap()->SummonCreature(NPC_HALION, HalionSpawnPos))
- halion->AI()->Talk(SAY_INTRO);
- break;
- case EVENT_TWILIGHT_MENDING:
- if (_instance->GetCreature(DATA_HALION)) // Just check if physical Halion is spawned
- if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
- twilightHalion->CastSpell(nullptr, SPELL_TWILIGHT_MENDING, true);
- break;
- case EVENT_TRIGGER_BERSERK:
- if (Creature* halion = _instance->GetCreature(DATA_HALION))
- halion->CastSpell(halion, SPELL_BERSERK, true);
- if (Creature* halion = _instance->GetCreature(DATA_TWILIGHT_HALION))
- halion->CastSpell(halion, SPELL_BERSERK, true);
- break;
- case EVENT_SHADOW_PULSARS_SHOOT:
- if (Creature* orbCarrier = _instance->GetCreature(DATA_ORB_CARRIER))
- orbCarrier->AI()->DoAction(ACTION_WARNING_SHOOT);
- _events.ScheduleEvent(EVENT_SHADOW_PULSARS_SHOOT, 30s);
- break;
- case EVENT_CHECK_CORPOREALITY:
- UpdateCorporeality();
- _events.ScheduleEvent(EVENT_CHECK_CORPOREALITY, 5s);
- break;
- case EVENT_ACTIVATE_EMBERS:
- _summons.DoZoneInCombat(NPC_LIVING_EMBER);
- break;
- case EVENT_EVADE_CHECK:
- DoCheckEvade();
- _events.Repeat(Seconds(5));
- break;
- default:
- break;
- }
- }
+ _events.ScheduleEvent(EVENT_CHECK_CORPOREALITY, 7s);
+ break;
}
+ case ACTION_ACTIVATE_EMBERS:
+ _events.ScheduleEvent(EVENT_ACTIVATE_EMBERS, 6s);
+ break;
+ default:
+ break;
+ }
+ }
- void DoCheckEvade()
- {
- Map::PlayerList const& players = me->GetMap()->GetPlayers();
- for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
- if (Player* player = i->GetSource())
- if (player->IsAlive() && IsInBoundary(player) && !player->IsGameMaster())
- return;
-
- EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
- }
-
- void SetData(uint32 id, uint32 value) override
- {
- switch (id)
- {
- case DATA_MATERIAL_DAMAGE_TAKEN:
- _materialDamageTaken += value;
- break;
- case DATA_TWILIGHT_DAMAGE_TAKEN:
- _twilightDamageTaken += value;
- break;
- case DATA_FIGHT_PHASE:
- _events.SetPhase(value);
- switch (value)
- {
- case PHASE_ONE:
- DoZoneInCombat();
- break;
- case PHASE_TWO:
- _events.ScheduleEvent(EVENT_SHADOW_PULSARS_SHOOT, 35s);
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
-
- private:
- //// @todo Find out a better scaling, if any.
- // [0 , 0.98[: Corporeality goes down
- // [0.98, 0.99]: Do nothing
- // ]0.99, 1.01[: Twilight Mending
- // [1.01, 1.02]: Do nothing
- // ]1.02, +oo [: Corporeality goes up
- void UpdateCorporeality()
- {
- uint8 oldValue = _materialCorporealityValue;
- if (_twilightDamageTaken == 0 || _materialDamageTaken == 0)
- {
- _events.ScheduleEvent(EVENT_TWILIGHT_MENDING, Milliseconds(100));
- _twilightDamageTaken = 0;
- _materialDamageTaken = 0;
- return;
- }
-
- float damageRatio = float(_materialDamageTaken) / float(_twilightDamageTaken);
+ void UpdateAI(uint32 diff) override
+ {
+ // The IsEngaged() check is needed because that check should be false when Halion is
+ // not engaged, while it would return true without as UpdateVictim() checks for
+ // combat state.
+ if (me->IsEngaged() && !UpdateVictim())
+ return;
- CorporealityEvent action = CORPOREALITY_NONE;
- if (damageRatio < 0.98f) // [0 , 0.98[: Corporeality goes down
- action = CORPOREALITY_DECREASE;
- else if (0.99f < damageRatio && damageRatio < 1.01f) // ]0.99, 1.01[: Twilight Mending
- action = CORPOREALITY_TWILIGHT_MENDING;
- else if (1.02f < damageRatio) // ]1.02, +oo [: Corporeality goes up
- action = CORPOREALITY_INCREASE;
+ _events.Update(diff);
- switch (action)
- {
- case CORPOREALITY_NONE:
- {
- _materialDamageTaken = 0;
- _twilightDamageTaken = 0;
- return;
- }
- case CORPOREALITY_INCREASE:
- {
- if (_materialCorporealityValue >= (MAX_CORPOREALITY_STATE - 1))
- return;
- ++_materialCorporealityValue;
- break;
- }
- case CORPOREALITY_DECREASE:
- {
- if (_materialCorporealityValue <= 0)
- return;
- --_materialCorporealityValue;
- break;
- }
- case CORPOREALITY_TWILIGHT_MENDING:
- {
- _events.ScheduleEvent(EVENT_TWILIGHT_MENDING, Milliseconds(100));
- _materialDamageTaken = 0;
- _twilightDamageTaken = 0;
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_START_INTRO:
+ DoCastSelf(SPELL_COSMETIC_FIRE_PILLAR, true);
+ _events.ScheduleEvent(EVENT_INTRO_PROGRESS_1, Seconds(4));
+ break;
+ case EVENT_INTRO_PROGRESS_1:
+ for (uint8 i = DATA_BURNING_TREE_3; i <= DATA_BURNING_TREE_4; ++i)
+ if (GameObject* tree = _instance->GetGameObject(i))
+ _instance->HandleGameObject(ObjectGuid::Empty, true, tree);
+ _events.ScheduleEvent(EVENT_INTRO_PROGRESS_2, Seconds(4));
+ break;
+ case EVENT_INTRO_PROGRESS_2:
+ for (uint8 i = DATA_BURNING_TREE_1; i <= DATA_BURNING_TREE_2; ++i)
+ if (GameObject* tree = _instance->GetGameObject(i))
+ _instance->HandleGameObject(ObjectGuid::Empty, true, tree);
+ _events.ScheduleEvent(EVENT_INTRO_PROGRESS_3, Seconds(4));
+ break;
+ case EVENT_INTRO_PROGRESS_3:
+ DoCastSelf(SPELL_FIERY_EXPLOSION);
+ if (_instance->GetGuidData(DATA_HALION))
return;
- }
- }
-
- _materialDamageTaken = 0;
- _twilightDamageTaken = 0;
-
- _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_MATERIAL, _materialCorporealityValue * 10);
- _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TWILIGHT, 100 - _materialCorporealityValue * 10);
-
- for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
- {
- if (Creature* halion = _instance->GetCreature(itr))
- {
- halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), true);
-
- if (itr == DATA_TWILIGHT_HALION)
- halion->AI()->Talk(oldValue < _materialCorporealityValue ? EMOTE_CORPOREALITY_TOT : EMOTE_CORPOREALITY_TIT, halion);
- else // if (itr == DATA_HALION)
- halion->AI()->Talk(oldValue > _materialCorporealityValue ? EMOTE_CORPOREALITY_POT : EMOTE_CORPOREALITY_PIP, halion);
- }
- }
- }
-
- uint32 GetSpell(uint8 pctValue, bool isTwilight = false) const
- {
- CorporealityEntry entry = _corporealityReference[pctValue];
- return isTwilight ? entry.twilightRealmSpell : entry.materialRealmSpell;
+ if (Creature* halion = me->GetMap()->SummonCreature(NPC_HALION, HalionSpawnPos))
+ halion->AI()->Talk(SAY_INTRO);
+ break;
+ case EVENT_TWILIGHT_MENDING:
+ if (_instance->GetCreature(DATA_HALION)) // Just check if physical Halion is spawned
+ if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
+ twilightHalion->CastSpell(nullptr, SPELL_TWILIGHT_MENDING, true);
+ break;
+ case EVENT_TRIGGER_BERSERK:
+ if (Creature* halion = _instance->GetCreature(DATA_HALION))
+ halion->CastSpell(halion, SPELL_BERSERK, true);
+ if (Creature* halion = _instance->GetCreature(DATA_TWILIGHT_HALION))
+ halion->CastSpell(halion, SPELL_BERSERK, true);
+ break;
+ case EVENT_SHADOW_PULSARS_SHOOT:
+ if (Creature* orbCarrier = _instance->GetCreature(DATA_ORB_CARRIER))
+ orbCarrier->AI()->DoAction(ACTION_WARNING_SHOOT);
+ _events.ScheduleEvent(EVENT_SHADOW_PULSARS_SHOOT, 30s);
+ break;
+ case EVENT_CHECK_CORPOREALITY:
+ UpdateCorporeality();
+ _events.ScheduleEvent(EVENT_CHECK_CORPOREALITY, 5s);
+ break;
+ case EVENT_ACTIVATE_EMBERS:
+ _summons.DoZoneInCombat(NPC_LIVING_EMBER);
+ break;
+ case EVENT_EVADE_CHECK:
+ DoCheckEvade();
+ _events.Repeat(Seconds(5));
+ break;
+ default:
+ break;
}
-
- EventMap _events;
- InstanceScript* _instance;
- SummonList _summons;
-
- uint32 _twilightDamageTaken;
- uint32 _materialDamageTaken;
- uint8 _materialCorporealityValue;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetRubySanctumAI<npc_halion_controllerAI>(creature);
}
-};
+ }
+
+ void DoCheckEvade()
+ {
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ if (Player* player = i->GetSource())
+ if (player->IsAlive() && IsInBoundary(player) && !player->IsGameMaster())
+ return;
-class npc_orb_carrier : public CreatureScript
-{
- public:
- npc_orb_carrier() : CreatureScript("npc_orb_carrier") { }
+ EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
+ }
- struct npc_orb_carrierAI : public ScriptedAI
+ void SetData(uint32 id, uint32 value) override
+ {
+ switch (id)
{
- npc_orb_carrierAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- ASSERT(creature->GetVehicleKit());
- }
-
- void UpdateAI(uint32 diff) override
- {
- /// According to sniffs this spell is cast every 1 or 2 seconds.
- /// However, refreshing it looks bad, so just cast the spell if
- /// we are not channeling it.
- if (!me->HasUnitState(UNIT_STATE_CASTING))
- me->CastSpell(nullptr, SPELL_TRACK_ROTATION, false);
-
- scheduler.Update(diff);
- }
-
- void DoAction(int32 action) override
- {
- switch (action)
+ case DATA_MATERIAL_DAMAGE_TAKEN:
+ _materialDamageTaken += value;
+ break;
+ case DATA_TWILIGHT_DAMAGE_TAKEN:
+ _twilightDamageTaken += value;
+ break;
+ case DATA_FIGHT_PHASE:
+ _events.SetPhase(value);
+ switch (value)
{
- case ACTION_WARNING_SHOOT:
- {
- Vehicle* vehicle = me->GetVehicleKit();
- Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
- if (northOrb && northOrb->GetTypeId() == TYPEID_UNIT)
- northOrb->ToCreature()->AI()->Talk(EMOTE_WARN_LASER);
-
- scheduler.Schedule(Seconds(5), [this](TaskContext /*context*/)
- {
- DoAction(ACTION_SHOOT);
- });
+ case PHASE_ONE:
+ DoZoneInCombat();
break;
- }
- case ACTION_SHOOT:
- {
- Vehicle* vehicle = me->GetVehicleKit();
- Unit* southOrb = vehicle->GetPassenger(SEAT_SOUTH);
- Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
- if (southOrb && northOrb)
- TriggerCutter(northOrb, southOrb);
-
- if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
- twilightHalion->AI()->Talk(SAY_SPHERE_PULSE);
-
- if (!IsHeroic())
- return;
-
- Unit* eastOrb = vehicle->GetPassenger(SEAT_EAST);
- Unit* westOrb = vehicle->GetPassenger(SEAT_WEST);
- if (eastOrb && westOrb)
- TriggerCutter(eastOrb, westOrb);
+ case PHASE_TWO:
+ _events.ScheduleEvent(EVENT_SHADOW_PULSARS_SHOOT, 35s);
break;
- }
default:
break;
}
- }
- private:
- InstanceScript* _instance;
- TaskScheduler scheduler;
-
- void TriggerCutter(Unit* caster, Unit* target)
- {
- caster->CastSpell(caster, SPELL_TWILIGHT_PULSE_PERIODIC, true);
- target->CastSpell(target, SPELL_TWILIGHT_PULSE_PERIODIC, true);
- caster->CastSpell(target, SPELL_TWILIGHT_CUTTER, false);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const override
+ break;
+ default:
+ break;
+ }
+ }
+
+private:
+ //// @todo Find out a better scaling, if any.
+ // [0 , 0.98[: Corporeality goes down
+ // [0.98, 0.99]: Do nothing
+ // ]0.99, 1.01[: Twilight Mending
+ // [1.01, 1.02]: Do nothing
+ // ]1.02, +oo [: Corporeality goes up
+ void UpdateCorporeality()
+ {
+ uint8 oldValue = _materialCorporealityValue;
+ if (_twilightDamageTaken == 0 || _materialDamageTaken == 0)
{
- return GetRubySanctumAI<npc_orb_carrierAI>(creature);
+ _events.ScheduleEvent(EVENT_TWILIGHT_MENDING, Milliseconds(100));
+ _twilightDamageTaken = 0;
+ _materialDamageTaken = 0;
+ return;
}
-};
-class npc_meteor_strike_initial : public CreatureScript
-{
- public:
- npc_meteor_strike_initial() : CreatureScript("npc_meteor_strike_initial") { }
+ float damageRatio = float(_materialDamageTaken) / float(_twilightDamageTaken);
+
+ CorporealityEvent action = CORPOREALITY_NONE;
+ if (damageRatio < 0.98f) // [0 , 0.98[: Corporeality goes down
+ action = CORPOREALITY_DECREASE;
+ else if (0.99f < damageRatio && damageRatio < 1.01f) // ]0.99, 1.01[: Twilight Mending
+ action = CORPOREALITY_TWILIGHT_MENDING;
+ else if (1.02f < damageRatio) // ]1.02, +oo [: Corporeality goes up
+ action = CORPOREALITY_INCREASE;
- struct npc_meteor_strike_initialAI : public ScriptedAI
+ switch (action)
{
- npc_meteor_strike_initialAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
+ case CORPOREALITY_NONE:
{
- SetCombatMovement(false);
+ _materialDamageTaken = 0;
+ _twilightDamageTaken = 0;
+ return;
}
-
- void DoAction(int32 action) override
+ case CORPOREALITY_INCREASE:
{
- switch (action)
- {
- case ACTION_METEOR_STRIKE_AOE:
- DoCastSelf(SPELL_METEOR_STRIKE_AOE_DAMAGE, true);
- DoCastSelf(SPELL_METEOR_STRIKE_FIRE_AURA_1, true);
- for (std::list<Creature*>::iterator itr = _meteorList.begin(); itr != _meteorList.end(); ++itr)
- (*itr)->AI()->DoAction(ACTION_METEOR_STRIKE_BURN);
- break;
- }
+ if (_materialCorporealityValue >= (MAX_CORPOREALITY_STATE - 1))
+ return;
+ ++_materialCorporealityValue;
+ break;
}
-
- void IsSummonedBy(WorldObject* summoner) override
+ case CORPOREALITY_DECREASE:
{
- Creature* owner = summoner->ToCreature();
- if (!owner)
+ if (_materialCorporealityValue <= 0)
return;
-
- // Let Controller count as summoner
- if (Creature* controller = _instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->JustSummoned(me);
-
- DoCastSelf(SPELL_METEOR_STRIKE_COUNTDOWN);
- DoCastSelf(SPELL_BIRTH_NO_VISUAL);
-
- if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
- {
- Position const* ownerPos = halionAI->GetMeteorStrikePosition();
- float randomAdjustment = frand(static_cast<float>(M_PI / 5.0f), static_cast<float>(M_PI / 2.0f));
- float angle[4];
- angle[0] = me->GetAbsoluteAngle(ownerPos);
- angle[1] = angle[0] + randomAdjustment;
- angle[2] = angle[0] + static_cast<float>(M_PI);
- angle[3] = angle[2] + randomAdjustment;
-
- _meteorList.clear();
- for (uint8 i = 0; i < 4; i++)
- {
- angle[i] = Position::NormalizeOrientation(angle[i]);
- me->SetOrientation(angle[i]);
- Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance
- if (Creature* meteor = me->SummonCreature(NPC_METEOR_STRIKE_NORTH + i, newPos, TEMPSUMMON_TIMED_DESPAWN, 30s))
- _meteorList.push_back(meteor);
- }
- }
+ --_materialCorporealityValue;
+ break;
}
-
- void UpdateAI(uint32 /*diff*/) override { }
- void EnterEvadeMode(EvadeReason /*why*/) override { }
- private:
- InstanceScript* _instance;
- std::list<Creature*> _meteorList;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetRubySanctumAI<npc_meteor_strike_initialAI>(creature);
- }
-};
-
-class npc_meteor_strike : public CreatureScript
-{
- public:
- npc_meteor_strike() : CreatureScript("npc_meteor_strike") { }
-
- struct npc_meteor_strikeAI : public ScriptedAI
- {
- npc_meteor_strikeAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript()), _spawnCount(0)
+ case CORPOREALITY_TWILIGHT_MENDING:
{
- SetCombatMovement(false);
+ _events.ScheduleEvent(EVENT_TWILIGHT_MENDING, Milliseconds(100));
+ _materialDamageTaken = 0;
+ _twilightDamageTaken = 0;
+ return;
}
+ }
- void DoAction(int32 action) override
- {
- if (action == ACTION_METEOR_STRIKE_BURN)
- {
- DoCastSelf(SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
- me->setActive(true);
- me->SetFarVisible(true);
- _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, Milliseconds(500));
- }
- }
+ _materialDamageTaken = 0;
+ _twilightDamageTaken = 0;
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- // Let Halion Controller count as summoner.
- if (Creature* controller = _instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->JustSummoned(me);
- }
+ _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_MATERIAL, _materialCorporealityValue * 10);
+ _instance->DoUpdateWorldState(WORLDSTATE_CORPOREALITY_TWILIGHT, 100 - _materialCorporealityValue * 10);
- void SetData(uint32 dataType, uint32 dataCount) override
+ for (uint8 itr = DATA_HALION; itr <= DATA_TWILIGHT_HALION; itr++)
+ {
+ if (Creature* halion = _instance->GetCreature(itr))
{
- if (dataType == DATA_SPAWNED_FLAMES)
- _spawnCount += dataCount;
- }
+ halion->CastSpell(halion, GetSpell(_materialCorporealityValue, itr == DATA_TWILIGHT_HALION), true);
- uint32 GetData(uint32 dataType) const override
- {
- if (dataType == DATA_SPAWNED_FLAMES)
- return _spawnCount;
- return 0;
+ if (itr == DATA_TWILIGHT_HALION)
+ halion->AI()->Talk(oldValue < _materialCorporealityValue ? EMOTE_CORPOREALITY_TOT : EMOTE_CORPOREALITY_TIT, halion);
+ else // if (itr == DATA_HALION)
+ halion->AI()->Talk(oldValue > _materialCorporealityValue ? EMOTE_CORPOREALITY_POT : EMOTE_CORPOREALITY_PIP, halion);
}
+ }
+ }
- void UpdateAI(uint32 diff) override
- {
- _events.Update(diff);
-
- if (_events.ExecuteEvent() == EVENT_SPAWN_METEOR_FLAME)
- {
- Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
- if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25s))
- flame->AI()->SetGUID(me->GetGUID());
- }
- }
+ uint32 GetSpell(uint8 pctValue, bool isTwilight = false) const
+ {
+ CorporealityEntry entry = _corporealityReference[pctValue];
+ return isTwilight ? entry.twilightRealmSpell : entry.materialRealmSpell;
+ }
- private:
- InstanceScript* _instance;
- EventMap _events;
- uint8 _spawnCount;
- };
+ EventMap _events;
+ InstanceScript* _instance;
+ SummonList _summons;
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetRubySanctumAI<npc_meteor_strikeAI>(creature);
- }
+ uint32 _twilightDamageTaken;
+ uint32 _materialDamageTaken;
+ uint8 _materialCorporealityValue;
};
-class npc_meteor_strike_flame : public CreatureScript
+// 40081 - Orb Carrier
+struct npc_orb_carrier : public ScriptedAI
{
- public:
- npc_meteor_strike_flame() : CreatureScript("npc_meteor_strike_flame") { }
-
- struct npc_meteor_strike_flameAI : public ScriptedAI
+ npc_orb_carrier(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ ASSERT(creature->GetVehicleKit());
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ /// According to sniffs this spell is cast every 1 or 2 seconds.
+ /// However, refreshing it looks bad, so just cast the spell if
+ /// we are not channeling it.
+ if (!me->HasUnitState(UNIT_STATE_CASTING))
+ me->CastSpell(nullptr, SPELL_TRACK_ROTATION, false);
+
+ scheduler.Update(diff);
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
{
- npc_meteor_strike_flameAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
+ case ACTION_WARNING_SHOOT:
{
- SetCombatMovement(false);
- }
+ Vehicle* vehicle = me->GetVehicleKit();
+ Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
+ if (northOrb && northOrb->GetTypeId() == TYPEID_UNIT)
+ northOrb->ToCreature()->AI()->Talk(EMOTE_WARN_LASER);
- void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
- {
- _rootOwnerGuid = guid;
- _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, Milliseconds(800));
- }
-
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- // Let Halion Controller count as summoner.
- if (Creature* controller = _instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->JustSummoned(me);
+ scheduler.Schedule(Seconds(5), [this](TaskContext /*context*/)
+ {
+ DoAction(ACTION_SHOOT);
+ });
+ break;
}
-
- void UpdateAI(uint32 diff) override
+ case ACTION_SHOOT:
{
- _events.Update(diff);
- if (_events.ExecuteEvent() != EVENT_SPAWN_METEOR_FLAME)
- return;
-
- me->CastSpell(me, SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
+ Vehicle* vehicle = me->GetVehicleKit();
+ Unit* southOrb = vehicle->GetPassenger(SEAT_SOUTH);
+ Unit* northOrb = vehicle->GetPassenger(SEAT_NORTH);
+ if (southOrb && northOrb)
+ TriggerCutter(northOrb, southOrb);
- Creature* meteorStrike = ObjectAccessor::GetCreature(*me, _rootOwnerGuid);
- if (!meteorStrike)
- return;
+ if (Creature* twilightHalion = _instance->GetCreature(DATA_TWILIGHT_HALION))
+ twilightHalion->AI()->Talk(SAY_SPHERE_PULSE);
- meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1);
- if (meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5)
+ if (!IsHeroic())
return;
- Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
- if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25s))
- flame->AI()->SetGUID(_rootOwnerGuid);
+ Unit* eastOrb = vehicle->GetPassenger(SEAT_EAST);
+ Unit* westOrb = vehicle->GetPassenger(SEAT_WEST);
+ if (eastOrb && westOrb)
+ TriggerCutter(eastOrb, westOrb);
+ break;
}
-
- void EnterEvadeMode(EvadeReason /*why*/) override { }
-
- private:
- InstanceScript* _instance;
- EventMap _events;
- ObjectGuid _rootOwnerGuid;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetRubySanctumAI<npc_meteor_strike_flameAI>(creature);
+ default:
+ break;
}
+ }
+private:
+ InstanceScript* _instance;
+ TaskScheduler scheduler;
+
+ void TriggerCutter(Unit* caster, Unit* target)
+ {
+ caster->CastSpell(caster, SPELL_TWILIGHT_PULSE_PERIODIC, true);
+ target->CastSpell(target, SPELL_TWILIGHT_PULSE_PERIODIC, true);
+ caster->CastSpell(target, SPELL_TWILIGHT_CUTTER, false);
+ }
};
-class npc_combustion_consumption : public CreatureScript
+// 40029 - Meteor Strike
+struct npc_meteor_strike_initial : public ScriptedAI
{
- public:
- npc_combustion_consumption() : CreatureScript("npc_combustion_consumption") { }
-
- struct npc_combustion_consumptionAI : public ScriptedAI
+ npc_meteor_strike_initial(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ SetCombatMovement(false);
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
{
- npc_combustion_consumptionAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- SetCombatMovement(false);
-
- switch (creature->GetEntry())
- {
- case NPC_COMBUSTION:
- _explosionSpell = SPELL_FIERY_COMBUSTION_EXPLOSION;
- _damageSpell = SPELL_COMBUSTION_DAMAGE_AURA;
- creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x01, true);
- break;
- case NPC_CONSUMPTION:
- _explosionSpell = SPELL_SOUL_CONSUMPTION_EXPLOSION;
- _damageSpell = SPELL_CONSUMPTION_DAMAGE_AURA;
- creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x20, true);
- break;
- default: // Should never happen
- _explosionSpell = 0;
- _damageSpell = 0;
- break;
- }
- }
-
- void IsSummonedBy(WorldObject* summoner) override
- {
- // Let Halion Controller count as summoner
- if (Creature* controller = _instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->JustSummoned(me);
-
- _summonerGuid = summoner->GetGUID();
- }
-
- void SetData(uint32 type, uint32 stackAmount) override
- {
- Unit* summoner = ObjectAccessor::GetUnit(*me, _summonerGuid);
-
- if (type != DATA_STACKS_DISPELLED || !_damageSpell || !_explosionSpell || !summoner)
- return;
+ case ACTION_METEOR_STRIKE_AOE:
+ DoCastSelf(SPELL_METEOR_STRIKE_AOE_DAMAGE, true);
+ DoCastSelf(SPELL_METEOR_STRIKE_FIRE_AURA_1, true);
+ for (std::list<Creature*>::iterator itr = _meteorList.begin(); itr != _meteorList.end(); ++itr)
+ (*itr)->AI()->DoAction(ACTION_METEOR_STRIKE_BURN);
+ break;
+ }
+ }
- CastSpellExtraArgs args;
- args.AddSpellMod(SPELLVALUE_AURA_STACK, stackAmount + 1);
- me->CastSpell(me, SPELL_SCALE_AURA, args);
- DoCastSelf(_damageSpell);
+ void IsSummonedBy(WorldObject* summoner) override
+ {
+ Creature* owner = summoner->ToCreature();
+ if (!owner)
+ return;
- int32 damage = 1200 + (stackAmount * 1290); // Needs more research.
- CastSpellExtraArgs args2;
- args2.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
- summoner->CastSpell(summoner, _explosionSpell, args2);
- }
+ // Let Controller count as summoner
+ if (Creature* controller = _instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->JustSummoned(me);
- void UpdateAI(uint32 /*diff*/) override { }
+ DoCastSelf(SPELL_METEOR_STRIKE_COUNTDOWN);
+ DoCastSelf(SPELL_BIRTH_NO_VISUAL);
- private:
- InstanceScript* _instance;
- uint32 _explosionSpell;
- uint32 _damageSpell;
- ObjectGuid _summonerGuid;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
+ if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI()))
{
- return GetRubySanctumAI<npc_combustion_consumptionAI>(creature);
+ Position const* ownerPos = halionAI->GetMeteorStrikePosition();
+ float randomAdjustment = frand(static_cast<float>(M_PI / 5.0f), static_cast<float>(M_PI / 2.0f));
+ float angle[4];
+ angle[0] = me->GetAbsoluteAngle(ownerPos);
+ angle[1] = angle[0] + randomAdjustment;
+ angle[2] = angle[0] + static_cast<float>(M_PI);
+ angle[3] = angle[2] + randomAdjustment;
+
+ _meteorList.clear();
+ for (uint8 i = 0; i < 4; i++)
+ {
+ angle[i] = Position::NormalizeOrientation(angle[i]);
+ me->SetOrientation(angle[i]);
+ Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance
+ if (Creature* meteor = me->SummonCreature(NPC_METEOR_STRIKE_NORTH + i, newPos, TEMPSUMMON_TIMED_DESPAWN, 30s))
+ _meteorList.push_back(meteor);
+ }
}
+ }
+
+ void UpdateAI(uint32 /*diff*/) override { }
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
+private:
+ InstanceScript* _instance;
+ std::list<Creature*> _meteorList;
};
-class npc_living_inferno : public CreatureScript
+// 40041, 40042, 40043, 40044 - Meteor Strike
+struct npc_meteor_strike : public ScriptedAI
{
- public:
- npc_living_inferno() : CreatureScript("npc_living_inferno") { }
-
- struct npc_living_infernoAI : public ScriptedAI
+ npc_meteor_strike(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript()), _spawnCount(0)
+ {
+ SetCombatMovement(false);
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_METEOR_STRIKE_BURN)
{
- npc_living_infernoAI(Creature* creature) : ScriptedAI(creature) { }
-
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- DoZoneInCombat();
- me->CastSpell(me, SPELL_BLAZING_AURA, true);
-
- // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs.
- if (me->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC)
- scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/)
- {
- me->CastSpell(me, SPELL_SPAWN_LIVING_EMBERS, true);
- });
-
- if (InstanceScript* instance = me->GetInstanceScript())
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- {
- controller->AI()->DoAction(ACTION_ACTIVATE_EMBERS);
- controller->AI()->JustSummoned(me);
- }
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- me->DespawnOrUnsummon(1ms);
- }
-
- void UpdateAI(uint32 diff) override
- {
- scheduler.Update(diff);
- ScriptedAI::UpdateAI(diff);
- }
-
- private:
- TaskScheduler scheduler;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
+ DoCastSelf(SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
+ me->setActive(true);
+ me->SetFarVisible(true);
+ _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, Milliseconds(500));
+ }
+ }
+
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ // Let Halion Controller count as summoner.
+ if (Creature* controller = _instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->JustSummoned(me);
+ }
+
+ void SetData(uint32 dataType, uint32 dataCount) override
+ {
+ if (dataType == DATA_SPAWNED_FLAMES)
+ _spawnCount += dataCount;
+ }
+
+ uint32 GetData(uint32 dataType) const override
+ {
+ if (dataType == DATA_SPAWNED_FLAMES)
+ return _spawnCount;
+ return 0;
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ if (_events.ExecuteEvent() == EVENT_SPAWN_METEOR_FLAME)
{
- return GetRubySanctumAI<npc_living_infernoAI>(creature);
+ Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
+ if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25s))
+ flame->AI()->SetGUID(me->GetGUID());
}
+ }
+
+private:
+ InstanceScript* _instance;
+ EventMap _events;
+ uint8 _spawnCount;
};
-class npc_living_ember : public CreatureScript
+// 40055 - Meteor Strike
+struct npc_meteor_strike_flame : public ScriptedAI
{
- public:
- npc_living_ember() : CreatureScript("npc_living_ember") { }
-
- struct npc_living_emberAI : public ScriptedAI
- {
- npc_living_emberAI(Creature* creature) : ScriptedAI(creature) { }
-
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- if (InstanceScript* instance = me->GetInstanceScript())
- if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
- controller->AI()->JustSummoned(me);
- }
+ npc_meteor_strike_flame(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ SetCombatMovement(false);
+ }
+
+ void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
+ {
+ _rootOwnerGuid = guid;
+ _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, Milliseconds(800));
+ }
+
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ // Let Halion Controller count as summoner.
+ if (Creature* controller = _instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->JustSummoned(me);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+ if (_events.ExecuteEvent() != EVENT_SPAWN_METEOR_FLAME)
+ return;
+
+ me->CastSpell(me, SPELL_METEOR_STRIKE_FIRE_AURA_2, true);
+
+ Creature* meteorStrike = ObjectAccessor::GetCreature(*me, _rootOwnerGuid);
+ if (!meteorStrike)
+ return;
+
+ meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1);
+ if (meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5)
+ return;
+
+ Position pos = me->GetNearPosition(5.0f, frand(-static_cast<float>(M_PI / 6.0f), static_cast<float>(M_PI / 6.0f)));
+ if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25s))
+ flame->AI()->SetGUID(_rootOwnerGuid);
+ }
+
+ void EnterEvadeMode(EvadeReason /*why*/) override { }
+
+private:
+ InstanceScript* _instance;
+ EventMap _events;
+ ObjectGuid _rootOwnerGuid;
+};
- void JustDied(Unit* /*killer*/) override
- {
- me->DespawnOrUnsummon(1ms);
- }
- };
+// 40001 - Combustion
+// 40135 - Consumption
+struct npc_combustion_consumption : public ScriptedAI
+{
+ npc_combustion_consumption(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ SetCombatMovement(false);
- CreatureAI* GetAI(Creature* creature) const override
+ switch (creature->GetEntry())
{
- return GetRubySanctumAI<npc_living_emberAI>(creature);
+ case NPC_COMBUSTION:
+ _explosionSpell = SPELL_FIERY_COMBUSTION_EXPLOSION;
+ _damageSpell = SPELL_COMBUSTION_DAMAGE_AURA;
+ creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x01, true);
+ break;
+ case NPC_CONSUMPTION:
+ _explosionSpell = SPELL_SOUL_CONSUMPTION_EXPLOSION;
+ _damageSpell = SPELL_CONSUMPTION_DAMAGE_AURA;
+ creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x20, true);
+ break;
+ default: // Should never happen
+ _explosionSpell = 0;
+ _damageSpell = 0;
+ break;
}
+ }
+
+ void IsSummonedBy(WorldObject* summoner) override
+ {
+ // Let Halion Controller count as summoner
+ if (Creature* controller = _instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->JustSummoned(me);
+
+ _summonerGuid = summoner->GetGUID();
+ }
+
+ void SetData(uint32 type, uint32 stackAmount) override
+ {
+ Unit* summoner = ObjectAccessor::GetUnit(*me, _summonerGuid);
+
+ if (type != DATA_STACKS_DISPELLED || !_damageSpell || !_explosionSpell || !summoner)
+ return;
+
+ CastSpellExtraArgs args;
+ args.AddSpellMod(SPELLVALUE_AURA_STACK, stackAmount + 1);
+ me->CastSpell(me, SPELL_SCALE_AURA, args);
+ DoCastSelf(_damageSpell);
+
+ int32 damage = 1200 + (stackAmount * 1290); // Needs more research.
+ CastSpellExtraArgs args2;
+ args2.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
+ summoner->CastSpell(summoner, _explosionSpell, args2);
+ }
+
+ void UpdateAI(uint32 /*diff*/) override { }
+
+private:
+ InstanceScript* _instance;
+ uint32 _explosionSpell;
+ uint32 _damageSpell;
+ ObjectGuid _summonerGuid;
};
-class go_twilight_portal : public GameObjectScript
+// 40681 - Living Inferno
+struct npc_living_inferno : public ScriptedAI
{
- public:
- go_twilight_portal() : GameObjectScript("go_twilight_portal") { }
+ npc_living_inferno(Creature* creature) : ScriptedAI(creature) { }
- struct go_twilight_portalAI : public GameObjectAI
- {
- go_twilight_portalAI(GameObject* gameobject) : GameObjectAI(gameobject),
- _instance(gameobject->GetInstanceScript()), _deleted(false)
- {
- switch (gameobject->GetEntry())
- {
- case GO_HALION_PORTAL_EXIT:
- gameobject->SetPhaseMask(0x20, true);
- _spellId = gameobject->GetGOInfo()->goober.spellId;
- break;
- case GO_HALION_PORTAL_1:
- case GO_HALION_PORTAL_2:
- gameobject->SetPhaseMask(0x1, true);
- /// Because WDB template has non-existent spell ID, not seen in sniffs either, meh
- _spellId = SPELL_TWILIGHT_REALM;
- break;
- default:
- _spellId = 0;
- break;
- }
- }
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ DoZoneInCombat();
+ me->CastSpell(me, SPELL_BLAZING_AURA, true);
- bool OnGossipHello(Player* player) override
+ // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs.
+ if (me->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC)
+ scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/)
{
- if (_spellId != 0)
- player->CastSpell(player, _spellId, true);
- return true;
- }
+ me->CastSpell(me, SPELL_SPAWN_LIVING_EMBERS, true);
+ });
- void UpdateAI(uint32 /*diff*/) override
+ if (InstanceScript* instance = me->GetInstanceScript())
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
{
- if (_instance->GetBossState(DATA_HALION) == IN_PROGRESS)
- return;
-
- if (!_deleted)
- {
- _deleted = true;
- me->Delete();
- }
+ controller->AI()->DoAction(ACTION_ACTIVATE_EMBERS);
+ controller->AI()->JustSummoned(me);
}
+ }
- private:
- InstanceScript* _instance;
- uint32 _spellId;
- bool _deleted;
- };
+ void JustDied(Unit* /*killer*/) override
+ {
+ me->DespawnOrUnsummon(1ms);
+ }
- GameObjectAI* GetAI(GameObject* gameobject) const override
- {
- return GetRubySanctumAI<go_twilight_portalAI>(gameobject);
- }
+ void UpdateAI(uint32 diff) override
+ {
+ scheduler.Update(diff);
+ ScriptedAI::UpdateAI(diff);
+ }
+
+private:
+ TaskScheduler scheduler;
};
-// 74641 - Meteor Strike
-class spell_halion_meteor_strike_marker : public SpellScriptLoader
+// 40683 - Living Ember
+struct npc_living_ember : public ScriptedAI
{
- public:
- spell_halion_meteor_strike_marker() : SpellScriptLoader("spell_halion_meteor_strike_marker") { }
+ npc_living_ember(Creature* creature) : ScriptedAI(creature) { }
+
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ if (InstanceScript* instance = me->GetInstanceScript())
+ if (Creature* controller = instance->GetCreature(DATA_HALION_CONTROLLER))
+ controller->AI()->JustSummoned(me);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ me->DespawnOrUnsummon(1ms);
+ }
+};
- class spell_halion_meteor_strike_marker_AuraScript : public AuraScript
+// 202794, 202796 - Twilight Portal
+struct go_twilight_portal : public GameObjectAI
+{
+ go_twilight_portal(GameObject* gameobject) : GameObjectAI(gameobject),
+ _instance(gameobject->GetInstanceScript()), _deleted(false)
+ {
+ switch (gameobject->GetEntry())
{
- PrepareAuraScript(spell_halion_meteor_strike_marker_AuraScript);
+ case GO_HALION_PORTAL_EXIT:
+ gameobject->SetPhaseMask(0x20, true);
+ _spellId = gameobject->GetGOInfo()->goober.spellId;
+ break;
+ case GO_HALION_PORTAL_1:
+ case GO_HALION_PORTAL_2:
+ gameobject->SetPhaseMask(0x1, true);
+ /// Because WDB template has non-existent spell ID, not seen in sniffs either, meh
+ _spellId = SPELL_TWILIGHT_REALM;
+ break;
+ default:
+ _spellId = 0;
+ break;
+ }
+ }
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- if (!GetCaster())
- return;
+ bool OnGossipHello(Player* player) override
+ {
+ if (_spellId != 0)
+ player->CastSpell(player, _spellId, true);
+ return true;
+ }
- if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
- if (Creature* creCaster = GetCaster()->ToCreature())
- creCaster->AI()->DoAction(ACTION_METEOR_STRIKE_AOE);
- }
+ void UpdateAI(uint32 /*diff*/) override
+ {
+ if (_instance->GetBossState(DATA_HALION) == IN_PROGRESS)
+ return;
- void Register() override
- {
- AfterEffectRemove += AuraEffectRemoveFn(spell_halion_meteor_strike_marker_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- }
- };
-
- AuraScript* GetAuraScript() const override
+ if (!_deleted)
{
- return new spell_halion_meteor_strike_marker_AuraScript();
+ _deleted = true;
+ me->Delete();
}
+ }
+
+private:
+ InstanceScript* _instance;
+ uint32 _spellId;
+ bool _deleted;
};
-class spell_halion_combustion_consumption : public SpellScriptLoader
+// 74641 - Meteor Strike
+class spell_halion_meteor_strike_marker : public AuraScript
{
- public:
- spell_halion_combustion_consumption(char const* scriptName, uint32 spell) : SpellScriptLoader(scriptName), _spellID(spell) { }
-
- class spell_halion_combustion_consumption_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_halion_combustion_consumption_AuraScript);
-
- public:
- spell_halion_combustion_consumption_AuraScript(uint32 spellID) : AuraScript(), _markSpell(spellID) { }
-
- private:
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ _markSpell });
- }
-
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
- return;
-
- if (GetTarget()->HasAura(_markSpell))
- GetTarget()->RemoveAurasDueToSpell(_markSpell, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
- }
-
- void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- GetTarget()->CastSpell(GetTarget(), _markSpell, true);
- }
-
- void AddMarkStack(AuraEffect const* /*aurEff*/)
- {
- GetTarget()->CastSpell(GetTarget(), _markSpell, true);
- }
-
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_halion_combustion_consumption_AuraScript::AddMarkStack, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
- AfterEffectApply += AuraEffectApplyFn(spell_halion_combustion_consumption_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_halion_combustion_consumption_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
- }
-
- uint32 _markSpell;
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_halion_combustion_consumption_AuraScript(_spellID);
- }
+ PrepareAuraScript(spell_halion_meteor_strike_marker);
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (!GetCaster())
+ return;
+
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
+ if (Creature* creCaster = GetCaster()->ToCreature())
+ creCaster->AI()->DoAction(ACTION_METEOR_STRIKE_AOE);
+ }
+
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_halion_meteor_strike_marker::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+};
- private:
- uint32 _spellID;
+// 74792 - Soul Consumption
+// 74562 - Fiery Combustion
+class spell_halion_combustion_consumption : public AuraScript
+{
+ PrepareAuraScript(spell_halion_combustion_consumption);
+
+public:
+ spell_halion_combustion_consumption(uint32 spellID) : AuraScript(), _markSpell(spellID) { }
+
+private:
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ _markSpell });
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
+ return;
+
+ if (GetTarget()->HasAura(_markSpell))
+ GetTarget()->RemoveAurasDueToSpell(_markSpell, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), _markSpell, true);
+ }
+
+ void AddMarkStack(AuraEffect const* /*aurEff*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), _markSpell, true);
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_halion_combustion_consumption::AddMarkStack, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
+ AfterEffectApply += AuraEffectApplyFn(spell_halion_combustion_consumption::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_halion_combustion_consumption::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
+ }
+
+ uint32 _markSpell;
};
// 74629 - Combustion Periodic
// 74803 - Consumption Periodic
-class spell_halion_combustion_consumption_periodic : public SpellScriptLoader
+class spell_halion_combustion_consumption_periodic : public AuraScript
{
- public:
- spell_halion_combustion_consumption_periodic() : SpellScriptLoader("spell_halion_combustion_consumption_periodic") { }
-
- class spell_halion_combustion_consumption_periodic_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_halion_combustion_consumption_periodic_AuraScript);
-
- bool Validate(SpellInfo const* spellInfo) override
- {
- return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
- }
-
- void HandleTick(AuraEffect const* aurEff)
- {
- PreventDefaultAction();
- Unit* caster = GetCaster();
- if (!caster)
- return;
-
- uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
- int32 radius = caster->GetObjectScale() * M_PI * 10000 / 3;
-
- CastSpellExtraArgs args(aurEff);
- args.OriginalCaster = caster->GetGUID();
- args.AddSpellMod(SPELLVALUE_RADIUS_MOD, radius);
- caster->CastSpell(nullptr, triggerSpell, args);
- }
-
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_halion_combustion_consumption_periodic_AuraScript::HandleTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_halion_combustion_consumption_periodic_AuraScript();
- }
+ PrepareAuraScript(spell_halion_combustion_consumption_periodic);
+
+ bool Validate(SpellInfo const* spellInfo) override
+ {
+ return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0).TriggerSpell });
+ }
+
+ void HandleTick(AuraEffect const* aurEff)
+ {
+ PreventDefaultAction();
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ uint32 triggerSpell = aurEff->GetSpellEffectInfo().TriggerSpell;
+ int32 radius = caster->GetObjectScale() * M_PI * 10000 / 3;
+
+ CastSpellExtraArgs args(aurEff);
+ args.OriginalCaster = caster->GetGUID();
+ args.AddSpellMod(SPELLVALUE_RADIUS_MOD, radius);
+ caster->CastSpell(nullptr, triggerSpell, args);
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_halion_combustion_consumption_periodic::HandleTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
};
-class spell_halion_marks : public SpellScriptLoader
+// 74567 - Mark of Combustion
+// 74795 - Mark of Consumption
+class spell_halion_marks : public AuraScript
{
- public:
- spell_halion_marks(char const* scriptName, uint32 summonSpell, uint32 removeSpell) : SpellScriptLoader(scriptName),
- _summonSpell(summonSpell), _removeSpell(removeSpell) { }
-
- class spell_halion_marks_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_halion_marks_AuraScript);
-
- public:
- spell_halion_marks_AuraScript(uint32 summonSpell, uint32 removeSpell) : AuraScript(),
- _summonSpellId(summonSpell), _removeSpellId(removeSpell) { }
-
- private:
- bool Validate(SpellInfo const* /*spell*/) override
- {
- return ValidateSpellInfo({ _summonSpellId, _removeSpellId });
- }
-
- /// We were purged. Force removed stacks to zero and trigger the appropriated remove handler.
- void BeforeDispel(DispelInfo* dispelData)
- {
- // Prevent any stack from being removed at this point.
- dispelData->SetRemovedCharges(0);
-
- if (Unit* dispelledUnit = GetUnitOwner())
- if (dispelledUnit->HasAura(_removeSpellId))
- dispelledUnit->RemoveAurasDueToSpell(_removeSpellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
- }
-
- void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
- {
- if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
- return;
-
- // Stacks marker
- CastSpellExtraArgs args(GetCasterGUID());
- args.AddSpellMod(SPELLVALUE_BASE_POINT1, aurEff->GetBase()->GetStackAmount());
- GetTarget()->CastSpell(GetTarget(), _summonSpellId, args);
- }
-
- void Register() override
- {
- OnDispel += AuraDispelFn(spell_halion_marks_AuraScript::BeforeDispel);
- AfterEffectRemove += AuraEffectRemoveFn(spell_halion_marks_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- }
-
- uint32 _summonSpellId;
- uint32 _removeSpellId;
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_halion_marks_AuraScript(_summonSpell, _removeSpell);
- }
-
- private:
- uint32 _summonSpell;
- uint32 _removeSpell;
+ PrepareAuraScript(spell_halion_marks);
+
+public:
+ spell_halion_marks(uint32 summonSpell, uint32 removeSpell) : AuraScript(),
+ _summonSpellId(summonSpell), _removeSpellId(removeSpell) { }
+
+private:
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ _summonSpellId, _removeSpellId });
+ }
+
+ /// We were purged. Force removed stacks to zero and trigger the appropriated remove handler.
+ void BeforeDispel(DispelInfo* dispelData)
+ {
+ // Prevent any stack from being removed at this point.
+ dispelData->SetRemovedCharges(0);
+
+ if (Unit* dispelledUnit = GetUnitOwner())
+ if (dispelledUnit->HasAura(_removeSpellId))
+ dispelledUnit->RemoveAurasDueToSpell(_removeSpellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
+ }
+
+ void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
+ return;
+
+ // Stacks marker
+ CastSpellExtraArgs args(GetCasterGUID());
+ args.AddSpellMod(SPELLVALUE_BASE_POINT1, aurEff->GetBase()->GetStackAmount());
+ GetTarget()->CastSpell(GetTarget(), _summonSpellId, args);
+ }
+
+ void Register() override
+ {
+ OnDispel += AuraDispelFn(spell_halion_marks::BeforeDispel);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_halion_marks::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+
+ uint32 _summonSpellId;
+ uint32 _removeSpellId;
};
// 74610 - Fiery Combustion
// 74800 - Soul Consumption
-class spell_halion_damage_aoe_summon : public SpellScriptLoader
+class spell_halion_damage_aoe_summon : public SpellScript
{
- public:
- spell_halion_damage_aoe_summon() : SpellScriptLoader("spell_halion_damage_aoe_summon") { }
-
- class spell_halion_damage_aoe_summon_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_halion_damage_aoe_summon_SpellScript);
-
- void HandleSummon(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- Unit* caster = GetCaster();
- uint32 entry = uint32(GetEffectInfo().MiscValue);
- SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB));
- uint32 duration = uint32(GetSpellInfo()->GetDuration());
-
- Position pos = caster->GetPosition();
- if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id))
- if (summon->IsAIEnabled())
- summon->AI()->SetData(DATA_STACKS_DISPELLED, GetSpellValue()->EffectBasePoints[EFFECT_1]);
- }
-
- void Register() override
- {
- OnEffectHit += SpellEffectFn(spell_halion_damage_aoe_summon_SpellScript::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_halion_damage_aoe_summon_SpellScript();
- }
+ PrepareSpellScript(spell_halion_damage_aoe_summon);
+
+ void HandleSummon(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ Unit* caster = GetCaster();
+ uint32 entry = uint32(GetEffectInfo().MiscValue);
+ SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetEffectInfo().MiscValueB));
+ uint32 duration = uint32(GetSpellInfo()->GetDuration());
+
+ Position pos = caster->GetPosition();
+ if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id))
+ if (summon->IsAIEnabled())
+ summon->AI()->SetData(DATA_STACKS_DISPELLED, GetSpellValue()->EffectBasePoints[EFFECT_1]);
+ }
+
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_halion_damage_aoe_summon::HandleSummon, EFFECT_0, SPELL_EFFECT_SUMMON);
+ }
};
-class spell_halion_twilight_realm_handlers : public SpellScriptLoader
+// 74812 - Leave Twilight Realm
+// 74807 - Twilight Realm
+class spell_halion_twilight_realm_handlers : public AuraScript
{
- public:
- spell_halion_twilight_realm_handlers(char const* scriptName, uint32 beforeHitSpell, bool isApplyHandler) : SpellScriptLoader(scriptName),
- _beforeHitSpell(beforeHitSpell), _isApplyHandler(isApplyHandler)
- { }
-
- class spell_halion_twilight_realm_handlers_AuraScript : public AuraScript
+ PrepareAuraScript(spell_halion_twilight_realm_handlers);
+
+public:
+ spell_halion_twilight_realm_handlers(uint32 beforeHitSpell, bool isApplyHandler) : AuraScript(),
+ _isApply(isApplyHandler), _beforeHitSpellId(beforeHitSpell)
+ { }
+
+private:
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ _beforeHitSpellId });
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(SPELL_TWILIGHT_REALM);
+ if (InstanceScript* instance = GetTarget()->GetInstanceScript())
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED);
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
+ {
+ Unit* target = GetTarget();
+ if (!target)
+ return;
+
+ target->RemoveAurasDueToSpell(_beforeHitSpellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL);
+ if (InstanceScript* instance = target->GetInstanceScript())
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED);
+ }
+
+ void Register() override
+ {
+ if (!_isApply)
{
- PrepareAuraScript(spell_halion_twilight_realm_handlers_AuraScript);
-
- public:
- spell_halion_twilight_realm_handlers_AuraScript(uint32 beforeHitSpell, bool isApplyHandler) : AuraScript(),
- _isApply(isApplyHandler), _beforeHitSpellId(beforeHitSpell)
- { }
-
- private:
- bool Validate(SpellInfo const* /*spell*/) override
- {
- return ValidateSpellInfo({ _beforeHitSpellId });
- }
-
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
- {
- GetTarget()->RemoveAurasDueToSpell(SPELL_TWILIGHT_REALM);
- if (InstanceScript* instance = GetTarget()->GetInstanceScript())
- instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED);
- }
-
- void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*handle*/)
- {
- Unit* target = GetTarget();
- if (!target)
- return;
-
- target->RemoveAurasDueToSpell(_beforeHitSpellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL);
- if (InstanceScript* instance = target->GetInstanceScript())
- instance->SendEncounterUnit(ENCOUNTER_FRAME_PHASE_SHIFT_CHANGED);
- }
-
- void Register() override
- {
- if (!_isApply)
- {
- AfterEffectApply += AuraEffectApplyFn(spell_halion_twilight_realm_handlers_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_halion_twilight_realm_handlers_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- }
- else
- AfterEffectApply += AuraEffectApplyFn(spell_halion_twilight_realm_handlers_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PHASE, AURA_EFFECT_HANDLE_REAL);
- }
-
- bool _isApply;
- uint32 _beforeHitSpellId;
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_halion_twilight_realm_handlers_AuraScript(_beforeHitSpell, _isApplyHandler);
+ AfterEffectApply += AuraEffectApplyFn(spell_halion_twilight_realm_handlers::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_halion_twilight_realm_handlers::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
+ else
+ AfterEffectApply += AuraEffectApplyFn(spell_halion_twilight_realm_handlers::OnApply, EFFECT_0, SPELL_AURA_PHASE, AURA_EFFECT_HANDLE_REAL);
+ }
- private:
- uint32 _beforeHitSpell;
- bool _isApplyHandler;
+ bool _isApply;
+ uint32 _beforeHitSpellId;
};
// 75396 - Clear Debuffs
-class spell_halion_clear_debuffs : public SpellScriptLoader
+class spell_halion_clear_debuffs : public SpellScript
{
- public:
- spell_halion_clear_debuffs() : SpellScriptLoader("spell_halion_clear_debuffs") { }
-
- class spell_halion_clear_debuffs_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_halion_clear_debuffs_SpellScript);
-
- bool Validate(SpellInfo const* /*spell*/) override
- {
- return ValidateSpellInfo({ SPELL_CLEAR_DEBUFFS, SPELL_TWILIGHT_REALM });
- }
-
- void HandleScript(SpellEffIndex /*effIndex*/)
- {
- if (GetHitUnit()->HasAura(GetEffectInfo().CalcValue()))
- GetHitUnit()->RemoveAurasDueToSpell(GetEffectInfo().CalcValue());
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_halion_clear_debuffs_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_halion_clear_debuffs_SpellScript();
- }
+ PrepareSpellScript(spell_halion_clear_debuffs);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_CLEAR_DEBUFFS, SPELL_TWILIGHT_REALM });
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (GetHitUnit()->HasAura(GetEffectInfo().CalcValue()))
+ GetHitUnit()->RemoveAurasDueToSpell(GetEffectInfo().CalcValue());
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_halion_clear_debuffs::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
class TwilightCutterSelector
@@ -1745,203 +1551,148 @@ class TwilightCutterSelector
};
// 74769, 77844, 77845, 77846 - Twilight Cutter
-class spell_halion_twilight_cutter : public SpellScriptLoader
+class spell_halion_twilight_cutter : public SpellScript
{
- public:
- spell_halion_twilight_cutter() : SpellScriptLoader("spell_halion_twilight_cutter") { }
+ PrepareSpellScript(spell_halion_twilight_cutter);
- class spell_halion_twilight_cutter_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_halion_twilight_cutter_SpellScript);
-
- void RemoveNotBetween(std::list<WorldObject*>& unitList)
- {
- if (unitList.empty())
- return;
-
- Unit* caster = GetCaster();
- if (Unit* channelTarget = ObjectAccessor::GetUnit(*caster, caster->GetChannelObjectGuid()))
- {
- unitList.remove_if(TwilightCutterSelector(caster, channelTarget));
- return;
- }
-
- // In case cutter caster werent found for some reason
- unitList.clear();
- }
+ void RemoveNotBetween(std::list<WorldObject*>& unitList)
+ {
+ if (unitList.empty())
+ return;
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_halion_twilight_cutter_SpellScript::RemoveNotBetween, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- }
- };
-
- SpellScript* GetSpellScript() const override
+ Unit* caster = GetCaster();
+ if (Unit* channelTarget = ObjectAccessor::GetUnit(*caster, caster->GetChannelObjectGuid()))
{
- return new spell_halion_twilight_cutter_SpellScript();
+ unitList.remove_if(TwilightCutterSelector(caster, channelTarget));
+ return;
}
+
+ // In case cutter caster werent found for some reason
+ unitList.clear();
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_halion_twilight_cutter::RemoveNotBetween, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
};
// 74808 - Twilight Phasing
-class spell_halion_twilight_phasing : public SpellScriptLoader
+class spell_halion_twilight_phasing : public SpellScript
{
- public:
- spell_halion_twilight_phasing() : SpellScriptLoader("spell_halion_twilight_phasing") { }
-
- class spell_halion_twilight_phasing_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_halion_twilight_phasing_SpellScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ SPELL_SUMMON_TWILIGHT_PORTAL });
- }
-
- void Phase()
- {
- Unit* caster = GetCaster();
- caster->CastSpell(caster->GetPosition(), SPELL_SUMMON_TWILIGHT_PORTAL, true);
- caster->GetMap()->SummonCreature(NPC_TWILIGHT_HALION, HalionSpawnPos);
- }
-
- void Register() override
- {
- OnHit += SpellHitFn(spell_halion_twilight_phasing_SpellScript::Phase);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_halion_twilight_phasing_SpellScript();
- }
+ PrepareSpellScript(spell_halion_twilight_phasing);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_SUMMON_TWILIGHT_PORTAL });
+ }
+
+ void Phase()
+ {
+ Unit* caster = GetCaster();
+ caster->CastSpell(caster->GetPosition(), SPELL_SUMMON_TWILIGHT_PORTAL, true);
+ caster->GetMap()->SummonCreature(NPC_TWILIGHT_HALION, HalionSpawnPos);
+ }
+
+ void Register() override
+ {
+ OnHit += SpellHitFn(spell_halion_twilight_phasing::Phase);
+ }
};
// 74805 - Summon Exit Portals
-class spell_halion_summon_exit_portals : public SpellScriptLoader
+class spell_halion_summon_exit_portals : public SpellScript
{
- public:
- spell_halion_summon_exit_portals() : SpellScriptLoader("spell_halion_summon_exit_portals") { }
-
- class spell_halion_summon_exit_portals_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_halion_summon_exit_portals_SpellScript);
-
- void SetDest0(SpellDestination& dest)
- {
- Position const offset = { 0.0f, 20.0f, 0.0f, 0.0f };
- dest.RelocateOffset(offset);
- }
-
- void SetDest1(SpellDestination& dest)
- {
- Position const offset = { 0.0f, -20.0f, 0.0f, 0.0f };
- dest.RelocateOffset(offset);
- }
-
- void Register() override
- {
- OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_halion_summon_exit_portals_SpellScript::SetDest0, EFFECT_0, TARGET_DEST_CASTER);
- OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_halion_summon_exit_portals_SpellScript::SetDest1, EFFECT_1, TARGET_DEST_CASTER);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_halion_summon_exit_portals_SpellScript();
- }
+ PrepareSpellScript(spell_halion_summon_exit_portals);
+
+ void SetDest0(SpellDestination& dest)
+ {
+ Position const offset = { 0.0f, 20.0f, 0.0f, 0.0f };
+ dest.RelocateOffset(offset);
+ }
+
+ void SetDest1(SpellDestination& dest)
+ {
+ Position const offset = { 0.0f, -20.0f, 0.0f, 0.0f };
+ dest.RelocateOffset(offset);
+ }
+
+ void Register() override
+ {
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_halion_summon_exit_portals::SetDest0, EFFECT_0, TARGET_DEST_CASTER);
+ OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_halion_summon_exit_portals::SetDest1, EFFECT_1, TARGET_DEST_CASTER);
+ }
};
// 75880 - Spawn Living Embers
-class spell_halion_spawn_living_embers : public SpellScriptLoader
+class spell_halion_spawn_living_embers : public SpellScript
{
- public:
- spell_halion_spawn_living_embers() : SpellScriptLoader("spell_halion_spawn_living_embers") { }
-
- class spell_halion_spawn_living_embers_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_halion_spawn_living_embers_SpellScript);
-
- void SelectMeteorFlames(std::list<WorldObject*>& unitList)
- {
- if (!unitList.empty())
- Trinity::Containers::RandomResize(unitList, 10);
- }
-
- void HandleScript(SpellEffIndex /* effIndex */)
- {
- GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_LIVING_EMBER, true);
- }
-
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_halion_spawn_living_embers_SpellScript::SelectMeteorFlames, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
- OnEffectHitTarget += SpellEffectFn(spell_halion_spawn_living_embers_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_halion_spawn_living_embers_SpellScript();
- }
+ PrepareSpellScript(spell_halion_spawn_living_embers);
+
+ void SelectMeteorFlames(std::list<WorldObject*>& unitList)
+ {
+ if (!unitList.empty())
+ Trinity::Containers::RandomResize(unitList, 10);
+ }
+
+ void HandleScript(SpellEffIndex /* effIndex */)
+ {
+ GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_LIVING_EMBER, true);
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_halion_spawn_living_embers::SelectMeteorFlames, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnEffectHitTarget += SpellEffectFn(spell_halion_spawn_living_embers::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
// 75886, 75887 - Blazing Aura
-class spell_halion_blazing_aura : public SpellScriptLoader
+class spell_halion_blazing_aura : public SpellScript
{
- public:
- spell_halion_blazing_aura() : SpellScriptLoader("spell_halion_blazing_aura") { }
-
- class spell_halion_blazing_aura_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_halion_blazing_aura_SpellScript);
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- GetHitUnit()->CastSpell(GetHitUnit(), GetEffectInfo().TriggerSpell);
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_halion_blazing_aura_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_halion_blazing_aura_SpellScript();
- }
+ PrepareSpellScript(spell_halion_blazing_aura);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->CastSpell(GetHitUnit(), GetEffectInfo().TriggerSpell);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_halion_blazing_aura::HandleScript, EFFECT_1, SPELL_EFFECT_FORCE_CAST);
+ }
};
void AddSC_boss_halion()
{
- new boss_halion();
- new boss_twilight_halion();
-
- new npc_halion_controller();
- new npc_meteor_strike_flame();
- new npc_meteor_strike_initial();
- new npc_meteor_strike();
- new npc_combustion_consumption();
- new npc_orb_carrier();
- new npc_living_inferno();
- new npc_living_ember();
-
- new go_twilight_portal();
-
- new spell_halion_meteor_strike_marker();
- new spell_halion_combustion_consumption("spell_halion_soul_consumption", SPELL_MARK_OF_CONSUMPTION);
- new spell_halion_combustion_consumption("spell_halion_fiery_combustion", SPELL_MARK_OF_COMBUSTION);
- new spell_halion_marks("spell_halion_mark_of_combustion", SPELL_FIERY_COMBUSTION_SUMMON, SPELL_FIERY_COMBUSTION);
- new spell_halion_marks("spell_halion_mark_of_consumption", SPELL_SOUL_CONSUMPTION_SUMMON, SPELL_SOUL_CONSUMPTION);
- new spell_halion_combustion_consumption_periodic();
- new spell_halion_damage_aoe_summon();
- new spell_halion_twilight_realm_handlers("spell_halion_leave_twilight_realm", SPELL_SOUL_CONSUMPTION, false);
- new spell_halion_twilight_realm_handlers("spell_halion_enter_twilight_realm", SPELL_FIERY_COMBUSTION, true);
- new spell_halion_summon_exit_portals();
- new spell_halion_twilight_phasing();
- new spell_halion_twilight_cutter();
- new spell_halion_clear_debuffs();
- new spell_halion_spawn_living_embers();
- new spell_halion_blazing_aura();
+ RegisterRubySanctumCreatureAI(boss_halion);
+ RegisterRubySanctumCreatureAI(boss_twilight_halion);
+
+ RegisterRubySanctumCreatureAI(npc_halion_controller);
+ RegisterRubySanctumCreatureAI(npc_meteor_strike_flame);
+ RegisterRubySanctumCreatureAI(npc_meteor_strike_initial);
+ RegisterRubySanctumCreatureAI(npc_meteor_strike);
+ RegisterRubySanctumCreatureAI(npc_combustion_consumption);
+ RegisterRubySanctumCreatureAI(npc_orb_carrier);
+ RegisterRubySanctumCreatureAI(npc_living_inferno);
+ RegisterRubySanctumCreatureAI(npc_living_ember);
+
+ RegisterRubySanctumGameObjectAI(go_twilight_portal);
+
+ RegisterSpellScript(spell_halion_meteor_strike_marker);
+ RegisterSpellScriptWithArgs(spell_halion_combustion_consumption, "spell_halion_soul_consumption", SPELL_MARK_OF_CONSUMPTION);
+ RegisterSpellScriptWithArgs(spell_halion_combustion_consumption, "spell_halion_fiery_combustion", SPELL_MARK_OF_COMBUSTION);
+ RegisterSpellScriptWithArgs(spell_halion_marks, "spell_halion_mark_of_combustion", SPELL_FIERY_COMBUSTION_SUMMON, SPELL_FIERY_COMBUSTION);
+ RegisterSpellScriptWithArgs(spell_halion_marks, "spell_halion_mark_of_consumption", SPELL_SOUL_CONSUMPTION_SUMMON, SPELL_SOUL_CONSUMPTION);
+ RegisterSpellScript(spell_halion_combustion_consumption_periodic);
+ RegisterSpellScript(spell_halion_damage_aoe_summon);
+ RegisterSpellScriptWithArgs(spell_halion_twilight_realm_handlers, "spell_halion_leave_twilight_realm", SPELL_SOUL_CONSUMPTION, false);
+ RegisterSpellScriptWithArgs(spell_halion_twilight_realm_handlers, "spell_halion_enter_twilight_realm", SPELL_FIERY_COMBUSTION, true);
+ RegisterSpellScript(spell_halion_summon_exit_portals);
+ RegisterSpellScript(spell_halion_twilight_phasing);
+ RegisterSpellScript(spell_halion_twilight_cutter);
+ RegisterSpellScript(spell_halion_clear_debuffs);
+ RegisterSpellScript(spell_halion_spawn_living_embers);
+ RegisterSpellScript(spell_halion_blazing_aura);
}
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h
index 7c243617e03..7f6b48d2e2f 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/ruby_sanctum.h
@@ -136,5 +136,6 @@ inline AI* GetRubySanctumAI(T* obj)
}
#define RegisterRubySanctumCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetRubySanctumAI)
+#define RegisterRubySanctumGameObjectAI(ai_name) RegisterGameObjectAIWithFactory(ai_name, GetRubySanctumAI)
#endif // RUBY_SANCTUM_H_