aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorForesterDev <11771800+ForesterDev@users.noreply.github.com>2020-09-04 19:03:55 +0400
committerShauren <shauren.trinity@gmail.com>2022-02-05 11:42:35 +0100
commit2ac0960f3f5817cfb89b2fdff3ab4b62489df3a8 (patch)
tree30030470a37d11370f166c0e798c226492002eeb
parentd250640c6b5005f261507df6b9d5a069714a5fdb (diff)
Scripts/ICC: update Lich King scripts to new model (#25396)
* Scripts/ICC: update Lich King scripts to new model * fix build (cherry picked from commit d04bdd0316c5c158da4ec0461b714d04321e8f57)
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp4297
1 files changed, 1923 insertions, 2374 deletions
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index 51aafdf0c6e..566444dcb43 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -488,1964 +488,1739 @@ class TriggerWickedSpirit : public BasicEvent
uint32 _counter;
};
-class boss_the_lich_king : public CreatureScript
+struct boss_the_lich_king : public BossAI
{
- public:
- boss_the_lich_king() : CreatureScript("boss_the_lich_king") { }
-
- struct boss_the_lich_kingAI : public BossAI
- {
- boss_the_lich_kingAI(Creature* creature) : BossAI(creature, DATA_THE_LICH_KING)
- {
- Initialize();
- }
-
- void Initialize()
- {
- _necroticPlagueStack = 0;
- _vileSpiritExplosions = 0;
- }
+ boss_the_lich_king(Creature* creature) : BossAI(creature, DATA_THE_LICH_KING)
+ {
+ Initialize();
+ }
- void Reset() override
- {
- _Reset();
- me->SetImmuneToPC(true);
- me->SetReactState(REACT_PASSIVE);
- events.SetPhase(PHASE_INTRO);
- Initialize();
- SetEquipmentSlots(true);
-
- // Reset The Frozen Throne gameobjects
- FrozenThroneResetWorker reset;
- Trinity::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset);
- Cell::VisitGridObjects(me, worker, 333.0f);
-
- // Reset any light override
- me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, 0, 5000);
+ void Initialize()
+ {
+ _necroticPlagueStack = 0;
+ _vileSpiritExplosions = 0;
+ }
- if (!ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
- me->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING_LK, TirionSpawn, TEMPSUMMON_MANUAL_DESPAWN);
- }
+ void Reset() override
+ {
+ _Reset();
+ me->SetImmuneToPC(true);
+ me->SetReactState(REACT_PASSIVE);
+ events.SetPhase(PHASE_INTRO);
+ Initialize();
+ SetEquipmentSlots(true);
+
+ // Reset The Frozen Throne gameobjects
+ FrozenThroneResetWorker reset;
+ Trinity::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset);
+ Cell::VisitGridObjects(me, worker, 333.0f);
+
+ // Reset any light override
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, 0, 5000);
+
+ if (!ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ me->SummonCreature(NPC_HIGHLORD_TIRION_FORDRING_LK, TirionSpawn, TEMPSUMMON_MANUAL_DESPAWN);
+ }
- void JustDied(Unit* /*killer*/) override
- {
- _JustDied();
- DoCastAOE(SPELL_PLAY_MOVIE, false);
- me->SetDisableGravity(false);
- me->SetAnimTier(UNIT_BYTE1_FLAG_NONE, false);
- me->GetMotionMaster()->MoveFall();
- if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
- frostmourne->DespawnOrUnsummon();
- me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_FOG, 5000);
- me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_FOG, 0.0f);
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ DoCastAOE(SPELL_PLAY_MOVIE, false);
+ me->SetDisableGravity(false);
+ me->SetAnimTier(UNIT_BYTE1_FLAG_NONE, false);
+ me->GetMotionMaster()->MoveFall();
+ if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
+ frostmourne->DespawnOrUnsummon();
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_FOG, 5000);
+ me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_FOG, 0.0f);
+
+ if (Is25ManRaid())
+ if (Player* player = me->GetLootRecipient())
+ player->RewardPlayerAndGroupAtEvent(NPC_THE_LICH_KING_QUEST, player);
+ }
- if (Is25ManRaid())
- if (Player* player = me->GetLootRecipient())
- player->RewardPlayerAndGroupAtEvent(NPC_THE_LICH_KING_QUEST, player);
- }
+ void JustEngagedWith(Unit* target) override
+ {
+ if (!instance->CheckRequiredBosses(DATA_THE_LICH_KING, target->ToPlayer()))
+ {
+ EnterEvadeMode(EVADE_REASON_OTHER);
+ instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
+ return;
+ }
- void JustEngagedWith(Unit* target) override
- {
- if (!instance->CheckRequiredBosses(DATA_THE_LICH_KING, target->ToPlayer()))
- {
- EnterEvadeMode(EVADE_REASON_OTHER);
- instance->DoCastSpellOnPlayers(LIGHT_S_HAMMER_TELEPORT);
- return;
- }
+ me->setActive(true);
+ me->SetCombatPulseDelay(5);
+ DoZoneInCombat();
+
+ events.SetPhase(PHASE_ONE);
+ events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 20s, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 10s, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_INFEST, 5s, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, 30s, 33s, 0, PHASE_ONE);
+ events.ScheduleEvent(EVENT_BERSERK, 15min, EVENT_GROUP_BERSERK);
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500ms, 0, PHASE_ONE);
+ }
- me->setActive(true);
- me->SetCombatPulseDelay(5);
- DoZoneInCombat();
+ bool CanAIAttack(Unit const* target) const override
+ {
+ // The Lich King must not select targets in frostmourne room if he killed everyone outside
+ return !target->HasAura(SPELL_IN_FROSTMOURNE_ROOM) && BossAI::CanAIAttack(target);
+ }
- events.SetPhase(PHASE_ONE);
- events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 20s, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 10s, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_INFEST, 5s, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, 30s, 33s, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_BERSERK, 15min, EVENT_GROUP_BERSERK);
- if (IsHeroic())
- events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500ms, 0, PHASE_ONE);
- }
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ tirion->DespawnOrUnsummon();
+ DoCastAOE(SPELL_KILL_FROSTMOURNE_PLAYERS);
+ EntryCheckPredicate pred(NPC_STRANGULATE_VEHICLE);
+ summons.DoAction(ACTION_TELEPORT_BACK, pred);
+ summons.DespawnAll();
+ _DespawnAtEvade();
+ }
- bool CanAIAttack(Unit const* target) const override
- {
- // The Lich King must not select targets in frostmourne room if he killed everyone outside
- return !target->HasAura(SPELL_IN_FROSTMOURNE_ROOM) && BossAI::CanAIAttack(target);
- }
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode() && !events.IsInPhase(PHASE_OUTRO))
+ Talk(SAY_LK_KILL);
+ }
- void EnterEvadeMode(EvadeReason /*why*/) override
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_START_ENCOUNTER:
+ instance->SetBossState(DATA_THE_LICH_KING, IN_PROGRESS);
+ Talk(SAY_LK_INTRO_1);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FROZEN_THRONE);
+ // schedule talks
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ events.ScheduleEvent(EVENT_INTRO_MOVE_1, 4s);
+ break;
+ case ACTION_START_ATTACK:
+ events.ScheduleEvent(EVENT_START_ATTACK, 5s);
+ break;
+ case ACTION_PLAY_MUSIC:
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FINAL);
+ break;
+ case ACTION_RESTORE_LIGHT:
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, 0, 5000);
+ break;
+ case ACTION_BREAK_FROSTMOURNE:
+ me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
+ me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE_2, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
+ SetEquipmentSlots(false, EQUIP_BROKEN_FROSTMOURNE);
+ events.ScheduleEvent(EVENT_OUTRO_TALK_6, 2500ms, 0, PHASE_OUTRO);
+ break;
+ case ACTION_FINISH_OUTRO:
+ events.ScheduleEvent(EVENT_OUTRO_TALK_7, 7s, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_TALK_8, 17s, 0, PHASE_OUTRO);
+ break;
+ case ACTION_TELEPORT_BACK:
{
- if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
- tirion->DespawnOrUnsummon();
- DoCastAOE(SPELL_KILL_FROSTMOURNE_PLAYERS);
EntryCheckPredicate pred(NPC_STRANGULATE_VEHICLE);
summons.DoAction(ACTION_TELEPORT_BACK, pred);
- summons.DespawnAll();
- _DespawnAtEvade();
- }
-
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER && !me->IsInEvadeMode() && !events.IsInPhase(PHASE_OUTRO))
- Talk(SAY_LK_KILL);
+ if (!IsHeroic())
+ Talk(SAY_LK_FROSTMOURNE_ESCAPE);
+ break;
}
+ default:
+ break;
+ }
+ }
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_START_ENCOUNTER:
- instance->SetBossState(DATA_THE_LICH_KING, IN_PROGRESS);
- Talk(SAY_LK_INTRO_1);
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FROZEN_THRONE);
- // schedule talks
- me->SetStandState(UNIT_STAND_STATE_STAND);
- events.ScheduleEvent(EVENT_INTRO_MOVE_1, 4s);
- break;
- case ACTION_START_ATTACK:
- events.ScheduleEvent(EVENT_START_ATTACK, 5s);
- break;
- case ACTION_PLAY_MUSIC:
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FINAL);
- break;
- case ACTION_RESTORE_LIGHT:
- me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, 0, 5000);
- break;
- case ACTION_BREAK_FROSTMOURNE:
- me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
- me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE_2, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
- SetEquipmentSlots(false, EQUIP_BROKEN_FROSTMOURNE);
- events.ScheduleEvent(EVENT_OUTRO_TALK_6, 2500ms, 0, PHASE_OUTRO);
- break;
- case ACTION_FINISH_OUTRO:
- events.ScheduleEvent(EVENT_OUTRO_TALK_7, 7s, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_TALK_8, 17s, 0, PHASE_OUTRO);
- break;
- case ACTION_TELEPORT_BACK:
- {
- EntryCheckPredicate pred(NPC_STRANGULATE_VEHICLE);
- summons.DoAction(ACTION_TELEPORT_BACK, pred);
- if (!IsHeroic())
- Talk(SAY_LK_FROSTMOURNE_ESCAPE);
- break;
- }
- default:
- break;
- }
- }
+ uint32 GetData(uint32 type) const override
+ {
+ switch (type)
+ {
+ case DATA_PLAGUE_STACK:
+ return _necroticPlagueStack;
+ case DATA_VILE:
+ return _vileSpiritExplosions;
+ default:
+ break;
+ }
- uint32 GetData(uint32 type) const override
- {
- switch (type)
- {
- case DATA_PLAGUE_STACK:
- return _necroticPlagueStack;
- case DATA_VILE:
- return _vileSpiritExplosions;
- default:
- break;
- }
+ return 0;
+ }
- return 0;
- }
+ void SetData(uint32 type, uint32 value) override
+ {
+ switch (type)
+ {
+ case DATA_PLAGUE_STACK:
+ _necroticPlagueStack = std::max(value, _necroticPlagueStack);
+ break;
+ case DATA_VILE:
+ _vileSpiritExplosions += value;
+ break;
+ default:
+ break;
+ }
+ }
- void SetData(uint32 type, uint32 value) override
- {
- switch (type)
- {
- case DATA_PLAGUE_STACK:
- _necroticPlagueStack = std::max(value, _necroticPlagueStack);
- break;
- case DATA_VILE:
- _vileSpiritExplosions += value;
- break;
- default:
- break;
- }
- }
+ void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
+ {
+ if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(70))
+ {
+ events.SetPhase(PHASE_TRANSITION);
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ me->InterruptNonMeleeSpells(true);
+ me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition);
+ return;
+ }
- void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
- {
- if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(70))
- {
- events.SetPhase(PHASE_TRANSITION);
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
- me->InterruptNonMeleeSpells(true);
- me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition);
- return;
- }
+ if (events.IsInPhase(PHASE_TWO) && !HealthAbovePct(40))
+ {
+ events.SetPhase(PHASE_TRANSITION);
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ me->InterruptNonMeleeSpells(true);
+ me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition);
+ return;
+ }
- if (events.IsInPhase(PHASE_TWO) && !HealthAbovePct(40))
- {
- events.SetPhase(PHASE_TRANSITION);
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
- me->InterruptNonMeleeSpells(true);
- me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition);
- return;
- }
+ if (events.IsInPhase(PHASE_THREE) && !HealthAbovePct(10))
+ {
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ events.Reset();
+ events.SetPhase(PHASE_OUTRO);
+ summons.DespawnAll();
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FURY_OF_FROSTMOURNE);
+ me->InterruptNonMeleeSpells(true);
+ me->CastSpell(nullptr, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE);
+ me->SetWalk(true);
+ events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 17600ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 27600ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_TALK_2, 34600ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_TALK_3, 43600ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 54600ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 58600ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_MOVE_CENTER, 69600ms, 0, PHASE_OUTRO);
+ // stop here. rest will get scheduled from MovementInform
+ return;
+ }
+ }
- if (events.IsInPhase(PHASE_THREE) && !HealthAbovePct(10))
+ void JustSummoned(Creature* summon) override
+ {
+ switch (summon->GetEntry())
+ {
+ case NPC_SHAMBLING_HORROR:
+ case NPC_DRUDGE_GHOUL:
+ summon->CastSpell(summon, SPELL_RISEN_WITCH_DOCTOR_SPAWN, true);
+ summon->SetReactState(REACT_PASSIVE);
+ summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
+ summon->m_Events.AddEvent(new LichKingStartMovementEvent(me, summon), summon->m_Events.CalculateTime(5s));
+ break;
+ case NPC_SHADOW_TRAP:
+ summon->CastSpell(summon, SPELL_SHADOW_TRAP_VISUAL, true);
+ break;
+ case NPC_ICE_SPHERE:
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
{
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
- events.Reset();
- events.SetPhase(PHASE_OUTRO);
- summons.DespawnAll();
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FURY_OF_FROSTMOURNE);
- me->InterruptNonMeleeSpells(true);
- me->CastSpell(nullptr, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE);
- me->SetWalk(true);
- events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 17600ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 27600ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_TALK_2, 34600ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_TALK_3, 43600ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 54600ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 58600ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_MOVE_CENTER, 69600ms, 0, PHASE_OUTRO);
- // stop here. rest will get scheduled from MovementInform
- return;
+ summon->SetReactState(REACT_PASSIVE);
+ summon->CastSpell(summon, SPELL_ICE_SPHERE, false);
+ summon->CastSpell(summon, SPELL_ICE_BURST_TARGET_SEARCH, false);
+ summon->CastSpell(target, SPELL_ICE_PULSE, false);
+ summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f);
}
- }
-
- void JustSummoned(Creature* summon) override
- {
- switch (summon->GetEntry())
- {
- case NPC_SHAMBLING_HORROR:
- case NPC_DRUDGE_GHOUL:
- summon->CastSpell(summon, SPELL_RISEN_WITCH_DOCTOR_SPAWN, true);
- summon->SetReactState(REACT_PASSIVE);
- summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
- summon->m_Events.AddEvent(new LichKingStartMovementEvent(me, summon), summon->m_Events.CalculateTime(5s));
- break;
- case NPC_SHADOW_TRAP:
- summon->CastSpell(summon, SPELL_SHADOW_TRAP_VISUAL, true);
- break;
- case NPC_ICE_SPHERE:
- {
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
- {
- summon->SetReactState(REACT_PASSIVE);
- summon->CastSpell(summon, SPELL_ICE_SPHERE, false);
- summon->CastSpell(summon, SPELL_ICE_BURST_TARGET_SEARCH, false);
- summon->CastSpell(target, SPELL_ICE_PULSE, false);
- summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f);
- }
- else
- summon->DespawnOrUnsummon();
- break;
- }
- case NPC_DEFILE:
- summon->SetReactState(REACT_PASSIVE);
- summon->CastSpell(summon, SPELL_DEFILE_AURA, false);
- break;
- case NPC_FROSTMOURNE_TRIGGER:
- {
- summon->CastSpell(nullptr, SPELL_BROKEN_FROSTMOURNE, true);
+ else
+ summon->DespawnOrUnsummon();
+ break;
+ }
+ case NPC_DEFILE:
+ summon->SetReactState(REACT_PASSIVE);
+ summon->CastSpell(summon, SPELL_DEFILE_AURA, false);
+ break;
+ case NPC_FROSTMOURNE_TRIGGER:
+ {
+ summon->CastSpell(nullptr, SPELL_BROKEN_FROSTMOURNE, true);
+
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_SOULSTORM, 10000);
+ me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_BLACKSNOW, 0.5f);
+
+ events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5s, 0, PHASE_OUTRO);
+ return;
+ }
+ case NPC_VILE_SPIRIT:
+ {
+ summons.Summon(summon);
+ summon->SetReactState(REACT_PASSIVE);
+ summon->SetSpeedRate(MOVE_FLIGHT, 0.5f);
+ summon->GetMotionMaster()->MoveRandom(10.0f);
+ if (!events.IsInPhase(PHASE_FROSTMOURNE))
+ summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15s));
+ return;
+ }
+ case NPC_STRANGULATE_VEHICLE:
+ summons.Summon(summon);
+ return;
+ case NPC_HIGHLORD_TIRION_FORDRING_LK:
+ return;
+ default:
+ break;
+ }
- me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_SOULSTORM, 10000);
- me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_BLACKSNOW, 0.5f);
+ BossAI::JustSummoned(summon);
+ }
- events.ScheduleEvent(EVENT_OUTRO_SOUL_BARRAGE, 5s, 0, PHASE_OUTRO);
- return;
- }
- case NPC_VILE_SPIRIT:
- {
- summons.Summon(summon);
- summon->SetReactState(REACT_PASSIVE);
- summon->SetSpeedRate(MOVE_FLIGHT, 0.5f);
- summon->GetMotionMaster()->MoveRandom(10.0f);
- if (!events.IsInPhase(PHASE_FROSTMOURNE))
- summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15s));
- return;
- }
- case NPC_STRANGULATE_VEHICLE:
- summons.Summon(summon);
- return;
- case NPC_HIGHLORD_TIRION_FORDRING_LK:
- return;
- default:
- break;
- }
+ void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
+ {
+ switch (summon->GetEntry())
+ {
+ case NPC_SHAMBLING_HORROR:
+ case NPC_DRUDGE_GHOUL:
+ case NPC_ICE_SPHERE:
+ case NPC_VALKYR_SHADOWGUARD:
+ case NPC_RAGING_SPIRIT:
+ case NPC_VILE_SPIRIT:
+ summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
+ break;
+ default:
+ break;
+ }
+ }
- BossAI::JustSummoned(summon);
- }
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_HARVESTED_SOUL && me->IsInCombat() && !IsHeroic())
+ Talk(SAY_LK_FROSTMOURNE_KILL);
- void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
- {
- switch (summon->GetEntry())
- {
- case NPC_SHAMBLING_HORROR:
- case NPC_DRUDGE_GHOUL:
- case NPC_ICE_SPHERE:
- case NPC_VALKYR_SHADOWGUARD:
- case NPC_RAGING_SPIRIT:
- case NPC_VILE_SPIRIT:
- summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
- break;
- default:
- break;
- }
- }
+ if (spellInfo->Id == REMORSELESS_WINTER_1 || spellInfo->Id == REMORSELESS_WINTER_2)
+ {
+ me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_SNOWSTORM, 5000);
+ me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_LIGHT_SNOW, 0.5f);
+ summons.DespawnEntry(NPC_SHADOW_TRAP);
+ }
+ }
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
- {
- if (spellInfo->Id == SPELL_HARVESTED_SOUL && me->IsInCombat() && !IsHeroic())
- Talk(SAY_LK_FROSTMOURNE_KILL);
+ void MovementInform(uint32 type, uint32 pointId) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ switch (pointId)
+ {
+ case POINT_LK_INTRO_1:
+ // schedule for next update cycle, current update must finalize movement
+ events.ScheduleEvent(EVENT_INTRO_MOVE_2, 1ms, 0, PHASE_INTRO);
+ break;
+ case POINT_LK_INTRO_2:
+ events.ScheduleEvent(EVENT_INTRO_MOVE_3, 1ms, 0, PHASE_INTRO);
+ break;
+ case POINT_LK_INTRO_3:
+ if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ tirion->AI()->DoAction(ACTION_CONTINUE_INTRO);
+ events.ScheduleEvent(EVENT_INTRO_TALK_1, 9s, 0, PHASE_INTRO);
+ break;
+ case POINT_CENTER_1:
+ me->SetFacingTo(0.0f);
+ Talk(SAY_LK_REMORSELESS_WINTER);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
+ DoCastSelf(SPELL_REMORSELESS_WINTER_1);
+ events.ScheduleEvent(EVENT_QUAKE, 62500ms, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 4s, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8s, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 6s, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_SUMMON_VALKYR, 78s, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_INFEST, 70s, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_DEFILE, 97s, 0, PHASE_TWO);
+ events.ScheduleEvent(EVENT_SOUL_REAPER, 94s, 0, PHASE_TWO);
+ break;
+ case POINT_CENTER_2:
+ me->SetFacingTo(0.0f);
+ Talk(SAY_LK_REMORSELESS_WINTER);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
+ DoCastSelf(SPELL_REMORSELESS_WINTER_2);
+ summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD);
+ events.ScheduleEvent(EVENT_QUAKE_2, 62500ms, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 6s, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8s, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT_2, 5s, 0, PHASE_TRANSITION);
+ events.ScheduleEvent(EVENT_DEFILE, 95500ms, 0, PHASE_THREE);
+ events.ScheduleEvent(EVENT_SOUL_REAPER, 99500ms, 0, PHASE_THREE);
+ events.ScheduleEvent(EVENT_VILE_SPIRITS, 79500ms, EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
+ events.ScheduleEvent(IsHeroic() ? EVENT_HARVEST_SOULS : EVENT_HARVEST_SOUL, 73500ms, 0, PHASE_THREE);
+ break;
+ case POINT_LK_OUTRO_1:
+ events.ScheduleEvent(EVENT_OUTRO_TALK_4, 1ms, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_RAISE_DEAD, 1s, 0, PHASE_OUTRO);
+ events.ScheduleEvent(EVENT_OUTRO_TALK_5, 29s, 0, PHASE_OUTRO);
+ break;
+ case POINT_LK_OUTRO_2:
+ if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ tirion->AI()->Talk(SAY_TIRION_OUTRO_2);
+ if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
+ frostmourne->AI()->DoAction(ACTION_SUMMON_TERENAS);
+ break;
+ default:
+ break;
+ }
+ }
- if (spellInfo->Id == REMORSELESS_WINTER_1 || spellInfo->Id == REMORSELESS_WINTER_2)
- {
- me->GetMap()->SetZoneOverrideLight(AREA_ICECROWN_CITADEL, LIGHT_DEFAULT, LIGHT_SNOWSTORM, 5000);
- me->GetMap()->SetZoneWeather(AREA_ICECROWN_CITADEL, WEATHER_STATE_LIGHT_SNOW, 0.5f);
- summons.DespawnEntry(NPC_SHADOW_TRAP);
- }
- }
+ void UpdateAI(uint32 diff) override
+ {
+ // check phase first to prevent updating victim and entering evade mode when not wanted
+ if (!(events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_INTRO) || events.IsInPhase(PHASE_FROSTMOURNE)))
+ if (!UpdateVictim())
+ return;
- void MovementInform(uint32 type, uint32 pointId) override
- {
- if (type != POINT_MOTION_TYPE)
- return;
+ events.Update(diff);
- switch (pointId)
- {
- case POINT_LK_INTRO_1:
- // schedule for next update cycle, current update must finalize movement
- events.ScheduleEvent(EVENT_INTRO_MOVE_2, 1ms, 0, PHASE_INTRO);
- break;
- case POINT_LK_INTRO_2:
- events.ScheduleEvent(EVENT_INTRO_MOVE_3, 1ms, 0, PHASE_INTRO);
- break;
- case POINT_LK_INTRO_3:
- if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
- tirion->AI()->DoAction(ACTION_CONTINUE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_TALK_1, 9s, 0, PHASE_INTRO);
- break;
- case POINT_CENTER_1:
- me->SetFacingTo(0.0f);
- Talk(SAY_LK_REMORSELESS_WINTER);
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
- DoCast(me, SPELL_REMORSELESS_WINTER_1);
- events.ScheduleEvent(EVENT_QUAKE, 62500ms, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 4s, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8s, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 6s, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_SUMMON_VALKYR, 78s, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_INFEST, 70s, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_DEFILE, 97s, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_SOUL_REAPER, 94s, 0, PHASE_TWO);
- break;
- case POINT_CENTER_2:
- me->SetFacingTo(0.0f);
- Talk(SAY_LK_REMORSELESS_WINTER);
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
- DoCast(me, SPELL_REMORSELESS_WINTER_2);
- summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD);
- events.ScheduleEvent(EVENT_QUAKE_2, 62500ms, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 6s, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 8s, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT_2, 5s, 0, PHASE_TRANSITION);
- events.ScheduleEvent(EVENT_DEFILE, 95500ms, 0, PHASE_THREE);
- events.ScheduleEvent(EVENT_SOUL_REAPER, 99500ms, 0, PHASE_THREE);
- events.ScheduleEvent(EVENT_VILE_SPIRITS, 79500ms, EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
- events.ScheduleEvent(IsHeroic() ? EVENT_HARVEST_SOULS : EVENT_HARVEST_SOUL, 73500ms, 0, PHASE_THREE);
- break;
- case POINT_LK_OUTRO_1:
- events.ScheduleEvent(EVENT_OUTRO_TALK_4, 1ms, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_RAISE_DEAD, 1s, 0, PHASE_OUTRO);
- events.ScheduleEvent(EVENT_OUTRO_TALK_5, 29s, 0, PHASE_OUTRO);
- break;
- case POINT_LK_OUTRO_2:
- if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
- tirion->AI()->Talk(SAY_TIRION_OUTRO_2);
- if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
- frostmourne->AI()->DoAction(ACTION_SUMMON_TERENAS);
- break;
- default:
- break;
- }
- }
+ // during Remorseless Winter phases The Lich King is channeling a spell, but we must continue casting other spells
+ if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.IsInPhase(PHASE_TRANSITION) || events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_FROSTMOURNE)))
+ return;
- void UpdateAI(uint32 diff) override
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- // check phase first to prevent updating victim and entering evade mode when not wanted
- if (!(events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_INTRO) || events.IsInPhase(PHASE_FROSTMOURNE)))
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- // during Remorseless Winter phases The Lich King is channeling a spell, but we must continue casting other spells
- if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.IsInPhase(PHASE_TRANSITION) || events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_FROSTMOURNE)))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
+ case EVENT_INTRO_MOVE_1:
+ me->SetSheath(SHEATH_STATE_MELEE);
+ me->RemoveAurasDueToSpell(SPELL_EMOTE_SIT_NO_SHEATH);
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_1, LichKingIntro[0]);
+ break;
+ case EVENT_INTRO_MOVE_2:
+ me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_2, LichKingIntro[1]);
+ break;
+ case EVENT_INTRO_MOVE_3:
+ me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_3, LichKingIntro[2]);
+ break;
+ case EVENT_INTRO_TALK_1:
+ Talk(SAY_LK_INTRO_2);
+ // for some reason blizz sends 2 emotes in row here so (we handle one in Talk)
+ me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
+ events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 7s, 0, PHASE_INTRO);
+ events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 13s, 0, PHASE_INTRO);
+ events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 18s, 0, PHASE_INTRO);
+ events.ScheduleEvent(EVENT_INTRO_CAST_FREEZE, 31s, 0, PHASE_INTRO);
+ break;
+ case EVENT_EMOTE_CAST_SHOUT:
+ DoCastSelf(SPELL_EMOTE_SHOUT_NO_SHEATH, false);
+ break;
+ case EVENT_INTRO_EMOTE_1:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NO_SHEATHE);
+ break;
+ case EVENT_INTRO_CAST_FREEZE:
+ Talk(SAY_LK_INTRO_3);
+ DoCastAOE(SPELL_ICE_LOCK, false);
+ events.ScheduleEvent(EVENT_FINISH_INTRO, 1s, 0, PHASE_INTRO);
+ break;
+ case EVENT_FINISH_INTRO:
+ me->SetWalk(false);
+ me->SetImmuneToPC(false);
+ me->SetReactState(REACT_AGGRESSIVE);
+ events.SetPhase(PHASE_ONE);
+ DoZoneInCombat();
+ break;
+ case EVENT_SUMMON_SHAMBLING_HORROR:
+ DoCastSelf(SPELL_SUMMON_SHAMBLING_HORROR);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
+ events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 1min, 0, PHASE_ONE);
+ break;
+ case EVENT_SUMMON_DRUDGE_GHOUL:
+ DoCastSelf(SPELL_SUMMON_DRUDGE_GHOULS);
+ events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 30s, 0, PHASE_ONE);
+ break;
+ case EVENT_INFEST:
+ DoCastSelf(SPELL_INFEST);
+ events.ScheduleEvent(EVENT_INFEST, 21s, 24s, 0, events.IsInPhase(PHASE_ONE) ? PHASE_ONE : PHASE_TWO);
+ break;
+ case EVENT_NECROTIC_PLAGUE:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, NecroticPlagueTargetCheck(me, NECROTIC_PLAGUE_LK, NECROTIC_PLAGUE_PLR)))
{
- case EVENT_INTRO_MOVE_1:
- me->SetSheath(SHEATH_STATE_MELEE);
- me->RemoveAurasDueToSpell(SPELL_EMOTE_SIT_NO_SHEATH);
- me->SetWalk(true);
- me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_1, LichKingIntro[0]);
- break;
- case EVENT_INTRO_MOVE_2:
- me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_2, LichKingIntro[1]);
- break;
- case EVENT_INTRO_MOVE_3:
- me->GetMotionMaster()->MovePoint(POINT_LK_INTRO_3, LichKingIntro[2]);
- break;
- case EVENT_INTRO_TALK_1:
- Talk(SAY_LK_INTRO_2);
- // for some reason blizz sends 2 emotes in row here so (we handle one in Talk)
- me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
- events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 7s, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 13s, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_EMOTE_CAST_SHOUT, 18s, 0, PHASE_INTRO);
- events.ScheduleEvent(EVENT_INTRO_CAST_FREEZE, 31s, 0, PHASE_INTRO);
- break;
- case EVENT_EMOTE_CAST_SHOUT:
- DoCast(me, SPELL_EMOTE_SHOUT_NO_SHEATH, false);
- break;
- case EVENT_INTRO_EMOTE_1:
- me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NO_SHEATHE);
- break;
- case EVENT_INTRO_CAST_FREEZE:
- Talk(SAY_LK_INTRO_3);
- DoCastAOE(SPELL_ICE_LOCK, false);
- events.ScheduleEvent(EVENT_FINISH_INTRO, 1s, 0, PHASE_INTRO);
- break;
- case EVENT_FINISH_INTRO:
- me->SetWalk(false);
- me->SetImmuneToPC(false);
- me->SetReactState(REACT_AGGRESSIVE);
- events.SetPhase(PHASE_ONE);
- break;
- case EVENT_SUMMON_SHAMBLING_HORROR:
- DoCast(me, SPELL_SUMMON_SHAMBLING_HORROR);
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
- events.ScheduleEvent(EVENT_SUMMON_SHAMBLING_HORROR, 1min, 0, PHASE_ONE);
- break;
- case EVENT_SUMMON_DRUDGE_GHOUL:
- DoCast(me, SPELL_SUMMON_DRUDGE_GHOULS);
- events.ScheduleEvent(EVENT_SUMMON_DRUDGE_GHOUL, 30s, 0, PHASE_ONE);
- break;
- case EVENT_INFEST:
- DoCast(me, SPELL_INFEST);
- events.ScheduleEvent(EVENT_INFEST, 21s, 24s, 0, events.IsInPhase(PHASE_ONE) ? PHASE_ONE : PHASE_TWO);
- break;
- case EVENT_NECROTIC_PLAGUE:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, NecroticPlagueTargetCheck(me, NECROTIC_PLAGUE_LK, NECROTIC_PLAGUE_PLR)))
- {
- Talk(EMOTE_NECROTIC_PLAGUE_WARNING, target);
- DoCast(target, SPELL_NECROTIC_PLAGUE);
- }
- events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, 30s, 33s, 0, PHASE_ONE);
- break;
- case EVENT_SHADOW_TRAP:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, SpellTargetSelector(me, SPELL_SHADOW_TRAP)))
- DoCast(target, SPELL_SHADOW_TRAP);
- events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500ms, 0, PHASE_ONE);
- break;
- case EVENT_SOUL_REAPER:
- DoCastVictim(SPELL_SOUL_REAPER);
- events.ScheduleEvent(EVENT_SOUL_REAPER, 33s, 35s, 0, PHASE_TWO_THREE);
- break;
- case EVENT_DEFILE:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_HARVEST_SOUL_VALKYR))
- {
- Talk(EMOTE_DEFILE_WARNING);
- DoCast(target, SPELL_DEFILE);
- }
- events.ScheduleEvent(EVENT_DEFILE, 32s, 35s, 0, PHASE_TWO_THREE);
- break;
- case EVENT_HARVEST_SOUL:
- Talk(SAY_LK_HARVEST_SOUL);
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, SpellTargetSelector(me, SPELL_HARVEST_SOUL)))
- DoCast(target, SPELL_HARVEST_SOUL);
- events.ScheduleEvent(EVENT_HARVEST_SOUL, 75s, 0, PHASE_THREE);
- break;
- case EVENT_PAIN_AND_SUFFERING:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
- me->CastSpell(target, SPELL_PAIN_AND_SUFFERING, TRIGGERED_NONE);
- events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 1500ms, 4s, 0, PHASE_TRANSITION);
- break;
- case EVENT_SUMMON_ICE_SPHERE:
- DoCastAOE(SPELL_SUMMON_ICE_SPHERE);
- events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 7500ms, 8500ms, 0, PHASE_TRANSITION);
- break;
- case EVENT_SUMMON_RAGING_SPIRIT:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
- me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE);
- events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 22s, 23s, 0, PHASE_TRANSITION);
- break;
- case EVENT_SUMMON_RAGING_SPIRIT_2:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
- me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE);
- events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 18s, 0, PHASE_TRANSITION);
- break;
- case EVENT_QUAKE:
- events.SetPhase(PHASE_TWO);
- me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes
- DoCastAOE(SPELL_QUAKE);
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
- Talk(SAY_LK_QUAKE);
- break;
- case EVENT_QUAKE_2:
- events.SetPhase(PHASE_THREE);
- me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes
- DoCastAOE(SPELL_QUAKE);
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
- Talk(SAY_LK_QUAKE);
- break;
- case EVENT_SUMMON_VALKYR:
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
- Talk(SAY_LK_SUMMON_VALKYR);
- DoCastAOE(SUMMON_VALKYR, true);
- events.ScheduleEvent(EVENT_SUMMON_VALKYR, 45s, 50s, 0, PHASE_TWO);
- break;
- case EVENT_START_ATTACK:
- me->SetReactState(REACT_AGGRESSIVE);
- if (events.IsInPhase(PHASE_FROSTMOURNE))
- events.SetPhase(PHASE_THREE);
- break;
- case EVENT_VILE_SPIRITS:
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
- DoCastAOE(SPELL_VILE_SPIRITS);
- events.ScheduleEvent(EVENT_VILE_SPIRITS, 35s, 40s, EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
- break;
- case EVENT_HARVEST_SOULS:
- Talk(SAY_LK_HARVEST_SOUL);
- DoCastAOE(SPELL_HARVEST_SOULS);
- events.ScheduleEvent(EVENT_HARVEST_SOULS, 100s, 110s, 0, PHASE_THREE);
- events.SetPhase(PHASE_FROSTMOURNE); // will stop running UpdateVictim (no evading)
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
- events.DelayEvents(50s, EVENT_GROUP_VILE_SPIRITS);
- events.RescheduleEvent(EVENT_DEFILE, 50s, 0, PHASE_THREE);
- events.RescheduleEvent(EVENT_SOUL_REAPER, 57s, 62s, 0, PHASE_THREE);
- events.ScheduleEvent(EVENT_START_ATTACK, 49s);
- events.ScheduleEvent(EVENT_FROSTMOURNE_HEROIC, 6500ms);
- for (ObjectGuid guid : summons)
- {
- if (Creature* summon = ObjectAccessor::GetCreature(*me, guid))
- {
- if (summon->GetEntry() == NPC_VILE_SPIRIT)
- {
- summon->m_Events.KillAllEvents(true);
- summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(56500ms));
- summon->SetReactState(REACT_PASSIVE);
- summon->CombatStop(true);
- summon->RemoveAurasDueToSpell(SPELL_VILE_SPIRIT_MOVE_SEARCH);
- summon->RemoveAurasDueToSpell(SPELL_VILE_SPIRIT_DAMAGE_SEARCH);
- summon->GetMotionMaster()->MoveTargetedHome();
- }
- else if (summon->GetEntry() == NPC_RAGING_SPIRIT)
- summon->AI()->DoAction(ACTION_DISABLE_RAGING);
- }
- }
- break;
- case EVENT_FROSTMOURNE_HEROIC:
- if (TempSummon* terenas = me->GetMap()->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE_H, TerenasSpawnHeroic, nullptr, 50000))
+ Talk(EMOTE_NECROTIC_PLAGUE_WARNING, target);
+ DoCast(target, SPELL_NECROTIC_PLAGUE);
+ }
+ events.ScheduleEvent(EVENT_NECROTIC_PLAGUE, 30s, 33s, 0, PHASE_ONE);
+ break;
+ case EVENT_SHADOW_TRAP:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, SpellTargetSelector(me, SPELL_SHADOW_TRAP)))
+ DoCast(target, SPELL_SHADOW_TRAP);
+ events.ScheduleEvent(EVENT_SHADOW_TRAP, 15500ms, 0, PHASE_ONE);
+ break;
+ case EVENT_SOUL_REAPER:
+ DoCastVictim(SPELL_SOUL_REAPER);
+ events.ScheduleEvent(EVENT_SOUL_REAPER, 33s, 35s, 0, PHASE_TWO_THREE);
+ break;
+ case EVENT_DEFILE:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true, true, -SPELL_HARVEST_SOUL_VALKYR))
+ {
+ Talk(EMOTE_DEFILE_WARNING);
+ DoCast(target, SPELL_DEFILE);
+ }
+ events.ScheduleEvent(EVENT_DEFILE, 32s, 35s, 0, PHASE_TWO_THREE);
+ break;
+ case EVENT_HARVEST_SOUL:
+ Talk(SAY_LK_HARVEST_SOUL);
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, SpellTargetSelector(me, SPELL_HARVEST_SOUL)))
+ DoCast(target, SPELL_HARVEST_SOUL);
+ events.ScheduleEvent(EVENT_HARVEST_SOUL, 75s, 0, PHASE_THREE);
+ break;
+ case EVENT_PAIN_AND_SUFFERING:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
+ me->CastSpell(target, SPELL_PAIN_AND_SUFFERING, TRIGGERED_NONE);
+ events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 1500ms, 4s, 0, PHASE_TRANSITION);
+ break;
+ case EVENT_SUMMON_ICE_SPHERE:
+ DoCastAOE(SPELL_SUMMON_ICE_SPHERE);
+ events.ScheduleEvent(EVENT_SUMMON_ICE_SPHERE, 7500ms, 8500ms, 0, PHASE_TRANSITION);
+ break;
+ case EVENT_SUMMON_RAGING_SPIRIT:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
+ me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE);
+ events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 22s, 23s, 0, PHASE_TRANSITION);
+ break;
+ case EVENT_SUMMON_RAGING_SPIRIT_2:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
+ me->CastSpell(target, SPELL_RAGING_SPIRIT, TRIGGERED_NONE);
+ events.ScheduleEvent(EVENT_SUMMON_RAGING_SPIRIT, 18s, 0, PHASE_TRANSITION);
+ break;
+ case EVENT_QUAKE:
+ events.SetPhase(PHASE_TWO);
+ me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes
+ DoCastAOE(SPELL_QUAKE);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
+ Talk(SAY_LK_QUAKE);
+ break;
+ case EVENT_QUAKE_2:
+ events.SetPhase(PHASE_THREE);
+ me->ClearUnitState(UNIT_STATE_CASTING); // clear state to ensure check in DoCastAOE passes
+ DoCastAOE(SPELL_QUAKE);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
+ Talk(SAY_LK_QUAKE);
+ break;
+ case EVENT_SUMMON_VALKYR:
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
+ Talk(SAY_LK_SUMMON_VALKYR);
+ DoCastAOE(SUMMON_VALKYR, true);
+ events.ScheduleEvent(EVENT_SUMMON_VALKYR, 45s, 50s, 0, PHASE_TWO);
+ break;
+ case EVENT_START_ATTACK:
+ me->SetReactState(REACT_AGGRESSIVE);
+ if (events.IsInPhase(PHASE_FROSTMOURNE))
+ events.SetPhase(PHASE_THREE);
+ break;
+ case EVENT_VILE_SPIRITS:
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_SPECIAL);
+ DoCastAOE(SPELL_VILE_SPIRITS);
+ events.ScheduleEvent(EVENT_VILE_SPIRITS, 35s, 40s, EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
+ break;
+ case EVENT_HARVEST_SOULS:
+ Talk(SAY_LK_HARVEST_SOUL);
+ DoCastAOE(SPELL_HARVEST_SOULS);
+ events.ScheduleEvent(EVENT_HARVEST_SOULS, 100s, 110s, 0, PHASE_THREE);
+ events.SetPhase(PHASE_FROSTMOURNE); // will stop running UpdateVictim (no evading)
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ events.DelayEvents(50s, EVENT_GROUP_VILE_SPIRITS);
+ events.RescheduleEvent(EVENT_DEFILE, 50s, 0, PHASE_THREE);
+ events.RescheduleEvent(EVENT_SOUL_REAPER, 57s, 62s, 0, PHASE_THREE);
+ events.ScheduleEvent(EVENT_START_ATTACK, 49s);
+ events.ScheduleEvent(EVENT_FROSTMOURNE_HEROIC, 6500ms);
+ for (ObjectGuid guid : summons)
+ {
+ if (Creature* summon = ObjectAccessor::GetCreature(*me, guid))
+ {
+ if (summon->GetEntry() == NPC_VILE_SPIRIT)
{
- terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO);
- std::list<Creature*> triggers;
- GetCreatureListWithEntryInGrid(triggers, terenas, NPC_WORLD_TRIGGER_INFINITE_AOI, 100.0f);
- if (!triggers.empty())
- {
- triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, true));
- Creature* spawner = triggers.front();
- spawner->setActive(true);
- spawner->SetFarVisible(true);
- spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true); // summons bombs randomly
- spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players
- spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3s));
- }
+ summon->m_Events.KillAllEvents(true);
+ summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(56500ms));
+ summon->SetReactState(REACT_PASSIVE);
+ summon->CombatStop(true);
+ summon->RemoveAurasDueToSpell(SPELL_VILE_SPIRIT_MOVE_SEARCH);
+ summon->RemoveAurasDueToSpell(SPELL_VILE_SPIRIT_DAMAGE_SEARCH);
+ summon->GetMotionMaster()->MoveTargetedHome();
}
- break;
- case EVENT_OUTRO_TALK_1:
- Talk(SAY_LK_OUTRO_1);
- DoCastAOE(SPELL_FURY_OF_FROSTMOURNE_NO_REZ, true);
- break;
- case EVENT_OUTRO_TALK_2:
- Talk(SAY_LK_OUTRO_2);
- DoCastAOE(SPELL_EMOTE_QUESTION_NO_SHEATH);
- break;
- case EVENT_OUTRO_EMOTE_TALK:
- me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
- break;
- case EVENT_OUTRO_TALK_3:
- if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
- me->SetFacingToObject(tirion);
- Talk(SAY_LK_OUTRO_3);
- break;
- case EVENT_OUTRO_MOVE_CENTER:
- me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_1, CenterPosition);
- break;
- case EVENT_OUTRO_TALK_4:
- me->SetFacingTo(0.01745329f);
- Talk(SAY_LK_OUTRO_4);
- break;
- case EVENT_OUTRO_RAISE_DEAD:
- DoCastAOE(SPELL_RAISE_DEAD);
- me->ClearUnitState(UNIT_STATE_CASTING);
- me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FINAL);
- break;
- case EVENT_OUTRO_TALK_5:
- Talk(SAY_LK_OUTRO_5);
- if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
- tirion->AI()->DoAction(ACTION_OUTRO);
- break;
- case EVENT_OUTRO_TALK_6:
- Talk(SAY_LK_OUTRO_6);
- if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
- tirion->SetFacingToObject(me);
- me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE_3, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
- SetEquipmentSlots(false, EQUIP_UNEQUIP);
- break;
- case EVENT_OUTRO_SOUL_BARRAGE:
- me->CastSpell(nullptr, SPELL_SOUL_BARRAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
- CreatureTextMgr::SendSound(me, SOUND_PAIN, CHAT_MSG_MONSTER_YELL);
- // set flight
- me->SetDisableGravity(true);
- me->SetAnimTier(UnitBytes1_Flags(UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER), false);
- me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_2, OutroFlying);
- break;
- case EVENT_OUTRO_TALK_7:
- Talk(SAY_LK_OUTRO_7);
- break;
- case EVENT_OUTRO_TALK_8:
- Talk(SAY_LK_OUTRO_8);
- break;
- case EVENT_BERSERK:
- Talk(SAY_LK_BERSERK);
- DoCast(me, SPELL_BERSERK2);
- break;
- default:
- break;
+ else if (summon->GetEntry() == NPC_RAGING_SPIRIT)
+ summon->AI()->DoAction(ACTION_DISABLE_RAGING);
+ }
}
-
- if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.IsInPhase(PHASE_TRANSITION) || events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_FROSTMOURNE)))
- return;
- }
-
- DoMeleeAttackIfReady();
+ break;
+ case EVENT_FROSTMOURNE_HEROIC:
+ if (TempSummon* terenas = me->GetMap()->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE_H, TerenasSpawnHeroic, nullptr, 50000))
+ {
+ terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO);
+ std::list<Creature*> triggers;
+ GetCreatureListWithEntryInGrid(triggers, terenas, NPC_WORLD_TRIGGER_INFINITE_AOI, 100.0f);
+ if (!triggers.empty())
+ {
+ triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, true));
+ Creature* spawner = triggers.front();
+ spawner->setActive(true);
+ spawner->SetFarVisible(true);
+ spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true); // summons bombs randomly
+ spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players
+ spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3s));
+ }
+ }
+ break;
+ case EVENT_OUTRO_TALK_1:
+ Talk(SAY_LK_OUTRO_1);
+ DoCastAOE(SPELL_FURY_OF_FROSTMOURNE_NO_REZ, true);
+ break;
+ case EVENT_OUTRO_TALK_2:
+ Talk(SAY_LK_OUTRO_2);
+ DoCastAOE(SPELL_EMOTE_QUESTION_NO_SHEATH);
+ break;
+ case EVENT_OUTRO_EMOTE_TALK:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
+ break;
+ case EVENT_OUTRO_TALK_3:
+ if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ me->SetFacingToObject(tirion);
+ Talk(SAY_LK_OUTRO_3);
+ break;
+ case EVENT_OUTRO_MOVE_CENTER:
+ me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_1, CenterPosition);
+ break;
+ case EVENT_OUTRO_TALK_4:
+ me->SetFacingTo(0.01745329f);
+ Talk(SAY_LK_OUTRO_4);
+ break;
+ case EVENT_OUTRO_RAISE_DEAD:
+ DoCastAOE(SPELL_RAISE_DEAD);
+ me->ClearUnitState(UNIT_STATE_CASTING);
+ me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_FINAL);
+ break;
+ case EVENT_OUTRO_TALK_5:
+ Talk(SAY_LK_OUTRO_5);
+ if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ tirion->AI()->DoAction(ACTION_OUTRO);
+ break;
+ case EVENT_OUTRO_TALK_6:
+ Talk(SAY_LK_OUTRO_6);
+ if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ tirion->SetFacingToObject(me);
+ me->CastSpell(nullptr, SPELL_SUMMON_BROKEN_FROSTMOURNE_3, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
+ SetEquipmentSlots(false, EQUIP_UNEQUIP);
+ break;
+ case EVENT_OUTRO_SOUL_BARRAGE:
+ me->CastSpell(nullptr, SPELL_SOUL_BARRAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
+ CreatureTextMgr::SendSound(me, SOUND_PAIN, CHAT_MSG_MONSTER_YELL, 0, TEXT_RANGE_NORMAL, TEAM_OTHER, false);
+ // set flight
+ me->SetDisableGravity(true);
+ me->SetAnimTier(UnitBytes1_Flags(UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER), false);
+ me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_2, OutroFlying);
+ break;
+ case EVENT_OUTRO_TALK_7:
+ Talk(SAY_LK_OUTRO_7);
+ break;
+ case EVENT_OUTRO_TALK_8:
+ Talk(SAY_LK_OUTRO_8);
+ break;
+ case EVENT_BERSERK:
+ Talk(SAY_LK_BERSERK);
+ DoCastSelf(SPELL_BERSERK2);
+ break;
+ default:
+ break;
}
- private:
- uint32 _necroticPlagueStack;
- uint32 _vileSpiritExplosions;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<boss_the_lich_kingAI>(creature);
+ if (me->HasUnitState(UNIT_STATE_CASTING) && !(events.IsInPhase(PHASE_TRANSITION) || events.IsInPhase(PHASE_OUTRO) || events.IsInPhase(PHASE_FROSTMOURNE)))
+ return;
}
-};
-class npc_tirion_fordring_tft : public CreatureScript
-{
- public:
- npc_tirion_fordring_tft() : CreatureScript("npc_tirion_fordring_tft") { }
+ DoMeleeAttackIfReady();
+ }
- struct npc_tirion_fordringAI : public ScriptedAI
- {
- npc_tirion_fordringAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- }
+private:
+ uint32 _necroticPlagueStack;
+ uint32 _vileSpiritExplosions;
+};
- void Reset() override
- {
- _events.Reset();
- if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE)
- me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
- me->LoadEquipment(1);
- }
+struct npc_tirion_fordring_tft : public ScriptedAI
+{
+ npc_tirion_fordring_tft(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
- void MovementInform(uint32 type, uint32 id) override
- {
- if (type != POINT_MOTION_TYPE)
- return;
+ void Reset() override
+ {
+ _events.Reset();
+ if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE)
+ me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
+ }
- switch (id)
- {
- case POINT_TIRION_INTRO:
- me->SetEmoteState(EMOTE_STATE_READY2H);
- if (Creature* theLichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- theLichKing->AI()->DoAction(ACTION_START_ENCOUNTER);
- break;
- case POINT_TIRION_OUTRO_1:
- _events.ScheduleEvent(EVENT_OUTRO_JUMP, 1ms, 0, PHASE_OUTRO);
- break;
- }
- }
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ switch (id)
+ {
+ case POINT_TIRION_INTRO:
+ me->SetEmoteState(EMOTE_STATE_READY2H);
+ if (Creature* theLichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ theLichKing->AI()->DoAction(ACTION_START_ENCOUNTER);
+ break;
+ case POINT_TIRION_OUTRO_1:
+ _events.ScheduleEvent(EVENT_OUTRO_JUMP, 1ms, 0, PHASE_OUTRO);
+ break;
+ }
+ }
- void DoAction(int32 action) override
- {
- switch (action)
- {
- case ACTION_CONTINUE_INTRO:
- Talk(SAY_TIRION_INTRO_1);
- _events.ScheduleEvent(EVENT_INTRO_TALK_1, 34s, 0, PHASE_INTRO);
- break;
- case ACTION_OUTRO:
- _events.SetPhase(PHASE_OUTRO);
- _events.ScheduleEvent(EVENT_OUTRO_TALK_1, 7s, 0, PHASE_OUTRO);
- _events.ScheduleEvent(EVENT_OUTRO_BLESS, 18s, 0, PHASE_OUTRO);
- _events.ScheduleEvent(EVENT_OUTRO_REMOVE_ICE, 23s, 0, PHASE_OUTRO);
- _events.ScheduleEvent(EVENT_OUTRO_MOVE_1, 25s, 0, PHASE_OUTRO);
- break;
- }
- }
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_CONTINUE_INTRO:
+ Talk(SAY_TIRION_INTRO_1);
+ _events.ScheduleEvent(EVENT_INTRO_TALK_1, 34s, 0, PHASE_INTRO);
+ break;
+ case ACTION_OUTRO:
+ _events.SetPhase(PHASE_OUTRO);
+ _events.ScheduleEvent(EVENT_OUTRO_TALK_1, 7s, 0, PHASE_OUTRO);
+ _events.ScheduleEvent(EVENT_OUTRO_BLESS, 18s, 0, PHASE_OUTRO);
+ _events.ScheduleEvent(EVENT_OUTRO_REMOVE_ICE, 23s, 0, PHASE_OUTRO);
+ _events.ScheduleEvent(EVENT_OUTRO_MOVE_1, 25s, 0, PHASE_OUTRO);
+ break;
+ }
+ }
- void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
- {
- if (spellInfo->Id == SPELL_ICE_LOCK)
- me->SetFacingTo(3.085098f);
- else if (spellInfo->Id == SPELL_BROKEN_FROSTMOURNE_KNOCK)
- me->LoadEquipment(1); // remove glow on ashbringer
- }
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_ICE_LOCK)
+ me->SetFacingTo(3.085098f);
+ else if (spellInfo->Id == SPELL_BROKEN_FROSTMOURNE_KNOCK)
+ me->LoadEquipment(1); // remove glow on ashbringer
+ }
- bool GossipSelect(Player* /*player*/, uint32 menuId, uint32 gossipListId) override
- {
- if (me->GetCreatureTemplate()->GossipMenuId == menuId && !gossipListId)
- {
- _events.SetPhase(PHASE_INTRO);
- me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
- me->SetWalk(true);
- me->GetMotionMaster()->MovePoint(POINT_TIRION_INTRO, TirionIntro);
- }
- return false;
- }
+ bool GossipSelect(Player* /*player*/, uint32 menuId, uint32 gossipListId) override
+ {
+ if (me->GetCreatureTemplate()->GossipMenuId == menuId && !gossipListId)
+ {
+ _events.SetPhase(PHASE_INTRO);
+ me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(POINT_TIRION_INTRO, TirionIntro);
+ }
+ return false;
+ }
- void JustReachedHome() override
- {
- me->SetEmoteState(EMOTE_ONESHOT_NONE);
- }
+ void JustReachedHome() override
+ {
+ me->SetEmoteState(EMOTE_ONESHOT_NONE);
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim() && !(_events.IsInPhase(PHASE_OUTRO) || _events.IsInPhase(PHASE_INTRO)))
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim() && !(_events.IsInPhase(PHASE_OUTRO) || _events.IsInPhase(PHASE_INTRO)))
+ 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())
- {
- switch (eventId)
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_INTRO_TALK_1:
+ Talk(SAY_TIRION_INTRO_2);
+ _events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 2s, 0, PHASE_INTRO);
+ _events.ScheduleEvent(EVENT_INTRO_CHARGE, 5s, 0, PHASE_INTRO);
+ break;
+ case EVENT_INTRO_EMOTE_1:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NO_SHEATHE);
+ break;
+ case EVENT_INTRO_CHARGE:
+ me->SetWalk(false);
+ me->GetMotionMaster()->MovePoint(POINT_TIRION_CHARGE, TirionCharge);
+ break;
+ case EVENT_OUTRO_TALK_1:
+ Talk(SAY_TIRION_OUTRO_1);
+ break;
+ case EVENT_OUTRO_BLESS:
+ DoCastSelf(SPELL_LIGHTS_BLESSING);
+ break;
+ case EVENT_OUTRO_REMOVE_ICE:
+ me->RemoveAurasDueToSpell(SPELL_ICE_LOCK);
+ SetEquipmentSlots(false, EQUIP_ASHBRINGER_GLOWING);
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
{
- case EVENT_INTRO_TALK_1:
- Talk(SAY_TIRION_INTRO_2);
- _events.ScheduleEvent(EVENT_INTRO_EMOTE_1, 2s, 0, PHASE_INTRO);
- _events.ScheduleEvent(EVENT_INTRO_CHARGE, 5s, 0, PHASE_INTRO);
- break;
- case EVENT_INTRO_EMOTE_1:
- me->HandleEmoteCommand(EMOTE_ONESHOT_POINT_NO_SHEATHE);
- break;
- case EVENT_INTRO_CHARGE:
- me->SetWalk(false);
- me->GetMotionMaster()->MovePoint(POINT_TIRION_CHARGE, TirionCharge);
- break;
- case EVENT_OUTRO_TALK_1:
- Talk(SAY_TIRION_OUTRO_1);
- break;
- case EVENT_OUTRO_BLESS:
- DoCast(me, SPELL_LIGHTS_BLESSING);
- break;
- case EVENT_OUTRO_REMOVE_ICE:
- me->RemoveAurasDueToSpell(SPELL_ICE_LOCK);
- SetEquipmentSlots(false, EQUIP_ASHBRINGER_GLOWING);
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- {
- me->SetFacingToObject(lichKing);
- lichKing->AI()->DoAction(ACTION_PLAY_MUSIC);
- }
- break;
- case EVENT_OUTRO_MOVE_1:
- me->GetMotionMaster()->MovePoint(POINT_TIRION_OUTRO_1, OutroPosition1);
- break;
- case EVENT_OUTRO_JUMP:
- DoCastAOE(SPELL_JUMP);
- break;
- default:
- break;
+ me->SetFacingToObject(lichKing);
+ lichKing->AI()->DoAction(ACTION_PLAY_MUSIC);
}
- }
-
- DoMeleeAttackIfReady();
+ break;
+ case EVENT_OUTRO_MOVE_1:
+ me->GetMotionMaster()->MovePoint(POINT_TIRION_OUTRO_1, OutroPosition1);
+ break;
+ case EVENT_OUTRO_JUMP:
+ DoCastAOE(SPELL_JUMP);
+ break;
+ default:
+ break;
}
+ }
- private:
- EventMap _events;
- InstanceScript* _instance;
- };
+ DoMeleeAttackIfReady();
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_tirion_fordringAI>(creature);
- }
+private:
+ EventMap _events;
+ InstanceScript* _instance;
};
-class npc_shambling_horror_icc : public CreatureScript
+struct npc_shambling_horror_icc : public ScriptedAI
{
- public:
- npc_shambling_horror_icc() : CreatureScript("npc_shambling_horror_icc") { }
-
- struct npc_shambling_horror_iccAI : public ScriptedAI
- {
- npc_shambling_horror_iccAI(Creature* creature) : ScriptedAI(creature)
- {
- _frenzied = false;
- }
-
- void Reset() override
- {
- _events.Reset();
- _events.ScheduleEvent(EVENT_SHOCKWAVE, 20s, 25s);
- _events.ScheduleEvent(EVENT_ENRAGE, 11s, 14s);
- }
+ npc_shambling_horror_icc(Creature* creature) : ScriptedAI(creature)
+ {
+ _frenzied = false;
+ }
- void DamageTaken(Unit* /*attacker*/, uint32& damage) override
- {
- if (!_frenzied && IsHeroic() && me->HealthBelowPctDamaged(20, damage))
- {
- _frenzied = true;
- DoCast(me, SPELL_FRENZY, true);
- }
- }
+ void Reset() override
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_SHOCKWAVE, 20s, 25s);
+ _events.ScheduleEvent(EVENT_ENRAGE, 11s, 14s);
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (!_frenzied && IsHeroic() && me->HealthBelowPctDamaged(20, damage))
+ {
+ _frenzied = true;
+ DoCastSelf(SPELL_FRENZY, true);
+ }
+ }
- _events.Update(diff);
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ _events.Update(diff);
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SHOCKWAVE:
- DoCast(me, SPELL_SHOCKWAVE);
- _events.ScheduleEvent(EVENT_SHOCKWAVE, 20s, 25s);
- break;
- case EVENT_ENRAGE:
- if (SPELL_CAST_OK != DoCast(me, SPELL_ENRAGE))
- _events.ScheduleEvent(EVENT_ENRAGE, 1s);
- else
- _events.ScheduleEvent(EVENT_ENRAGE, 20s, 25s);
- break;
- default:
- break;
- }
- }
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- DoMeleeAttackIfReady();
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SHOCKWAVE:
+ DoCastSelf(SPELL_SHOCKWAVE);
+ _events.ScheduleEvent(EVENT_SHOCKWAVE, 20s, 25s);
+ break;
+ case EVENT_ENRAGE:
+ if (SPELL_CAST_OK != DoCastSelf(SPELL_ENRAGE))
+ _events.ScheduleEvent(EVENT_ENRAGE, 1s);
+ else
+ _events.ScheduleEvent(EVENT_ENRAGE, 20s, 25s);
+ break;
+ default:
+ break;
}
+ }
- void OnSpellCastInterrupt(SpellInfo const* spell) override
- {
- ScriptedAI::OnSpellCastInterrupt(spell);
+ DoMeleeAttackIfReady();
+ }
- // When enrage is interrupted, reschedule the event
- if (spell->Id == ENRAGE)
- _events.RescheduleEvent(EVENT_ENRAGE, 1s);
- }
+ void OnSpellCastInterrupt(SpellInfo const* spell) override
+ {
+ ScriptedAI::OnSpellCastInterrupt(spell);
- private:
- EventMap _events;
- bool _frenzied;
- };
+ // When enrage is interrupted, reschedule the event
+ if (spell->Id == ENRAGE)
+ _events.RescheduleEvent(EVENT_ENRAGE, 1s);
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_shambling_horror_iccAI>(creature);
- }
+private:
+ EventMap _events;
+ bool _frenzied;
};
-class npc_raging_spirit : public CreatureScript
+struct npc_raging_spirit : public ScriptedAI
{
- public:
- npc_raging_spirit() : CreatureScript("npc_raging_spirit") { }
-
- struct npc_raging_spiritAI : public ScriptedAI
- {
- npc_raging_spiritAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- }
+ npc_raging_spirit(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
- void Reset() override
- {
- me->SetReactState(REACT_PASSIVE);
- _events.Reset();
- _events.ScheduleEvent(EVENT_SET_AGRESSIVE, 2s);
- _events.ScheduleEvent(EVENT_SOUL_SHRIEK, 12s, 15s);
- DoCast(me, SPELL_PLAGUE_AVOIDANCE, true);
- DoCast(me, SPELL_RAGING_SPIRIT_VISUAL, true);
- if (TempSummon* summon = me->ToTempSummon())
- if (Unit* summoner = summon->GetSummonerUnit())
- summoner->CastSpell(me, SPELL_RAGING_SPIRIT_VISUAL_CLONE, true);
- DoCast(me, SPELL_BOSS_HITTIN_YA, true);
- }
+ void Reset() override
+ {
+ me->SetReactState(REACT_PASSIVE);
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_SET_AGRESSIVE, 2s);
+ _events.ScheduleEvent(EVENT_SOUL_SHRIEK, 12s, 15s);
+ DoCastSelf(SPELL_PLAGUE_AVOIDANCE, true);
+ DoCastSelf(SPELL_RAGING_SPIRIT_VISUAL, true);
+ if (TempSummon* summon = me->ToTempSummon())
+ if (Unit* summoner = summon->GetSummonerUnit())
+ summoner->CastSpell(me, SPELL_RAGING_SPIRIT_VISUAL_CLONE, true);
+ DoCastSelf(SPELL_BOSS_HITTIN_YA, true);
+ }
- void DoAction(int32 action) override
- {
- if (action == ACTION_DISABLE_RAGING)
- {
- _events.Reset();
- _events.SetPhase(PHASE_FROSTMOURNE);
- _events.ScheduleEvent(EVENT_SET_AGRESSIVE, 52s);
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
- me->InterruptNonMeleeSpells(true);
- }
- }
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_DISABLE_RAGING)
+ {
+ _events.Reset();
+ _events.SetPhase(PHASE_FROSTMOURNE);
+ _events.ScheduleEvent(EVENT_SET_AGRESSIVE, 52s);
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ me->InterruptNonMeleeSpells(true);
+ }
+ }
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- // player is the spellcaster so register summon manually
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- lichKing->AI()->JustSummoned(me);
- }
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ // player is the spellcaster so register summon manually
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ lichKing->AI()->JustSummoned(me);
+ }
- void JustDied(Unit* /*killer*/) override
- {
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- lichKing->AI()->SummonedCreatureDespawn(me);
- if (TempSummon* summon = me->ToTempSummon())
- summon->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ lichKing->AI()->SummonedCreatureDespawn(me);
+ if (TempSummon* summon = me->ToTempSummon())
+ summon->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!_events.IsInPhase(PHASE_FROSTMOURNE) && !UpdateVictim())
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ if (!_events.IsInPhase(PHASE_FROSTMOURNE) && !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())
- {
- switch (eventId)
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SOUL_SHRIEK:
+ DoCastAOE(SPELL_SOUL_SHRIEK);
+ _events.ScheduleEvent(EVENT_SOUL_SHRIEK, 12s, 15s);
+ break;
+ case EVENT_SET_AGRESSIVE:
+ me->SetReactState(REACT_AGGRESSIVE);
+ if (_events.IsInPhase(PHASE_FROSTMOURNE))
{
- case EVENT_SOUL_SHRIEK:
- DoCastAOE(SPELL_SOUL_SHRIEK);
- _events.ScheduleEvent(EVENT_SOUL_SHRIEK, 12s, 15s);
- break;
- case EVENT_SET_AGRESSIVE:
- me->SetReactState(REACT_AGGRESSIVE);
- if (_events.IsInPhase(PHASE_FROSTMOURNE))
- {
- _events.SetPhase(PHASE_THREE);
- _events.ScheduleEvent(EVENT_SOUL_SHRIEK, 12s, 15s);
- }
- break;
- default:
- break;
+ _events.SetPhase(PHASE_THREE);
+ _events.ScheduleEvent(EVENT_SOUL_SHRIEK, 12s, 15s);
}
- }
-
- DoMeleeAttackIfReady();
+ break;
+ default:
+ break;
}
+ }
- private:
- EventMap _events;
- InstanceScript* _instance;
- };
+ DoMeleeAttackIfReady();
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_raging_spiritAI>(creature);
- }
+private:
+ EventMap _events;
+ InstanceScript* _instance;
};
-class npc_valkyr_shadowguard : public CreatureScript
+struct npc_valkyr_shadowguard : public ScriptedAI
{
- public:
- npc_valkyr_shadowguard() : CreatureScript("npc_valkyr_shadowguard") { }
-
- struct npc_valkyr_shadowguardAI : public ScriptedAI
- {
- npc_valkyr_shadowguardAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- }
+ npc_valkyr_shadowguard(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
- void Reset() override
- {
- _events.Reset();
- me->SetReactState(REACT_PASSIVE);
- DoCast(me, SPELL_WINGS_OF_THE_DAMNED, false);
- }
+ void Reset() override
+ {
+ _events.Reset();
+ me->SetReactState(REACT_PASSIVE);
+ DoCastSelf(SPELL_WINGS_OF_THE_DAMNED, false);
+ }
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- _events.Reset();
- _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2500ms);
- }
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2500ms);
+ }
- void DamageTaken(Unit* /*attacker*/, uint32& damage) override
- {
- if (!IsHeroic())
- return;
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (!IsHeroic())
+ return;
- if (!me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
- return;
+ if (!me->HasAuraType(SPELL_AURA_CONTROL_VEHICLE))
+ return;
- if (me->HealthBelowPctDamaged(50, damage))
- {
- DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
- ScheduleHeroicEvents();
- }
- }
+ if (me->HealthBelowPctDamaged(50, damage))
+ {
+ DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
+ ScheduleHeroicEvents();
+ }
+ }
- void ScheduleHeroicEvents()
- {
- _events.Reset();
- _events.ScheduleEvent(EVENT_MOVE_TO_CENTER, 1ms);
- me->ClearUnitState(UNIT_STATE_EVADE);
- }
+ void ScheduleHeroicEvents()
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_MOVE_TO_CENTER, 1ms);
+ me->ClearUnitState(UNIT_STATE_EVADE);
+ }
- void AttackStart(Unit* /*target*/) override
- {
- }
+ void AttackStart(Unit* /*target*/) override
+ {
+ }
- void MovementInform(uint32 type, uint32 id) override
- {
- if (type != POINT_MOTION_TYPE)
- return;
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
- switch (id)
+ switch (id)
+ {
+ case POINT_DROP_PLAYER:
+ DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
+ if (IsHeroic())
+ ScheduleHeroicEvents();
+ else
+ me->DespawnOrUnsummon(1s);
+ break;
+ case POINT_CHARGE:
+ if (Player* target = ObjectAccessor::GetPlayer(*me, _grabbedPlayer))
{
- case POINT_DROP_PLAYER:
- DoCastAOE(SPELL_EJECT_ALL_PASSENGERS);
- if (IsHeroic())
- ScheduleHeroicEvents();
- else
- me->DespawnOrUnsummon(1s);
- break;
- case POINT_CHARGE:
- if (Player* target = ObjectAccessor::GetPlayer(*me, _grabbedPlayer))
- {
- me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- if (GameObject* platform = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(DATA_ARTHAS_PLATFORM)))
- {
- std::list<Creature*> triggers;
- GetCreatureListWithEntryInGrid(triggers, me, NPC_WORLD_TRIGGER, 150.0f);
- triggers.remove_if(Trinity::HeightDifferenceCheck(platform, 5.0f, true));
- if (triggers.empty())
- return;
-
- triggers.sort(Trinity::ObjectDistanceOrderPred(me));
- DoCast(target, SPELL_VALKYR_CARRY);
- _dropPoint.Relocate(triggers.front());
- _events.ScheduleEvent(EVENT_MOVE_TO_DROP_POS, 1500ms);
- }
- }
- else
- me->DespawnOrUnsummon();
- break;
- case POINT_SIPHON:
- DoZoneInCombat();
- _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2s);
- break;
- default:
- break;
+ me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
+ if (GameObject* platform = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(DATA_ARTHAS_PLATFORM)))
+ {
+ std::list<Creature*> triggers;
+ GetCreatureListWithEntryInGrid(triggers, me, NPC_WORLD_TRIGGER, 150.0f);
+ triggers.remove_if(Trinity::HeightDifferenceCheck(platform, 5.0f, true));
+ if (triggers.empty())
+ return;
+
+ triggers.sort(Trinity::ObjectDistanceOrderPred(me));
+ DoCast(target, SPELL_VALKYR_CARRY);
+ _dropPoint.Relocate(triggers.front());
+ _events.ScheduleEvent(EVENT_MOVE_TO_DROP_POS, 1500ms);
+ }
}
- }
+ else
+ me->DespawnOrUnsummon();
+ break;
+ case POINT_SIPHON:
+ DoZoneInCombat();
+ _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2s);
+ break;
+ default:
+ break;
+ }
+ }
- void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
- {
- _grabbedPlayer = guid;
- }
+ void SetGUID(ObjectGuid const& guid, int32 /*id*/) override
+ {
+ _grabbedPlayer = guid;
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ 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())
- {
- switch (eventId)
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_GRAB_PLAYER:
+ if (!_grabbedPlayer)
{
- case EVENT_GRAB_PLAYER:
- if (!_grabbedPlayer)
- {
- DoCastAOE(SPELL_VALKYR_TARGET_SEARCH);
- _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2s);
- }
- break;
- case EVENT_MOVE_TO_DROP_POS:
- me->GetMotionMaster()->MovePoint(POINT_DROP_PLAYER, _dropPoint);
- break;
- case EVENT_LIFE_SIPHON:
- if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
- DoCast(target, SPELL_LIFE_SIPHON);
- _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2500ms);
- break;
- case EVENT_MOVE_TO_CENTER:
- {
- Position pos = me->GetRandomPoint(CenterPosition, 4.0f);
- pos.m_positionZ = me->GetHomePosition().m_positionZ;
- me->GetMotionMaster()->MovePoint(POINT_SIPHON, pos);
- break;
- }
- default:
- break;
+ DoCastAOE(SPELL_VALKYR_TARGET_SEARCH);
+ _events.ScheduleEvent(EVENT_GRAB_PLAYER, 2s);
}
+ break;
+ case EVENT_MOVE_TO_DROP_POS:
+ me->GetMotionMaster()->MovePoint(POINT_DROP_PLAYER, _dropPoint);
+ break;
+ case EVENT_LIFE_SIPHON:
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
+ DoCast(target, SPELL_LIFE_SIPHON);
+ _events.ScheduleEvent(EVENT_LIFE_SIPHON, 2500ms);
+ break;
+ case EVENT_MOVE_TO_CENTER:
+ {
+ Position pos = me->GetRandomPoint(CenterPosition, 4.0f);
+ pos.m_positionZ = me->GetHomePosition().m_positionZ;
+ me->GetMotionMaster()->MovePoint(POINT_SIPHON, pos);
+ break;
}
-
- // no melee attacks
+ default:
+ break;
}
+ }
- private:
- EventMap _events;
- Position _dropPoint;
- ObjectGuid _grabbedPlayer;
- InstanceScript* _instance;
- };
+ // no melee attacks
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_valkyr_shadowguardAI>(creature);
- }
+private:
+ EventMap _events;
+ Position _dropPoint;
+ ObjectGuid _grabbedPlayer;
+ InstanceScript* _instance;
};
-class npc_strangulate_vehicle : public CreatureScript
+struct npc_strangulate_vehicle : public ScriptedAI
{
- public:
- npc_strangulate_vehicle() : CreatureScript("npc_strangulate_vehicle") { }
+ npc_strangulate_vehicle(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
- struct npc_strangulate_vehicleAI : public ScriptedAI
- {
- npc_strangulate_vehicleAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- }
+ void IsSummonedBy(WorldObject* summonerWO) override
+ {
+ Unit* summoner = summonerWO->ToUnit();
+ if (!summoner)
+ return;
+ me->SetFacingToObject(summoner);
+ DoCast(summoner, SPELL_HARVEST_SOUL_VEHICLE);
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_MOVE_TO_LICH_KING, 2s);
+ _events.ScheduleEvent(EVENT_TELEPORT, 6s);
+
+ // this will let us easily access all creatures of this entry on heroic mode when its time to teleport back
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ lichKing->AI()->JustSummoned(me);
+ }
- void IsSummonedBy(WorldObject* summonerWO) override
- {
- Unit* summoner = summonerWO->ToUnit();
- if (!summoner)
- return;
- me->SetFacingToObject(summoner);
- DoCast(summoner, SPELL_HARVEST_SOUL_VEHICLE);
- _events.Reset();
- _events.ScheduleEvent(EVENT_MOVE_TO_LICH_KING, 2s);
- _events.ScheduleEvent(EVENT_TELEPORT, 6s);
+ void DoAction(int32 action) override
+ {
+ if (action != ACTION_TELEPORT_BACK)
+ return;
- // this will let us easily access all creatures of this entry on heroic mode when its time to teleport back
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- lichKing->AI()->JustSummoned(me);
+ if (TempSummon* summ = me->ToTempSummon())
+ {
+ if (Unit* summoner = summ->GetSummonerUnit())
+ {
+ DoCast(summoner, SPELL_HARVEST_SOUL_TELEPORT_BACK);
+ summoner->RemoveAurasDueToSpell(SPELL_HARVEST_SOULS_TELEPORT);
}
+ }
- void DoAction(int32 action) override
- {
- if (action != ACTION_TELEPORT_BACK)
- return;
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ lichKing->AI()->SummonedCreatureDespawn(me);
+ me->DespawnOrUnsummon();
+ }
- if (TempSummon* summ = me->ToTempSummon())
- {
- if (Unit* summoner = summ->GetSummonerUnit())
- {
- DoCast(summoner, SPELL_HARVEST_SOUL_TELEPORT_BACK);
- summoner->RemoveAurasDueToSpell(SPELL_HARVEST_SOULS_TELEPORT);
- }
- }
+ void UpdateAI(uint32 diff) override
+ {
+ UpdateVictim();
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- lichKing->AI()->SummonedCreatureDespawn(me);
- me->DespawnOrUnsummon();
- }
+ _events.Update(diff);
- void UpdateAI(uint32 diff) override
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
{
- UpdateVictim();
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
+ case EVENT_TELEPORT:
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveIdle();
+ if (TempSummon* summ = me->ToTempSummon())
{
- case EVENT_TELEPORT:
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveIdle();
- if (TempSummon* summ = me->ToTempSummon())
+ if (Unit* summoner = summ->GetSummonerUnit())
+ {
+ summoner->CastSpell(nullptr, SPELL_HARVEST_SOUL_VISUAL, true);
+ summoner->ExitVehicle(summoner);
+ if (!IsHeroic())
+ summoner->CastSpell(summoner, SPELL_HARVEST_SOUL_TELEPORT, true);
+ else
{
- if (Unit* summoner = summ->GetSummonerUnit())
- {
- summoner->CastSpell(nullptr, SPELL_HARVEST_SOUL_VISUAL, true);
- summoner->ExitVehicle(summoner);
- if (!IsHeroic())
- summoner->CastSpell(summoner, SPELL_HARVEST_SOUL_TELEPORT, true);
- else
- {
- summoner->CastSpell(summoner, SPELL_HARVEST_SOULS_TELEPORT, true);
- summoner->RemoveAurasDueToSpell(HARVEST_SOUL, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
- }
- }
+ summoner->CastSpell(summoner, SPELL_HARVEST_SOULS_TELEPORT, true);
+ summoner->RemoveAurasDueToSpell(HARVEST_SOUL, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
}
+ }
+ }
- _events.ScheduleEvent(EVENT_DESPAWN_SELF, 65s);
- break;
- case EVENT_MOVE_TO_LICH_KING:
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- {
- if (me->GetExactDist(lichKing) > 10.0f)
- {
- Position pos = lichKing->GetNearPosition(float(rand_norm()) * 5.0f + 7.5f, lichKing->GetAbsoluteAngle(me));
- me->GetMotionMaster()->MovePoint(0, pos);
- }
- }
- break;
- case EVENT_DESPAWN_SELF:
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- lichKing->AI()->SummonedCreatureDespawn(me);
- me->DespawnOrUnsummon(1ms);
- break;
- default:
- break;
+ _events.ScheduleEvent(EVENT_DESPAWN_SELF, 65s);
+ break;
+ case EVENT_MOVE_TO_LICH_KING:
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ {
+ if (me->GetExactDist(lichKing) > 10.0f)
+ {
+ Position pos = lichKing->GetNearPosition(float(rand_norm()) * 5.0f + 7.5f, lichKing->GetAbsoluteAngle(me));
+ me->GetMotionMaster()->MovePoint(0, pos);
+ }
}
- }
+ break;
+ case EVENT_DESPAWN_SELF:
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ lichKing->AI()->SummonedCreatureDespawn(me);
+ me->DespawnOrUnsummon(1ms);
+ break;
+ default:
+ break;
}
-
- private:
- EventMap _events;
- InstanceScript* _instance;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_strangulate_vehicleAI>(creature);
}
+ }
+
+private:
+ EventMap _events;
+ InstanceScript* _instance;
};
-class npc_terenas_menethil : public CreatureScript
+struct npc_terenas_menethil : public ScriptedAI
{
- public:
- npc_terenas_menethil() : CreatureScript("npc_terenas_menethil") { }
+ npc_terenas_menethil(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
- struct npc_terenas_menethilAI : public ScriptedAI
- {
- npc_terenas_menethilAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- }
-
- bool CanAIAttack(Unit const* target) const override
- {
- return target->GetEntry() != NPC_THE_LICH_KING;
- }
+ bool CanAIAttack(Unit const* target) const override
+ {
+ return target->GetEntry() != NPC_THE_LICH_KING;
+ }
- void DoAction(int32 action) override
- {
- switch (action)
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_FROSTMOURNE_INTRO:
+ me->setActive(true);
+ me->SetFarVisible(false);
+ if (!IsHeroic())
+ me->SetHealth(me->GetMaxHealth() / 2);
+ DoCastSelf(SPELL_LIGHTS_FAVOR);
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_1, 2s, PHASE_FROSTMOURNE);
+ _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_2, 11s, PHASE_FROSTMOURNE);
+ if (!IsHeroic())
{
- case ACTION_FROSTMOURNE_INTRO:
- me->setActive(true);
- me->SetFarVisible(false);
- if (!IsHeroic())
- me->SetHealth(me->GetMaxHealth() / 2);
- DoCast(me, SPELL_LIGHTS_FAVOR);
- _events.Reset();
- _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_1, 2s, PHASE_FROSTMOURNE);
- _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_2, 11s, PHASE_FROSTMOURNE);
- if (!IsHeroic())
- {
- _events.ScheduleEvent(EVENT_DESTROY_SOUL, 1min, PHASE_FROSTMOURNE);
- _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_3, 25s);
- }
- break;
- case ACTION_TELEPORT_BACK:
- me->CastSpell(nullptr, SPELL_RESTORE_SOUL, TRIGGERED_NONE);
- me->DespawnOrUnsummon(3s);
- break;
- default:
- break;
+ _events.ScheduleEvent(EVENT_DESTROY_SOUL, 1min, PHASE_FROSTMOURNE);
+ _events.ScheduleEvent(EVENT_FROSTMOURNE_TALK_3, 25s);
}
- }
+ break;
+ case ACTION_TELEPORT_BACK:
+ me->CastSpell(nullptr, SPELL_RESTORE_SOUL, TRIGGERED_NONE);
+ me->DespawnOrUnsummon(3s);
+ break;
+ default:
+ break;
+ }
+ }
- void EnterEvadeMode(EvadeReason /*why*/) override
- {
- // no running back home
- if (!me->IsAlive())
- return;
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ // no running back home
+ if (!me->IsAlive())
+ return;
- me->CombatStop(false);
- EngagementOver();
- }
+ me->CombatStop(false);
+ EngagementOver();
+ }
- void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (damage >= me->GetHealth())
+ {
+ damage = me->GetHealth() - 1;
+ if (!me->HasAura(SPELL_TERENAS_LOSES_INSIDE) && !IsHeroic())
{
- if (damage >= me->GetHealth())
+ me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
+ DoCast(SPELL_TERENAS_LOSES_INSIDE);
+ _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1s);
+ if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f))
{
- damage = me->GetHealth() - 1;
- if (!me->HasAura(SPELL_TERENAS_LOSES_INSIDE) && !IsHeroic())
- {
- me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- DoCast(SPELL_TERENAS_LOSES_INSIDE);
- _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1s);
- if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f))
- {
- warden->CastSpell(nullptr, SPELL_DESTROY_SOUL, TRIGGERED_NONE);
- warden->DespawnOrUnsummon(2s);
- }
-
- me->DespawnOrUnsummon(2s);
- }
+ warden->CastSpell(nullptr, SPELL_DESTROY_SOUL, TRIGGERED_NONE);
+ warden->DespawnOrUnsummon(2s);
}
+
+ me->DespawnOrUnsummon(2s);
}
+ }
+ }
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- _events.Reset();
- _events.SetPhase(PHASE_OUTRO);
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- me->SetFacingToObject(lichKing);
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ _events.Reset();
+ _events.SetPhase(PHASE_OUTRO);
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ me->SetFacingToObject(lichKing);
- _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_1, 2s, 0, PHASE_OUTRO);
- _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_2, 14s, 0, PHASE_OUTRO);
- }
+ _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_1, 2s, 0, PHASE_OUTRO);
+ _events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_2, 14s, 0, PHASE_OUTRO);
+ }
- void UpdateAI(uint32 diff) override
- {
- UpdateVictim();
+ void UpdateAI(uint32 diff) override
+ {
+ UpdateVictim();
- _events.Update(diff);
+ _events.Update(diff);
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FROSTMOURNE_TALK_1:
+ Talk(SAY_TERENAS_INTRO_1);
+ if (IsHeroic())
+ DoCastAOE(SPELL_RESTORE_SOULS);
+ break;
+ case EVENT_FROSTMOURNE_TALK_2:
+ Talk(SAY_TERENAS_INTRO_2);
+ break;
+ case EVENT_FROSTMOURNE_TALK_3:
+ Talk(SAY_TERENAS_INTRO_3);
+ break;
+ case EVENT_OUTRO_TERENAS_TALK_1:
+ Talk(SAY_TERENAS_OUTRO_1);
+ break;
+ case EVENT_OUTRO_TERENAS_TALK_2:
+ Talk(SAY_TERENAS_OUTRO_2);
+ DoCastAOE(SPELL_MASS_RESURRECTION);
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
{
- case EVENT_FROSTMOURNE_TALK_1:
- Talk(SAY_TERENAS_INTRO_1);
- if (IsHeroic())
- DoCastAOE(SPELL_RESTORE_SOULS);
- break;
- case EVENT_FROSTMOURNE_TALK_2:
- Talk(SAY_TERENAS_INTRO_2);
- break;
- case EVENT_FROSTMOURNE_TALK_3:
- Talk(SAY_TERENAS_INTRO_3);
- break;
- case EVENT_OUTRO_TERENAS_TALK_1:
- Talk(SAY_TERENAS_OUTRO_1);
- break;
- case EVENT_OUTRO_TERENAS_TALK_2:
- Talk(SAY_TERENAS_OUTRO_2);
- DoCastAOE(SPELL_MASS_RESURRECTION);
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- {
- lichKing->AI()->DoAction(ACTION_FINISH_OUTRO);
- lichKing->SetImmuneToNPC(false);
- if (Creature* tirion = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
- tirion->AI()->AttackStart(lichKing);
- }
- break;
- case EVENT_DESTROY_SOUL:
- me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f))
- warden->CastSpell(nullptr, SPELL_DESTROY_SOUL, TRIGGERED_NONE);
- DoCast(SPELL_TERENAS_LOSES_INSIDE);
- _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1s);
- break;
- case EVENT_TELEPORT_BACK:
- if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
- lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
- break;
- default:
- break;
+ lichKing->AI()->DoAction(ACTION_FINISH_OUTRO);
+ lichKing->SetImmuneToNPC(false);
+ if (Creature* tirion = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HIGHLORD_TIRION_FORDRING)))
+ tirion->AI()->AttackStart(lichKing);
}
- }
-
- // fighting Spirit Warden
- if (me->IsInCombat())
- DoMeleeAttackIfReady();
+ break;
+ case EVENT_DESTROY_SOUL:
+ me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
+ if (Creature* warden = me->FindNearestCreature(NPC_SPIRIT_WARDEN, 20.0f))
+ warden->CastSpell(nullptr, SPELL_DESTROY_SOUL, TRIGGERED_NONE);
+ DoCast(SPELL_TERENAS_LOSES_INSIDE);
+ _events.ScheduleEvent(EVENT_TELEPORT_BACK, 1s);
+ break;
+ case EVENT_TELEPORT_BACK:
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_THE_LICH_KING)))
+ lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
+ break;
+ default:
+ break;
}
+ }
- private:
- EventMap _events;
- InstanceScript* _instance;
- };
+ // fighting Spirit Warden
+ if (me->IsInCombat())
+ DoMeleeAttackIfReady();
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_terenas_menethilAI>(creature);
- }
+private:
+ EventMap _events;
+ InstanceScript* _instance;
};
-class npc_spirit_warden : public CreatureScript
+struct npc_spirit_warden : public ScriptedAI
{
- public:
- npc_spirit_warden() : CreatureScript("npc_spirit_warden") { }
+ npc_spirit_warden(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
- struct npc_spirit_wardenAI : public ScriptedAI
- {
- npc_spirit_wardenAI(Creature* creature) : ScriptedAI(creature),
- _instance(creature->GetInstanceScript())
- {
- }
-
- void Reset() override
- {
- _events.Reset();
- _events.ScheduleEvent(EVENT_SOUL_RIP, 12s, 15s);
- DoCast(SPELL_DARK_HUNGER);
- }
+ void Reset() override
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_SOUL_RIP, 12s, 15s);
+ DoCast(SPELL_DARK_HUNGER);
+ }
- void JustDied(Unit* /*killer*/) override
- {
- if (Creature* terenas = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_TERENAS_MENETHIL)))
- terenas->AI()->DoAction(ACTION_TELEPORT_BACK);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* terenas = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_TERENAS_MENETHIL)))
+ terenas->AI()->DoAction(ACTION_TELEPORT_BACK);
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- _events.Update(diff);
+ _events.Update(diff);
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SOUL_RIP:
- DoCastVictim(SPELL_SOUL_RIP);
- _events.ScheduleEvent(EVENT_SOUL_RIP, 23s, 27s);
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SOUL_RIP:
+ DoCastVictim(SPELL_SOUL_RIP);
+ _events.ScheduleEvent(EVENT_SOUL_RIP, 23s, 27s);
+ break;
+ default:
+ break;
}
+ }
- private:
- EventMap _events;
- InstanceScript* _instance;
- };
+ DoMeleeAttackIfReady();
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_spirit_wardenAI>(creature);
- }
+private:
+ EventMap _events;
+ InstanceScript* _instance;
};
-class npc_spirit_bomb : public CreatureScript
+struct npc_spirit_bomb : public CreatureAI
{
- public:
- npc_spirit_bomb() : CreatureScript("npc_spirit_bomb") { }
-
- struct npc_spirit_bombAI : public CreatureAI
- {
- npc_spirit_bombAI(Creature* creature) : CreatureAI(creature)
- {
- }
+ npc_spirit_bomb(Creature* creature) : CreatureAI(creature) { }
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- float destX, destY, destZ;
- me->GetPosition(destX, destY);
- destZ = 1055.0f; // approximation, gets more precise later
- me->UpdateGroundPositionZ(destX, destY, destZ);
- me->GetMotionMaster()->MovePoint(POINT_GROUND, destX, destY, destZ);
- }
-
- void MovementInform(uint32 type, uint32 point) override
- {
- if (type != POINT_MOTION_TYPE || point != POINT_GROUND)
- return;
-
- _events.ScheduleEvent(EVENT_BOMB_EXPLOSION, 3s);
- }
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ float destX, destY, destZ;
+ me->GetPosition(destX, destY);
+ destZ = 1055.0f; // approximation, gets more precise later
+ me->UpdateGroundPositionZ(destX, destY, destZ);
+ me->GetMotionMaster()->MovePoint(POINT_GROUND, destX, destY, destZ);
+ }
- void AttackStart(Unit* /*victim*/) override
- {
- }
+ void MovementInform(uint32 type, uint32 point) override
+ {
+ if (type != POINT_MOTION_TYPE || point != POINT_GROUND)
+ return;
- void UpdateAI(uint32 diff) override
- {
- UpdateVictim();
+ _events.ScheduleEvent(EVENT_BOMB_EXPLOSION, 3s);
+ }
- _events.Update(diff);
+ void AttackStart(Unit* /*victim*/) override
+ {
+ }
- if (_events.ExecuteEvent() == EVENT_BOMB_EXPLOSION)
- {
- me->RemoveAllAuras();
- DoCastAOE(SPELL_EXPLOSION);
- me->DespawnOrUnsummon(1s);
- }
- }
+ void UpdateAI(uint32 diff) override
+ {
+ UpdateVictim();
- private:
- EventMap _events;
- };
+ _events.Update(diff);
- CreatureAI* GetAI(Creature* creature) const override
+ if (_events.ExecuteEvent() == EVENT_BOMB_EXPLOSION)
{
- return GetIcecrownCitadelAI<npc_spirit_bombAI>(creature);
+ me->RemoveAllAuras();
+ DoCastAOE(SPELL_EXPLOSION);
+ me->DespawnOrUnsummon(1s);
}
+ }
+
+private:
+ EventMap _events;
};
-class npc_broken_frostmourne : public CreatureScript
+struct npc_broken_frostmourne : public CreatureAI
{
- public:
- npc_broken_frostmourne() : CreatureScript("npc_broken_frostmourne") { }
-
- struct npc_broken_frostmourneAI : public CreatureAI
- {
- npc_broken_frostmourneAI(Creature* creature) : CreatureAI(creature)
- {
- }
+ npc_broken_frostmourne(Creature* creature) : CreatureAI(creature) { }
- void Reset() override
- {
- _events.Reset();
- }
-
- void IsSummonedBy(WorldObject* /*summoner*/) override
- {
- _events.SetPhase(PHASE_OUTRO);
- _events.ScheduleEvent(EVENT_OUTRO_KNOCK_BACK, 3s, 0, PHASE_OUTRO);
- }
+ void Reset() override
+ {
+ _events.Reset();
+ }
- void DoAction(int32 action) override
- {
- if (action == ACTION_SUMMON_TERENAS)
- _events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6s, 0, PHASE_OUTRO);
- }
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ _events.SetPhase(PHASE_OUTRO);
+ _events.ScheduleEvent(EVENT_OUTRO_KNOCK_BACK, 3s, 0, PHASE_OUTRO);
+ }
- void EnterEvadeMode(EvadeReason /*why*/) override
- {
- }
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_SUMMON_TERENAS)
+ _events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6s, 0, PHASE_OUTRO);
+ }
- void UpdateAI(uint32 diff) override
- {
- UpdateVictim();
+ void EnterEvadeMode(EvadeReason /*why*/) override
+ {
+ }
- _events.Update(diff);
+ void UpdateAI(uint32 diff) override
+ {
+ UpdateVictim();
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_OUTRO_KNOCK_BACK:
- DoCastAOE(SPELL_BROKEN_FROSTMOURNE_KNOCK);
- break;
- case EVENT_OUTRO_SUMMON_TERENAS:
- DoCastAOE(SPELL_SUMMON_TERENAS);
- break;
- default:
- break;
- }
- }
+ _events.Update(diff);
- // no melee attacks
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_OUTRO_KNOCK_BACK:
+ DoCastAOE(SPELL_BROKEN_FROSTMOURNE_KNOCK);
+ break;
+ case EVENT_OUTRO_SUMMON_TERENAS:
+ DoCastAOE(SPELL_SUMMON_TERENAS);
+ break;
+ default:
+ break;
}
+ }
- private:
- EventMap _events;
- };
+ // no melee attacks
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetIcecrownCitadelAI<npc_broken_frostmourneAI>(creature);
- }
+private:
+ EventMap _events;
};
-class spell_the_lich_king_infest : public SpellScriptLoader
+class spell_the_lich_king_infest : public AuraScript
{
- public:
- spell_the_lich_king_infest() : SpellScriptLoader("spell_the_lich_king_infest") { }
+ PrepareAuraScript(spell_the_lich_king_infest);
- class spell_the_lich_king_infest_AuraScript : public AuraScript
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ if (GetUnitOwner()->HealthAbovePct(90))
{
- PrepareAuraScript(spell_the_lich_king_infest_AuraScript);
-
- void OnPeriodic(AuraEffect const* /*aurEff*/)
- {
- if (GetUnitOwner()->HealthAbovePct(90))
- {
- PreventDefaultAction();
- Remove(AURA_REMOVE_BY_ENEMY_SPELL);
- }
- }
-
- void OnUpdate(AuraEffect* aurEff)
- {
- // multiply, starting from 2nd tick
- if (aurEff->GetTickNumber() == 1)
- return;
+ PreventDefaultAction();
+ Remove(AURA_REMOVE_BY_ENEMY_SPELL);
+ }
+ }
- aurEff->SetAmount(int32(aurEff->GetAmount() * 1.15f));
- }
+ void OnUpdate(AuraEffect* aurEff)
+ {
+ // multiply, starting from 2nd tick
+ if (aurEff->GetTickNumber() == 1)
+ return;
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_infest_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
- OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_the_lich_king_infest_AuraScript::OnUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
- }
- };
+ aurEff->SetAmount(int32(aurEff->GetAmount() * 1.15f));
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_infest_AuraScript();
- }
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_infest::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
+ OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_the_lich_king_infest::OnUpdate, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
+ }
};
-class spell_the_lich_king_necrotic_plague : public SpellScriptLoader
+class spell_the_lich_king_necrotic_plague : public AuraScript
{
- public:
- spell_the_lich_king_necrotic_plague() : SpellScriptLoader("spell_the_lich_king_necrotic_plague") { }
-
- class spell_the_lich_king_necrotic_plague_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_necrotic_plague_AuraScript);
-
- bool Validate(SpellInfo const* /*spell*/) override
- {
- return ValidateSpellInfo({ SPELL_NECROTIC_PLAGUE_JUMP });
- }
+ PrepareAuraScript(spell_the_lich_king_necrotic_plague);
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- switch (GetTargetApplication()->GetRemoveMode())
- {
- case AURA_REMOVE_BY_ENEMY_SPELL:
- case AURA_REMOVE_BY_EXPIRE:
- case AURA_REMOVE_BY_DEATH:
- break;
- default:
- return;
- }
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_NECROTIC_PLAGUE_JUMP });
+ }
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
- args.SetOriginalCaster(GetCasterGUID());
- args.AddSpellMod(SPELLVALUE_MAX_TARGETS, 1);
- GetTarget()->CastSpell(nullptr, SPELL_NECROTIC_PLAGUE_JUMP, args);
- if (Unit* caster = GetCaster())
- caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
- }
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ switch (GetTargetApplication()->GetRemoveMode())
+ {
+ case AURA_REMOVE_BY_ENEMY_SPELL:
+ case AURA_REMOVE_BY_EXPIRE:
+ case AURA_REMOVE_BY_DEATH:
+ break;
+ default:
+ return;
+ }
- void Register() override
- {
- AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
- }
- };
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SetOriginalCaster(GetCasterGUID());
+ args.AddSpellMod(SPELLVALUE_MAX_TARGETS, 1);
+ GetTarget()->CastSpell(nullptr, SPELL_NECROTIC_PLAGUE_JUMP, args);
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_necrotic_plague_AuraScript();
- }
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
+ }
};
-class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader
+class spell_the_lich_king_necrotic_plague_jump : public SpellScript
{
- public:
- spell_the_lich_king_necrotic_plague_jump() : SpellScriptLoader("spell_the_lich_king_necrotic_plague_jump") { }
+ PrepareSpellScript(spell_the_lich_king_necrotic_plague_jump);
- class spell_the_lich_king_necrotic_plague_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_necrotic_plague_SpellScript);
-
- public:
- spell_the_lich_king_necrotic_plague_SpellScript()
- {
- _hadAura = false;
- }
-
- private:
- void SelectTarget(std::list<WorldObject*>& targets)
- {
- targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
- if (targets.size() < 2)
- return;
-
- targets.resize(1);
- }
+public:
+ spell_the_lich_king_necrotic_plague_jump()
+ {
+ _hadAura = false;
+ }
- void CheckAura(SpellMissInfo missInfo)
- {
- if (missInfo != SPELL_MISS_NONE)
- return;
+private:
+ void SelectTarget(std::list<WorldObject*>& targets)
+ {
+ targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
+ if (targets.size() < 2)
+ return;
- if (GetHitUnit()->HasAura(GetSpellInfo()->Id))
- _hadAura = true;
- }
+ targets.resize(1);
+ }
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_necrotic_plague_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
- BeforeHit += BeforeSpellHitFn(spell_the_lich_king_necrotic_plague_SpellScript::CheckAura);
- }
+ void CheckAura(SpellMissInfo missInfo)
+ {
+ if (missInfo != SPELL_MISS_NONE)
+ return;
- bool _hadAura;
- };
+ if (GetHitUnit()->HasAura(GetSpellInfo()->Id))
+ _hadAura = true;
+ }
- class spell_the_lich_king_necrotic_plague_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_necrotic_plague_AuraScript);
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_necrotic_plague_jump::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ BeforeHit += BeforeSpellHitFn(spell_the_lich_king_necrotic_plague_jump::CheckAura);
+ }
- public:
- spell_the_lich_king_necrotic_plague_AuraScript()
- {
- _lastAmount = 0;
- }
+ bool _hadAura;
+};
- private:
- void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- if (Unit* caster = GetCaster())
- if (caster->GetAI())
- caster->GetAI()->SetData(DATA_PLAGUE_STACK, GetStackAmount());
- }
+class spell_the_lich_king_necrotic_plague_jump_aura : public AuraScript
+{
+ PrepareAuraScript(spell_the_lich_king_necrotic_plague_jump_aura);
- void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
- {
- _lastAmount = aurEff->GetAmount();
- switch (GetTargetApplication()->GetRemoveMode())
- {
- case AURA_REMOVE_BY_EXPIRE:
- case AURA_REMOVE_BY_DEATH:
- break;
- default:
- return;
- }
+public:
+ spell_the_lich_king_necrotic_plague_jump_aura()
+ {
+ _lastAmount = 0;
+ }
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
- args.SetOriginalCaster(GetCasterGUID());
- args.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount() + 1);
- GetTarget()->CastSpell(nullptr, SPELL_NECROTIC_PLAGUE_JUMP, args);
- if (Unit* caster = GetCaster())
- caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
- }
+private:
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (caster->GetAI())
+ caster->GetAI()->SetData(DATA_PLAGUE_STACK, GetStackAmount());
+ }
- void OnDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
- {
- _lastAmount = aurEff->GetAmount();
- }
+ void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ _lastAmount = aurEff->GetAmount();
+ switch (GetTargetApplication()->GetRemoveMode())
+ {
+ case AURA_REMOVE_BY_EXPIRE:
+ case AURA_REMOVE_BY_DEATH:
+ break;
+ default:
+ return;
+ }
- void AfterDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
- {
- // this means the stack increased so don't process as if dispelled
- if (aurEff->GetAmount() > _lastAmount)
- return;
-
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
- args.SetOriginalCaster(GetCasterGUID());
- args.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount());
- args.AddSpellMod(SPELLVALUE_BASE_POINT1, AURA_REMOVE_BY_ENEMY_SPELL); // add as marker (spell has no effect 1)
- GetTarget()->CastSpell(nullptr, SPELL_NECROTIC_PLAGUE_JUMP, args);
- if (Unit* caster = GetCaster())
- caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
-
- Remove(AURA_REMOVE_BY_ENEMY_SPELL);
- }
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SetOriginalCaster(GetCasterGUID());
+ args.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount() + 1);
+ GetTarget()->CastSpell(nullptr, SPELL_NECROTIC_PLAGUE_JUMP, args);
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
+ }
- void Register() override
- {
- OnEffectApply += AuraEffectApplyFn(spell_the_lich_king_necrotic_plague_AuraScript::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::OnDispel, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY);
- AfterEffectApply += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_AuraScript::AfterDispel, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY);
- }
+ void OnDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ _lastAmount = aurEff->GetAmount();
+ }
- int32 _lastAmount;
- };
+ void AfterDispel(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ // this means the stack increased so don't process as if dispelled
+ if (aurEff->GetAmount() > _lastAmount)
+ return;
+
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.SetOriginalCaster(GetCasterGUID());
+ args.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount());
+ args.AddSpellMod(SPELLVALUE_BASE_POINT1, AURA_REMOVE_BY_ENEMY_SPELL); // add as marker (spell has no effect 1)
+ GetTarget()->CastSpell(nullptr, SPELL_NECROTIC_PLAGUE_JUMP, args);
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
+
+ Remove(AURA_REMOVE_BY_ENEMY_SPELL);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_necrotic_plague_SpellScript();
- }
+ void Register() override
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_the_lich_king_necrotic_plague_jump_aura::OnApply, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_jump_aura::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_jump_aura::OnDispel, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY);
+ AfterEffectApply += AuraEffectRemoveFn(spell_the_lich_king_necrotic_plague_jump_aura::AfterDispel, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAPPLY);
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_necrotic_plague_AuraScript();
- }
+ int32 _lastAmount;
};
-class spell_the_lich_king_shadow_trap_visual : public SpellScriptLoader
+class spell_the_lich_king_shadow_trap_visual : public AuraScript
{
- public:
- spell_the_lich_king_shadow_trap_visual() : SpellScriptLoader("spell_the_lich_king_shadow_trap_visual") { }
-
- class spell_the_lich_king_shadow_trap_visual_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_shadow_trap_visual_AuraScript);
+ PrepareAuraScript(spell_the_lich_king_shadow_trap_visual);
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
- GetTarget()->CastSpell(GetTarget(), SPELL_SHADOW_TRAP_AURA, TRIGGERED_NONE);
- }
-
- void Register() override
- {
- AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_shadow_trap_visual_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- }
- };
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
+ GetTarget()->CastSpell(GetTarget(), SPELL_SHADOW_TRAP_AURA, TRIGGERED_NONE);
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_shadow_trap_visual_AuraScript();
- }
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_shadow_trap_visual::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
};
-class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader
+class spell_the_lich_king_shadow_trap_periodic : public SpellScript
{
- public:
- spell_the_lich_king_shadow_trap_periodic() : SpellScriptLoader("spell_the_lich_king_shadow_trap_periodic") { }
-
- class spell_the_lich_king_shadow_trap_periodic_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_shadow_trap_periodic_SpellScript);
+ PrepareSpellScript(spell_the_lich_king_shadow_trap_periodic);
- void CheckTargetCount(std::list<WorldObject*>& targets)
- {
- if (targets.empty())
- return;
-
- GetCaster()->CastSpell(nullptr, SPELL_SHADOW_TRAP_KNOCKBACK, true);
- }
+ void CheckTargetCount(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- }
- };
+ GetCaster()->CastSpell(nullptr, SPELL_SHADOW_TRAP_KNOCKBACK, true);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_shadow_trap_periodic_SpellScript();
- }
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_shadow_trap_periodic::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
};
-class spell_the_lich_king_quake : public SpellScriptLoader
+class spell_the_lich_king_quake : public SpellScript
{
- public:
- spell_the_lich_king_quake() : SpellScriptLoader("spell_the_lich_king_quake") { }
-
- class spell_the_lich_king_quake_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_quake_SpellScript);
+ PrepareSpellScript(spell_the_lich_king_quake);
- bool Load() override
- {
- return GetCaster()->GetInstanceScript() != nullptr;
- }
-
- void FilterTargets(std::list<WorldObject*>& targets)
- {
- if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetGuidData(DATA_ARTHAS_PLATFORM)))
- targets.remove_if(Trinity::HeightDifferenceCheck(platform, 5.0f, false));
- }
+ bool Load() override
+ {
+ return GetCaster()->GetInstanceScript() != nullptr;
+ }
- void HandleSendEvent(SpellEffIndex /*effIndex*/)
- {
- if (UnitAI* AI = GetCaster()->GetAI())
- AI->DoAction(ACTION_START_ATTACK);
- }
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetGuidData(DATA_ARTHAS_PLATFORM)))
+ targets.remove_if(Trinity::HeightDifferenceCheck(platform, 5.0f, false));
+ }
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
- OnEffectHit += SpellEffectFn(spell_the_lich_king_quake_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
- }
- };
+ void HandleSendEvent(SpellEffIndex /*effIndex*/)
+ {
+ if (UnitAI* AI = GetCaster()->GetAI())
+ AI->DoAction(ACTION_START_ATTACK);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_quake_SpellScript();
- }
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_quake::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnEffectHit += SpellEffectFn(spell_the_lich_king_quake::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
+ }
};
-class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader
+class spell_the_lich_king_ice_burst_target_search : public SpellScript
{
- public:
- spell_the_lich_king_ice_burst_target_search() : SpellScriptLoader("spell_the_lich_king_ice_burst_target_search") { }
-
- class spell_the_lich_king_ice_burst_target_search_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_ice_burst_target_search_SpellScript);
-
- bool Validate(SpellInfo const* /*spell*/) override
- {
- return ValidateSpellInfo({ SPELL_ICE_BURST });
- }
-
- void CheckTargetCount(std::list<WorldObject*>& unitList)
- {
- if (unitList.empty())
- return;
+ PrepareSpellScript(spell_the_lich_king_ice_burst_target_search);
- // if there is at least one affected target cast the explosion
- GetCaster()->CastSpell(GetCaster(), SPELL_ICE_BURST, true);
- if (GetCaster()->GetTypeId() == TYPEID_UNIT)
- {
- GetCaster()->ToCreature()->SetReactState(REACT_PASSIVE);
- GetCaster()->AttackStop();
- GetCaster()->ToCreature()->DespawnOrUnsummon(500ms);
- }
- }
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_ICE_BURST });
+ }
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- }
- };
+ void CheckTargetCount(std::list<WorldObject*>& unitList)
+ {
+ if (unitList.empty())
+ return;
- SpellScript* GetSpellScript() const override
+ // if there is at least one affected target cast the explosion
+ GetCaster()->CastSpell(GetCaster(), SPELL_ICE_BURST, true);
+ if (GetCaster()->GetTypeId() == TYPEID_UNIT)
{
- return new spell_the_lich_king_ice_burst_target_search_SpellScript();
+ GetCaster()->ToCreature()->SetReactState(REACT_PASSIVE);
+ GetCaster()->AttackStop();
+ GetCaster()->ToCreature()->DespawnOrUnsummon(500ms);
}
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_ice_burst_target_search::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
};
-class spell_the_lich_king_raging_spirit : public SpellScriptLoader
+class spell_the_lich_king_raging_spirit : public SpellScript
{
- public:
- spell_the_lich_king_raging_spirit() : SpellScriptLoader("spell_the_lich_king_raging_spirit") { }
+ PrepareSpellScript(spell_the_lich_king_raging_spirit);
- class spell_the_lich_king_raging_spirit_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_raging_spirit_SpellScript);
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- GetHitUnit()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_raging_spirit_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_raging_spirit_SpellScript();
- }
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_raging_spirit::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
class ExactDistanceCheck
@@ -2463,774 +2238,543 @@ class ExactDistanceCheck
float _dist;
};
-class spell_the_lich_king_defile : public SpellScriptLoader
+class spell_the_lich_king_defile : public SpellScript
{
- public:
- spell_the_lich_king_defile() : SpellScriptLoader("spell_the_lich_king_defile") { }
-
- class spell_the_lich_king_defile_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_defile_SpellScript);
+ PrepareSpellScript(spell_the_lich_king_defile);
- void CorrectRange(std::list<WorldObject*>& targets)
- {
- targets.remove_if(ExactDistanceCheck(GetCaster(), 10.0f * GetCaster()->GetObjectScale()));
- targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HARVEST_SOUL_VALKYR));
- }
-
- void ChangeDamageAndGrow()
- {
- SetHitDamage(int32(GetHitDamage() * GetCaster()->GetObjectScale()));
- // HACK: target player should cast this spell on defile
- // however with current aura handling auras cast by different units
- // cannot stack on the same aura object increasing the stack count
- GetCaster()->CastSpell(GetCaster(), SPELL_DEFILE_GROW, true);
- }
+ void CorrectRange(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(ExactDistanceCheck(GetCaster(), 10.0f * GetCaster()->GetObjectScale()));
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HARVEST_SOUL_VALKYR));
+ }
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
- OnHit += SpellHitFn(spell_the_lich_king_defile_SpellScript::ChangeDamageAndGrow);
- }
- };
+ void ChangeDamageAndGrow()
+ {
+ SetHitDamage(int32(GetHitDamage() * GetCaster()->GetObjectScale()));
+ // HACK: target player should cast this spell on defile
+ // however with current aura handling auras cast by different units
+ // cannot stack on the same aura object increasing the stack count
+ GetCaster()->CastSpell(GetCaster(), SPELL_DEFILE_GROW, true);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_defile_SpellScript();
- }
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnHit += SpellHitFn(spell_the_lich_king_defile::ChangeDamageAndGrow);
+ }
};
-class spell_the_lich_king_summon_into_air : public SpellScriptLoader
+class spell_the_lich_king_summon_into_air : public SpellScript
{
- public:
- spell_the_lich_king_summon_into_air() : SpellScriptLoader("spell_the_lich_king_summon_into_air") { }
-
- class spell_the_lich_king_summon_into_air_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_summon_into_air_SpellScript);
-
- void ModDestHeight(SpellEffIndex /*effIndex*/)
- {
- static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f};
- WorldLocation* dest = const_cast<WorldLocation*>(GetExplTargetDest());
- dest->RelocateOffset(offset);
- GetHitDest()->RelocateOffset(offset);
- // spirit bombs get higher
- if (GetEffectInfo().MiscValue == NPC_SPIRIT_BOMB)
- {
- static Position const offsetExtra = { 0.0f, 0.0f, 5.0f, 0.0f };
- dest->RelocateOffset(offsetExtra);
- GetHitDest()->RelocateOffset(offsetExtra);
- }
- }
-
- void Register() override
- {
- OnEffectHit += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
- }
- };
+ PrepareSpellScript(spell_the_lich_king_summon_into_air);
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_summon_into_air_SpellScript();
+ void ModDestHeight(SpellEffIndex /*effIndex*/)
+ {
+ static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f};
+ WorldLocation* dest = const_cast<WorldLocation*>(GetExplTargetDest());
+ dest->RelocateOffset(offset);
+ GetHitDest()->RelocateOffset(offset);
+ // spirit bombs get higher
+ if (GetEffectInfo().MiscValue == NPC_SPIRIT_BOMB)
+ {
+ static Position const offsetExtra = { 0.0f, 0.0f, 5.0f, 0.0f };
+ dest->RelocateOffset(offsetExtra);
+ GetHitDest()->RelocateOffset(offsetExtra);
}
+ }
+
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_the_lich_king_summon_into_air::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
+ }
};
-class spell_the_lich_king_soul_reaper : public SpellScriptLoader
+class spell_the_lich_king_soul_reaper : public AuraScript
{
- public:
- spell_the_lich_king_soul_reaper() : SpellScriptLoader("spell_the_lich_king_soul_reaper") { }
-
- class spell_the_lich_king_soul_reaper_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_soul_reaper_AuraScript);
-
- bool Validate(SpellInfo const* /*spell*/) override
- {
- return ValidateSpellInfo({ SPELL_SOUL_REAPER_BUFF });
- }
+ PrepareAuraScript(spell_the_lich_king_soul_reaper);
- void OnPeriodic(AuraEffect const* /*aurEff*/)
- {
- if (Unit* caster = GetCaster())
- GetTarget()->CastSpell(caster, SPELL_SOUL_REAPER_BUFF, true);
- }
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_SOUL_REAPER_BUFF });
+ }
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_soul_reaper_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
- }
- };
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ if (Unit* caster = GetCaster())
+ GetTarget()->CastSpell(caster, SPELL_SOUL_REAPER_BUFF, true);
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_soul_reaper_AuraScript();
- }
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_soul_reaper::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_DAMAGE);
+ }
};
-class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader
+class spell_the_lich_king_valkyr_target_search : public SpellScript
{
- public:
- spell_the_lich_king_valkyr_target_search() : SpellScriptLoader("spell_the_lich_king_valkyr_target_search") { }
-
- class spell_the_lich_king_valkyr_target_search_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_valkyr_target_search_SpellScript);
+ PrepareSpellScript(spell_the_lich_king_valkyr_target_search);
- bool Validate(SpellInfo const* /*spell*/) override
- {
- return ValidateSpellInfo({ SPELL_CHARGE });
- }
-
- void SelectTarget(std::list<WorldObject*>& targets)
- {
- if (targets.empty())
- return;
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_CHARGE });
+ }
- targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
- if (targets.empty())
- return;
+ void SelectTarget(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
- _target = Trinity::Containers::SelectRandomContainerElement(targets);
- targets.clear();
- targets.push_back(_target);
- GetCaster()->GetAI()->SetGUID(_target->GetGUID());
- }
+ targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
+ if (targets.empty())
+ return;
- void ReplaceTarget(std::list<WorldObject*>& targets)
- {
- targets.clear();
- if (_target)
- targets.push_back(_target);
- }
+ _target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(_target);
+ GetCaster()->GetAI()->SetGUID(_target->GetGUID());
+ }
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- GetCaster()->CastSpell(GetHitUnit(), SPELL_CHARGE, true);
- }
+ void ReplaceTarget(std::list<WorldObject*>& targets)
+ {
+ targets.clear();
+ if (_target)
+ targets.push_back(_target);
+ }
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_valkyr_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_CHARGE, true);
+ }
- WorldObject* _target = nullptr;
- };
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_valkyr_target_search::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_valkyr_target_search_SpellScript();
- }
+ WorldObject* _target = nullptr;
};
-class spell_the_lich_king_cast_back_to_caster : public SpellScriptLoader
+class spell_the_lich_king_cast_back_to_caster : public SpellScript
{
- public:
- spell_the_lich_king_cast_back_to_caster() : SpellScriptLoader("spell_the_lich_king_cast_back_to_caster") { }
-
- class spell_the_lich_king_cast_back_to_caster_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_cast_back_to_caster_SpellScript);
-
- void HandleScript(SpellEffIndex /*effIndex*/)
- {
- GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
- }
+ PrepareSpellScript(spell_the_lich_king_cast_back_to_caster);
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_cast_back_to_caster_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_cast_back_to_caster_SpellScript();
- }
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_cast_back_to_caster::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
-class spell_the_lich_king_life_siphon : public SpellScriptLoader
+class spell_the_lich_king_life_siphon : public SpellScript
{
- public:
- spell_the_lich_king_life_siphon() : SpellScriptLoader("spell_the_lich_king_life_siphon") { }
-
- class spell_the_lich_king_life_siphon_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_life_siphon_SpellScript);
-
- bool Validate(SpellInfo const* /*spell*/) override
- {
- return ValidateSpellInfo({ SPELL_LIFE_SIPHON_HEAL });
- }
+ PrepareSpellScript(spell_the_lich_king_life_siphon);
- void TriggerHeal()
- {
- CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
- args.AddSpellBP0(GetHitDamage() * 10);
- GetHitUnit()->CastSpell(GetCaster(), SPELL_LIFE_SIPHON_HEAL, args);
- }
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ return ValidateSpellInfo({ SPELL_LIFE_SIPHON_HEAL });
+ }
- void Register() override
- {
- AfterHit += SpellHitFn(spell_the_lich_king_life_siphon_SpellScript::TriggerHeal);
- }
- };
+ void TriggerHeal()
+ {
+ CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
+ args.AddSpellBP0(GetHitDamage() * 10);
+ GetHitUnit()->CastSpell(GetCaster(), SPELL_LIFE_SIPHON_HEAL, args);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_life_siphon_SpellScript();
- }
+ void Register() override
+ {
+ AfterHit += SpellHitFn(spell_the_lich_king_life_siphon::TriggerHeal);
+ }
};
-class spell_the_lich_king_vile_spirits : public SpellScriptLoader
+class spell_the_lich_king_vile_spirits : public AuraScript
{
- public:
- spell_the_lich_king_vile_spirits() : SpellScriptLoader("spell_the_lich_king_vile_spirits") { }
+ PrepareAuraScript(spell_the_lich_king_vile_spirits);
- class spell_the_lich_king_vile_spirits_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_vile_spirits_AuraScript);
-
- public:
- spell_the_lich_king_vile_spirits_AuraScript()
- {
- _is25Man = false;
- }
-
- private:
- bool Load() override
- {
- _is25Man = GetUnitOwner()->GetMap()->Is25ManRaid();
- return true;
- }
+public:
+ spell_the_lich_king_vile_spirits()
+ {
+ _is25Man = false;
+ }
- void OnPeriodic(AuraEffect const* aurEff)
- {
- if (_is25Man || ((aurEff->GetTickNumber() - 1) % 5))
- GetTarget()->CastSpell(nullptr, aurEff->GetSpellEffectInfo().TriggerSpell, CastSpellExtraArgs(aurEff)
- .SetOriginalCaster(GetCasterGUID()));
- }
+private:
+ bool Load() override
+ {
+ _is25Man = GetUnitOwner()->GetMap()->Is25ManRaid();
+ return true;
+ }
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_vile_spirits_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
- }
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ if (_is25Man || ((aurEff->GetTickNumber() - 1) % 5))
+ GetTarget()->CastSpell(nullptr, aurEff->GetSpellEffectInfo().TriggerSpell, CastSpellExtraArgs(aurEff)
+ .SetOriginalCaster(GetCasterGUID()));
+ }
- bool _is25Man;
- };
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_vile_spirits::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_vile_spirits_AuraScript();
- }
+ bool _is25Man;
};
-class spell_the_lich_king_vile_spirits_visual : public SpellScriptLoader
+class spell_the_lich_king_vile_spirits_visual : public SpellScript
{
- public:
- spell_the_lich_king_vile_spirits_visual() : SpellScriptLoader("spell_the_lich_king_vile_spirits_visual") { }
+ PrepareSpellScript(spell_the_lich_king_vile_spirits_visual);
- class spell_the_lich_king_vile_spirits_visual_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_vile_spirits_visual_SpellScript);
-
- void ModDestHeight(SpellEffIndex /*effIndex*/)
- {
- Position offset = {0.0f, 0.0f, 15.0f, 0.0f};
- const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
- }
-
- void Register() override
- {
- OnEffectLaunch += SpellEffectFn(spell_the_lich_king_vile_spirits_visual_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
+ void ModDestHeight(SpellEffIndex /*effIndex*/)
+ {
+ Position offset = {0.0f, 0.0f, 15.0f, 0.0f};
+ const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_vile_spirits_visual_SpellScript();
- }
+ void Register() override
+ {
+ OnEffectLaunch += SpellEffectFn(spell_the_lich_king_vile_spirits_visual::ModDestHeight, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
};
-class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoader
+class spell_the_lich_king_vile_spirit_move_target_search : public SpellScript
{
- public:
- spell_the_lich_king_vile_spirit_move_target_search() : SpellScriptLoader("spell_the_lich_king_vile_spirit_move_target_search") { }
-
- class spell_the_lich_king_vile_spirit_move_target_search_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_vile_spirit_move_target_search_SpellScript);
-
- public:
- spell_the_lich_king_vile_spirit_move_target_search_SpellScript()
- {
- _target = nullptr;
- }
+ PrepareSpellScript(spell_the_lich_king_vile_spirit_move_target_search);
- private:
- bool Load() override
- {
- return GetCaster()->GetTypeId() == TYPEID_UNIT;
- }
+public:
+ spell_the_lich_king_vile_spirit_move_target_search()
+ {
+ _target = nullptr;
+ }
- void SelectTarget(std::list<WorldObject*>& targets)
- {
- if (targets.empty())
- return;
+private:
+ bool Load() override
+ {
+ return GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
- _target = Trinity::Containers::SelectRandomContainerElement(targets);
- }
+ void SelectTarget(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- // for this spell, all units are in target map, however it should select one to attack
- if (GetHitUnit() != _target)
- return;
+ _target = Trinity::Containers::SelectRandomContainerElement(targets);
+ }
- GetCaster()->ToCreature()->AI()->AttackStart(GetHitUnit());
- GetCaster()->GetThreatManager().AddThreat(GetHitUnit(), 100000.0f);
- }
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ // for this spell, all units are in target map, however it should select one to attack
+ if (GetHitUnit() != _target)
+ return;
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
+ GetCaster()->ToCreature()->AI()->AttackStart(GetHitUnit());
+ GetCaster()->GetThreatManager().AddThreat(GetHitUnit(), 100000.0f);
+ }
- WorldObject* _target;
- };
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_move_target_search::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_vile_spirit_move_target_search::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_vile_spirit_move_target_search_SpellScript();
- }
+ WorldObject* _target;
};
-class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptLoader
+class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScript
{
- public:
- spell_the_lich_king_vile_spirit_damage_target_search() : SpellScriptLoader("spell_the_lich_king_vile_spirit_damage_target_search") { }
-
- class spell_the_lich_king_vile_spirit_damage_target_search_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript);
+ PrepareSpellScript(spell_the_lich_king_vile_spirit_damage_target_search);
- bool Load() override
- {
- return GetCaster()->GetTypeId() == TYPEID_UNIT;
- }
-
- void CheckTargetCount(std::list<WorldObject*>& targets)
- {
- if (targets.empty())
- return;
-
- // this spell has SPELL_AURA_BLOCK_SPELL_FAMILY so every next cast of this
- // searcher spell will be blocked
- if (TempSummon* summon = GetCaster()->ToTempSummon())
- if (Unit* summoner = summon->GetSummonerUnit())
- summoner->GetAI()->SetData(DATA_VILE, 1);
- GetCaster()->CastSpell(nullptr, SPELL_SPIRIT_BURST, true);
- GetCaster()->ToCreature()->DespawnOrUnsummon(3s);
- GetCaster()->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
- }
+ bool Load() override
+ {
+ return GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
- void Register() override
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- }
- };
+ void CheckTargetCount(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
+
+ // this spell has SPELL_AURA_BLOCK_SPELL_FAMILY so every next cast of this
+ // searcher spell will be blocked
+ if (TempSummon* summon = GetCaster()->ToTempSummon())
+ if (Unit* summoner = summon->GetSummonerUnit())
+ summoner->GetAI()->SetData(DATA_VILE, 1);
+ GetCaster()->CastSpell(nullptr, SPELL_SPIRIT_BURST, true);
+ GetCaster()->ToCreature()->DespawnOrUnsummon(3s);
+ GetCaster()->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_vile_spirit_damage_target_search_SpellScript();
- }
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_damage_target_search::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
};
-class spell_the_lich_king_harvest_soul : public SpellScriptLoader
+class spell_the_lich_king_harvest_soul : public AuraScript
{
- public:
- spell_the_lich_king_harvest_soul() : SpellScriptLoader("spell_the_lich_king_harvest_soul") { }
-
- class spell_the_lich_king_harvest_soul_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_harvest_soul_AuraScript);
+ PrepareAuraScript(spell_the_lich_king_harvest_soul);
- bool Load() override
- {
- return GetOwner()->GetInstanceScript() != nullptr;
- }
-
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- // m_originalCaster to allow stacking from different casters, meh
- if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
- GetTarget()->CastSpell(nullptr, SPELL_HARVESTED_SOUL, CastSpellExtraArgs(TRIGGERED_FULL_MASK)
- .SetOriginalCaster(GetTarget()->GetInstanceScript()->GetGuidData(DATA_THE_LICH_KING)));
- }
+ bool Load() override
+ {
+ return GetOwner()->GetInstanceScript() != nullptr;
+ }
- void Register() override
- {
- AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_harvest_soul_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
- }
- };
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ // m_originalCaster to allow stacking from different casters, meh
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
+ GetTarget()->CastSpell(nullptr, SPELL_HARVESTED_SOUL, CastSpellExtraArgs(TRIGGERED_FULL_MASK)
+ .SetOriginalCaster(GetTarget()->GetInstanceScript()->GetGuidData(DATA_THE_LICH_KING)));
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_harvest_soul_AuraScript();
- }
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_harvest_soul::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
+ }
};
-class spell_the_lich_king_lights_favor : public SpellScriptLoader
+class spell_the_lich_king_lights_favor : public AuraScript
{
- public:
- spell_the_lich_king_lights_favor() : SpellScriptLoader("spell_the_lich_king_lights_favor") { }
+ PrepareAuraScript(spell_the_lich_king_lights_favor);
- class spell_the_lich_king_lights_favor_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_lights_favor_AuraScript);
-
- void OnPeriodic(AuraEffect const* /*aurEff*/)
- {
- if (Unit* caster = GetCaster())
- if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1))
- effect->RecalculateAmount(caster);
- }
-
- void CalculateBonus(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
- {
- canBeRecalculated = true;
- amount = 0;
- if (Unit* caster = GetCaster())
- amount = int32(caster->GetHealthPct());
- }
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1))
+ effect->RecalculateAmount(caster);
+ }
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_lights_favor_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_the_lich_king_lights_favor_AuraScript::CalculateBonus, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
- }
- };
+ void CalculateBonus(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
+ {
+ canBeRecalculated = true;
+ amount = 0;
+ if (Unit* caster = GetCaster())
+ amount = int32(caster->GetHealthPct());
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_lights_favor_AuraScript();
- }
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_lights_favor::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_the_lich_king_lights_favor::CalculateBonus, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ }
};
-class spell_the_lich_king_soul_rip : public SpellScriptLoader
+class spell_the_lich_king_soul_rip : public AuraScript
{
- public:
- spell_the_lich_king_soul_rip() : SpellScriptLoader("spell_the_lich_king_soul_rip") { }
-
- class spell_the_lich_king_soul_rip_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_soul_rip_AuraScript);
-
- void OnPeriodic(AuraEffect const* aurEff)
- {
- PreventDefaultAction();
- // shouldn't be needed, this is channeled
- if (Unit* caster = GetCaster())
- {
- CastSpellExtraArgs args(aurEff);
- args.OriginalCaster = GetCasterGUID();
- args.AddSpellBP0(5000 * aurEff->GetTickNumber());
- caster->CastSpell(GetTarget(), SPELL_SOUL_RIP_DAMAGE, args);
- }
- }
+ PrepareAuraScript(spell_the_lich_king_soul_rip);
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_soul_rip_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_soul_rip_AuraScript();
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ PreventDefaultAction();
+ // shouldn't be needed, this is channeled
+ if (Unit* caster = GetCaster())
+ {
+ CastSpellExtraArgs args(aurEff);
+ args.OriginalCaster = GetCasterGUID();
+ args.AddSpellBP0(5000 * aurEff->GetTickNumber());
+ caster->CastSpell(GetTarget(), SPELL_SOUL_RIP_DAMAGE, args);
}
+ }
+
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_the_lich_king_soul_rip::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
};
-class spell_the_lich_king_restore_soul : public SpellScriptLoader
+class spell_the_lich_king_restore_soul : public SpellScript
{
- public:
- spell_the_lich_king_restore_soul() : SpellScriptLoader("spell_the_lich_king_restore_soul") { }
+ PrepareSpellScript(spell_the_lich_king_restore_soul);
- class spell_the_lich_king_restore_soul_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_restore_soul_SpellScript);
-
- public:
- spell_the_lich_king_restore_soul_SpellScript()
- {
- _instance = nullptr;
- }
-
- private:
- bool Load() override
- {
- _instance = GetCaster()->GetInstanceScript();
- return _instance != nullptr;
- }
+public:
+ spell_the_lich_king_restore_soul()
+ {
+ _instance = nullptr;
+ }
- void HandleScript(SpellEffIndex /*effIndex*/)
- {
- if (Creature* lichKing = ObjectAccessor::GetCreature(*GetCaster(), _instance->GetGuidData(DATA_THE_LICH_KING)))
- lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
- if (Creature* spawner = GetCaster()->FindNearestCreature(NPC_WORLD_TRIGGER_INFINITE_AOI, 50.0f))
- spawner->RemoveAllAuras();
-
- std::list<Creature*> spirits;
- GetCaster()->GetCreatureListWithEntryInGrid(spirits, NPC_WICKED_SPIRIT, 200.0f);
- for (std::list<Creature*>::iterator itr = spirits.begin(); itr != spirits.end(); ++itr)
- {
- (*itr)->m_Events.KillAllEvents(true);
- (*itr)->SetReactState(REACT_PASSIVE);
- (*itr)->AI()->EnterEvadeMode();
- }
- }
+private:
+ bool Load() override
+ {
+ _instance = GetCaster()->GetInstanceScript();
+ return _instance != nullptr;
+ }
- void RemoveAura(SpellMissInfo missInfo)
- {
- if (missInfo != SPELL_MISS_NONE)
- return;
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*GetCaster(), _instance->GetGuidData(DATA_THE_LICH_KING)))
+ lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
+ if (Creature* spawner = GetCaster()->FindNearestCreature(NPC_WORLD_TRIGGER_INFINITE_AOI, 50.0f))
+ spawner->RemoveAllAuras();
+
+ std::list<Creature*> spirits;
+ GetCaster()->GetCreatureListWithEntryInGrid(spirits, NPC_WICKED_SPIRIT, 200.0f);
+ for (std::list<Creature*>::iterator itr = spirits.begin(); itr != spirits.end(); ++itr)
+ {
+ (*itr)->m_Events.KillAllEvents(true);
+ (*itr)->SetReactState(REACT_PASSIVE);
+ (*itr)->AI()->EnterEvadeMode();
+ }
+ }
- if (Unit* target = GetHitUnit())
- target->RemoveAurasDueToSpell(target->GetMap()->IsHeroic() ? SPELL_HARVEST_SOULS_TELEPORT : SPELL_HARVEST_SOUL_TELEPORT);
- }
+ void RemoveAura(SpellMissInfo missInfo)
+ {
+ if (missInfo != SPELL_MISS_NONE)
+ return;
- void Register() override
- {
- OnEffectHit += SpellEffectFn(spell_the_lich_king_restore_soul_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
- BeforeHit += BeforeSpellHitFn(spell_the_lich_king_restore_soul_SpellScript::RemoveAura);
- }
+ if (Unit* target = GetHitUnit())
+ target->RemoveAurasDueToSpell(target->GetMap()->IsHeroic() ? SPELL_HARVEST_SOULS_TELEPORT : SPELL_HARVEST_SOUL_TELEPORT);
+ }
- InstanceScript* _instance;
- };
+ void Register() override
+ {
+ OnEffectHit += SpellEffectFn(spell_the_lich_king_restore_soul::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
+ BeforeHit += BeforeSpellHitFn(spell_the_lich_king_restore_soul::RemoveAura);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_restore_soul_SpellScript();
- }
+ InstanceScript* _instance;
};
-class spell_the_lich_king_dark_hunger : public SpellScriptLoader
+class spell_the_lich_king_dark_hunger : public AuraScript
{
- public:
- spell_the_lich_king_dark_hunger() : SpellScriptLoader("spell_the_lich_king_dark_hunger") { }
-
- class spell_the_lich_king_dark_hunger_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_dark_hunger_AuraScript);
+ PrepareAuraScript(spell_the_lich_king_dark_hunger);
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- return ValidateSpellInfo({ SPELL_DARK_HUNGER_HEAL });
- }
-
- void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo)
- {
- PreventDefaultAction();
- DamageInfo* damageInfo = eventInfo.GetDamageInfo();
- if (!damageInfo || !damageInfo->GetDamage())
- return;
-
- CastSpellExtraArgs args(aurEff);
- args.AddSpellBP0(damageInfo->GetDamage() / 2);
- GetTarget()->CastSpell(GetTarget(), SPELL_DARK_HUNGER_HEAL, args);
- }
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_DARK_HUNGER_HEAL });
+ }
- void Register() override
- {
- OnEffectProc += AuraEffectProcFn(spell_the_lich_king_dark_hunger_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
- }
- };
+ void HandleProc(AuraEffect* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ DamageInfo* damageInfo = eventInfo.GetDamageInfo();
+ if (!damageInfo || !damageInfo->GetDamage())
+ return;
+
+ CastSpellExtraArgs args(aurEff);
+ args.AddSpellBP0(damageInfo->GetDamage() / 2);
+ GetTarget()->CastSpell(GetTarget(), SPELL_DARK_HUNGER_HEAL, args);
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_dark_hunger_AuraScript();
- }
+ void Register() override
+ {
+ OnEffectProc += AuraEffectProcFn(spell_the_lich_king_dark_hunger::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
};
-class spell_the_lich_king_in_frostmourne_room : public SpellScriptLoader
+class spell_the_lich_king_in_frostmourne_room : public AuraScript
{
- public:
- spell_the_lich_king_in_frostmourne_room() : SpellScriptLoader("spell_the_lich_king_in_frostmourne_room") { }
-
- class spell_the_lich_king_in_frostmourne_room_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_the_lich_king_in_frostmourne_room_AuraScript);
+ PrepareAuraScript(spell_the_lich_king_in_frostmourne_room);
- bool Load() override
- {
- return GetOwner()->GetInstanceScript() != nullptr;
- }
-
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- // m_originalCaster to allow stacking from different casters, meh
- if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
- GetTarget()->CastSpell(nullptr, SPELL_HARVESTED_SOUL, CastSpellExtraArgs(TRIGGERED_FULL_MASK)
- .SetOriginalCaster(GetTarget()->GetInstanceScript()->GetGuidData(DATA_THE_LICH_KING)));
- }
+ bool Load() override
+ {
+ return GetOwner()->GetInstanceScript() != nullptr;
+ }
- void Register() override
- {
- AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_in_frostmourne_room_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- }
- };
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ // m_originalCaster to allow stacking from different casters, meh
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
+ GetTarget()->CastSpell(nullptr, SPELL_HARVESTED_SOUL, CastSpellExtraArgs(TRIGGERED_FULL_MASK)
+ .SetOriginalCaster(GetTarget()->GetInstanceScript()->GetGuidData(DATA_THE_LICH_KING)));
+ }
- AuraScript* GetAuraScript() const override
- {
- return new spell_the_lich_king_in_frostmourne_room_AuraScript();
- }
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_the_lich_king_in_frostmourne_room::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
};
-class spell_the_lich_king_summon_spirit_bomb : public SpellScriptLoader
+class spell_the_lich_king_summon_spirit_bomb : public SpellScript
{
- public:
- spell_the_lich_king_summon_spirit_bomb() : SpellScriptLoader("spell_the_lich_king_summon_spirit_bomb") { }
+ PrepareSpellScript(spell_the_lich_king_summon_spirit_bomb);
- class spell_the_lich_king_summon_spirit_bomb_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_summon_spirit_bomb_SpellScript);
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- GetHitUnit()->CastSpell(nullptr, uint32(GetEffectValue()), true);
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_summon_spirit_bomb_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->CastSpell(nullptr, uint32(GetEffectValue()), true);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_summon_spirit_bomb_SpellScript();
- }
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_summon_spirit_bomb::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
-class spell_the_lich_king_trigger_vile_spirit : public SpellScriptLoader
+class spell_the_lich_king_trigger_vile_spirit : public SpellScript
{
- public:
- spell_the_lich_king_trigger_vile_spirit() : SpellScriptLoader("spell_the_lich_king_trigger_vile_spirit") { }
-
- class spell_the_lich_king_trigger_vile_spirit_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_trigger_vile_spirit_SpellScript);
-
- void ActivateSpirit()
- {
- Creature* target = GetHitCreature();
- if (!target)
- return;
+ PrepareSpellScript(spell_the_lich_king_trigger_vile_spirit);
- VileSpiritActivateEvent(target).Execute(0, 0);
- }
+ void ActivateSpirit()
+ {
+ Creature* target = GetHitCreature();
+ if (!target)
+ return;
- void Register() override
- {
- OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::ActivateSpirit);
- }
- };
+ VileSpiritActivateEvent(target).Execute(0, 0);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_trigger_vile_spirit_SpellScript();
- }
+ void Register() override
+ {
+ OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit::ActivateSpirit);
+ }
};
-class spell_the_lich_king_jump : public SpellScriptLoader
+class spell_the_lich_king_jump : public SpellScript
{
- public:
- spell_the_lich_king_jump() : SpellScriptLoader("spell_the_lich_king_jump") { }
-
- class spell_the_lich_king_jump_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_jump_SpellScript);
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- GetHitUnit()->RemoveAurasDueToSpell(SPELL_RAISE_DEAD);
- GetHitUnit()->CastSpell(nullptr, SPELL_JUMP_2, true);
- if (Creature* creature = GetHitCreature())
- creature->AI()->DoAction(ACTION_BREAK_FROSTMOURNE);
- }
+ PrepareSpellScript(spell_the_lich_king_jump);
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_jump_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->RemoveAurasDueToSpell(SPELL_RAISE_DEAD);
+ GetHitUnit()->CastSpell(nullptr, SPELL_JUMP_2, true);
+ if (Creature* creature = GetHitCreature())
+ creature->AI()->DoAction(ACTION_BREAK_FROSTMOURNE);
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_jump_SpellScript();
- }
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_jump::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
-class spell_the_lich_king_jump_remove_aura : public SpellScriptLoader
+class spell_the_lich_king_jump_remove_aura : public SpellScript
{
- public:
- spell_the_lich_king_jump_remove_aura() : SpellScriptLoader("spell_the_lich_king_jump_remove_aura") { }
+ PrepareSpellScript(spell_the_lich_king_jump_remove_aura);
- class spell_the_lich_king_jump_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_jump_SpellScript);
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- GetHitUnit()->RemoveAurasDueToSpell(uint32(GetEffectValue()));
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_jump_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->RemoveAurasDueToSpell(uint32(GetEffectValue()));
+ }
- SpellScript* GetSpellScript() const override
- {
- return new spell_the_lich_king_jump_SpellScript();
- }
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_jump_remove_aura::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
};
-class spell_the_lich_king_harvest_souls_teleport : public SpellScriptLoader
+class spell_the_lich_king_harvest_souls_teleport : public SpellScript
{
-public:
- spell_the_lich_king_harvest_souls_teleport() : SpellScriptLoader("spell_the_lich_king_harvest_souls_teleport") { }
+ PrepareSpellScript(spell_the_lich_king_harvest_souls_teleport);
- class spell_the_lich_king_harvest_souls_teleport_SpellScript : public SpellScript
+ void RelocateTransportOffset(SpellEffIndex /*effIndex*/)
{
- PrepareSpellScript(spell_the_lich_king_harvest_souls_teleport_SpellScript);
-
- void RelocateTransportOffset(SpellEffIndex /*effIndex*/)
- {
- float randCoordX = frand(-18.0f, 18.0f);
- float randCoordY = frand(-18.0f, 18.0f);
- GetHitDest()->RelocateOffset({ randCoordX, randCoordY, 0.0f, 0.0f });
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_harvest_souls_teleport_SpellScript::RelocateTransportOffset, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS);
- }
- };
+ float randCoordX = frand(-18.0f, 18.0f);
+ float randCoordY = frand(-18.0f, 18.0f);
+ GetHitDest()->RelocateOffset({ randCoordX, randCoordY, 0.0f, 0.0f });
+ }
- SpellScript* GetSpellScript() const override
+ void Register() override
{
- return new spell_the_lich_king_harvest_souls_teleport_SpellScript();
+ OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_harvest_souls_teleport::RelocateTransportOffset, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS);
}
};
@@ -3264,46 +2808,51 @@ class achievement_neck_deep_in_vile : public AchievementCriteriaScript
void AddSC_boss_the_lich_king()
{
- new boss_the_lich_king();
- new npc_tirion_fordring_tft();
- new npc_shambling_horror_icc();
- new npc_raging_spirit();
- new npc_valkyr_shadowguard();
- new npc_strangulate_vehicle();
- new npc_terenas_menethil();
- new npc_spirit_warden();
- new npc_spirit_bomb();
- new npc_broken_frostmourne();
- new spell_the_lich_king_infest();
- new spell_the_lich_king_necrotic_plague();
- new spell_the_lich_king_necrotic_plague_jump();
- new spell_the_lich_king_shadow_trap_visual();
- new spell_the_lich_king_shadow_trap_periodic();
- new spell_the_lich_king_quake();
- new spell_the_lich_king_ice_burst_target_search();
- new spell_the_lich_king_raging_spirit();
- new spell_the_lich_king_defile();
- new spell_the_lich_king_summon_into_air();
- new spell_the_lich_king_soul_reaper();
- new spell_the_lich_king_valkyr_target_search();
- new spell_the_lich_king_cast_back_to_caster();
- new spell_the_lich_king_life_siphon();
- new spell_the_lich_king_vile_spirits();
- new spell_the_lich_king_vile_spirits_visual();
- new spell_the_lich_king_vile_spirit_move_target_search();
- new spell_the_lich_king_vile_spirit_damage_target_search();
- new spell_the_lich_king_harvest_soul();
- new spell_the_lich_king_lights_favor();
- new spell_the_lich_king_soul_rip();
- new spell_the_lich_king_restore_soul();
- new spell_the_lich_king_dark_hunger();
- new spell_the_lich_king_in_frostmourne_room();
- new spell_the_lich_king_summon_spirit_bomb();
- new spell_the_lich_king_trigger_vile_spirit();
- new spell_the_lich_king_jump();
- new spell_the_lich_king_jump_remove_aura();
+ // Creatures
+ RegisterIcecrownCitadelCreatureAI(boss_the_lich_king);
+ RegisterIcecrownCitadelCreatureAI(npc_tirion_fordring_tft);
+ RegisterIcecrownCitadelCreatureAI(npc_shambling_horror_icc);
+ RegisterIcecrownCitadelCreatureAI(npc_raging_spirit);
+ RegisterIcecrownCitadelCreatureAI(npc_valkyr_shadowguard);
+ RegisterIcecrownCitadelCreatureAI(npc_strangulate_vehicle);
+ RegisterIcecrownCitadelCreatureAI(npc_terenas_menethil);
+ RegisterIcecrownCitadelCreatureAI(npc_spirit_warden);
+ RegisterIcecrownCitadelCreatureAI(npc_spirit_bomb);
+ RegisterIcecrownCitadelCreatureAI(npc_broken_frostmourne);
+
+ // Spells
+ RegisterSpellScript(spell_the_lich_king_infest);
+ RegisterSpellScript(spell_the_lich_king_necrotic_plague);
+ RegisterSpellAndAuraScriptPair(spell_the_lich_king_necrotic_plague_jump, spell_the_lich_king_necrotic_plague_jump_aura);
+ RegisterSpellScript(spell_the_lich_king_shadow_trap_visual);
+ RegisterSpellScript(spell_the_lich_king_shadow_trap_periodic);
+ RegisterSpellScript(spell_the_lich_king_quake);
+ RegisterSpellScript(spell_the_lich_king_ice_burst_target_search);
+ RegisterSpellScript(spell_the_lich_king_raging_spirit);
+ RegisterSpellScript(spell_the_lich_king_defile);
+ RegisterSpellScript(spell_the_lich_king_summon_into_air);
+ RegisterSpellScript(spell_the_lich_king_soul_reaper);
+ RegisterSpellScript(spell_the_lich_king_valkyr_target_search);
+ RegisterSpellScript(spell_the_lich_king_cast_back_to_caster);
+ RegisterSpellScript(spell_the_lich_king_life_siphon);
+ RegisterSpellScript(spell_the_lich_king_vile_spirits);
+ RegisterSpellScript(spell_the_lich_king_vile_spirits_visual);
+ RegisterSpellScript(spell_the_lich_king_vile_spirit_move_target_search);
+ RegisterSpellScript(spell_the_lich_king_vile_spirit_damage_target_search);
+ RegisterSpellScript(spell_the_lich_king_harvest_soul);
+ RegisterSpellScript(spell_the_lich_king_lights_favor);
+ RegisterSpellScript(spell_the_lich_king_soul_rip);
+ RegisterSpellScript(spell_the_lich_king_restore_soul);
+ RegisterSpellScript(spell_the_lich_king_dark_hunger);
+ RegisterSpellScript(spell_the_lich_king_in_frostmourne_room);
+ RegisterSpellScript(spell_the_lich_king_summon_spirit_bomb);
+ RegisterSpellScript(spell_the_lich_king_trigger_vile_spirit);
+ RegisterSpellScript(spell_the_lich_king_jump);
+ RegisterSpellScript(spell_the_lich_king_jump_remove_aura);
new spell_trigger_spell_from_caster("spell_the_lich_king_mass_resurrection", SPELL_MASS_RESURRECTION_REAL);
- new spell_the_lich_king_harvest_souls_teleport();
+ RegisterSpellScript(spell_the_lich_king_harvest_souls_teleport);
+
+ // Achievements
new achievement_been_waiting_long_time();
new achievement_neck_deep_in_vile();
}