summaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/game/Spells/SpellInfoCorrections.cpp6
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp17
-rw-r--r--src/server/scripts/Northrend/zone_zuldrak.cpp595
3 files changed, 363 insertions, 255 deletions
diff --git a/src/server/game/Spells/SpellInfoCorrections.cpp b/src/server/game/Spells/SpellInfoCorrections.cpp
index 77057e7988..1ebdd97eec 100644
--- a/src/server/game/Spells/SpellInfoCorrections.cpp
+++ b/src/server/game/Spells/SpellInfoCorrections.cpp
@@ -2187,12 +2187,6 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
});
- // Halls of Lightning, Arcing Burn
- ApplySpellFix({ 52671, 59834 }, [](SpellInfo* spellInfo)
- {
- spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
- });
-
// Trial of the Champion, Death's Respite
ApplySpellFix({ 68306 }, [](SpellInfo* spellInfo)
{
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
index 7e7e800b9a..f19dba6995 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
@@ -41,6 +41,7 @@ enum VolkhanOther
NPC_VOLKHAN_ANVIL = 28823,
NPC_MOLTEN_GOLEM = 28695,
NPC_BRITTLE_GOLEM = 28681,
+ NPC_SLAG = 28585,
// Misc
ACTION_SHATTER = 1,
@@ -77,7 +78,7 @@ enum Yells
struct boss_volkhan : public BossAI
{
- boss_volkhan(Creature* creature) : BossAI(creature, DATA_VOLKHAN), summons(creature) { }
+ boss_volkhan(Creature* creature) : BossAI(creature, DATA_VOLKHAN) { }
void Reset() override
{
@@ -104,6 +105,18 @@ struct boss_volkhan : public BossAI
{
_JustDied();
Talk(SAY_DEATH);
+
+ std::list<Creature*> slags;
+ GetCreatureListWithEntryInGrid(slags, me, NPC_SLAG, 100.0f);
+
+ if (!slags.empty())
+ {
+ for (Creature* slag : slags)
+ {
+ if (slag)
+ slag->DespawnOrUnsummon();
+ }
+ }
}
void GetNextPos()
@@ -286,8 +299,6 @@ struct boss_volkhan : public BossAI
}
private:
- EventMap events;
- SummonList summons;
float x, y, z;
uint8 PointID;
uint8 ShatteredCount;
diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp
index 3a91af290b..8dbca6a782 100644
--- a/src/server/scripts/Northrend/zone_zuldrak.cpp
+++ b/src/server/scripts/Northrend/zone_zuldrak.cpp
@@ -17,6 +17,7 @@
#include "CreatureScript.h"
#include "GameObjectScript.h"
+#include "GridNotifiers.h"
#include "PassiveAI.h"
#include "Player.h"
#include "ScriptedCreature.h"
@@ -26,6 +27,7 @@
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "Vehicle.h"
+#include <algorithm>
enum AlchemistItemRequirements
{
@@ -234,297 +236,376 @@ public:
}
};
-enum overlordDrakuru
+enum OverlordDrakuru
{
- SPELL_SHADOW_BOLT = 54113,
- SPELL_SCOURGE_DISGUISE_EXPIRING = 52010,
- SPELL_THROW_BRIGHT_CRYSTAL = 54087,
- SPELL_TELEPORT_EFFECT = 52096,
- SPELL_SCOURGE_DISGUISE = 51966,
- SPELL_SCOURGE_DISGUISE_INSTANT_CAST = 52192,
- SPELL_BLIGHT_FOG = 54104,
- SPELL_THROW_PORTAL_CRYSTAL = 54209,
- SPELL_ARTHAS_PORTAL = 51807,
- SPELL_TOUCH_OF_DEATH = 54236,
- SPELL_DRAKURU_DEATH = 54248,
- SPELL_SUMMON_SKULL = 54253,
-
- QUEST_BETRAYAL = 12713,
-
- NPC_BLIGHTBLOOD_TROLL = 28931,
- NPC_LICH_KING = 28498,
-
- EVENT_BETRAYAL_1 = 1,
- EVENT_BETRAYAL_2 = 2,
- EVENT_BETRAYAL_3 = 3,
- EVENT_BETRAYAL_4 = 4,
- EVENT_BETRAYAL_5 = 5,
- EVENT_BETRAYAL_6 = 6,
- EVENT_BETRAYAL_7 = 7,
- EVENT_BETRAYAL_8 = 8,
- EVENT_BETRAYAL_9 = 9,
- EVENT_BETRAYAL_10 = 10,
- EVENT_BETRAYAL_11 = 11,
- EVENT_BETRAYAL_12 = 12,
- EVENT_BETRAYAL_13 = 13,
- EVENT_BETRAYAL_14 = 14,
- EVENT_BETRAYAL_SHADOW_BOLT = 20,
- EVENT_BETRAYAL_CRYSTAL = 21,
- EVENT_BETRAYAL_COMBAT_TALK = 22,
-
- SAY_DRAKURU_0 = 0,
- SAY_DRAKURU_1 = 1,
- SAY_DRAKURU_2 = 2,
- SAY_DRAKURU_3 = 3,
- SAY_DRAKURU_4 = 4,
- SAY_DRAKURU_5 = 5,
- SAY_DRAKURU_6 = 6,
- SAY_DRAKURU_7 = 7,
- SAY_LICH_7 = 7,
- SAY_LICH_8 = 8,
- SAY_LICH_9 = 9,
- SAY_LICH_10 = 10,
- SAY_LICH_11 = 11,
- SAY_LICH_12 = 12,
+ SPELL_SHADOW_BOLT = 54113,
+ SPELL_SCOURGE_DISGUISE_EXPIRING = 52010,
+ SPELL_DROP_DISGUISE = 54089,
+ SPELL_THROW_BRIGHT_CRYSTAL = 54087,
+ SPELL_TELEPORT_EFFECT = 52096,
+ SPELL_SCOURGE_SPOTLIGHT = 53104,
+ SPELL_SCOURGE_DISGUISE = 51966,
+ SPELL_SCOURGE_DISGUISE_INSTANT_CAST = 52192,
+ SPELL_BLIGHT_FOG = 54104,
+ SPELL_THROW_PORTAL_CRYSTAL = 54209,
+ SPELL_ARTHAS_PORTAL = 51807,
+ SPELL_TOUCH_OF_DEATH = 54236,
+ SPELL_DRAKURU_DEATH = 54248,
+ SPELL_SUMMON_SKULL = 54253,
+ SPELL_BLOATED_ABOMINATION_FEIGN_DEATH = 52593,
+ SPELL_EXPLODE_ABOMINATION_BLOODY_MEAT = 52523,
+ SPELL_EXPLODE_ABOMINATION_MEAT = 52520,
+ SPELL_DRAKURUS_SKULL_MISSILE = 54250,
+ SPELL_BURST_AT_THE_SEAMS_BONE = 52516,
+
+ QUEST_BETRAYAL = 12713,
+
+ NPC_BLIGHTBLOOD_TROLL = 28931,
+ NPC_LICH_KING = 28498,
+ NPC_TOTALLY_GENERIC_BUNNY = 29100,
+ NPC_TOTALLY_GENERIC_BUNNY_JSB = 28960,
+ GO_DRAKURUS_LAST_WISH = 202357,
+
+ ACTION_SUMMON_DRAKURU_LAST_WISH = 1,
+ ACTION_DESTROY_DRAKURU_LAST_WISH = 2,
+ ACTION_REMOVE_SPOTLIGHTS = 3,
+
+ SUMMON_GROUP_BLIGHTBLOOD_TROLL = 1,
+
+ EVENT_BETRAYAL_INTRO_1 = 1,
+ EVENT_BETRAYAL_INTRO_2 = 2,
+ EVENT_BETRAYAL_INTRO_3 = 3,
+ EVENT_BETRAYAL_INTRO_4 = 4,
+ EVENT_BETRAYAL_EVADE_CHECK = 5,
+ EVENT_BETRAYAL_EPILOGUE_1 = 6,
+ EVENT_BETRAYAL_EPILOGUE_2 = 7,
+ EVENT_BETRAYAL_EPILOGUE_3 = 8,
+ EVENT_BETRAYAL_EPILOGUE_4 = 9,
+ EVENT_BETRAYAL_EPILOGUE_5 = 10,
+ EVENT_BETRAYAL_EPILOGUE_6 = 11,
+ EVENT_BETRAYAL_EPILOGUE_7 = 12,
+ EVENT_BETRAYAL_EPILOGUE_8 = 13,
+ EVENT_BETRAYAL_EPILOGUE_9 = 14,
+ EVENT_BETRAYAL_EPILOGUE_10 = 15,
+
+ SAY_DRAKURU_0 = 0,
+ SAY_DRAKURU_1 = 1,
+ SAY_DRAKURU_2 = 2,
+ SAY_DRAKURU_3 = 3,
+ SAY_DRAKURU_4 = 4,
+ SAY_DRAKURU_5 = 5,
+ SAY_DRAKURU_6 = 6,
+ SAY_DRAKURU_7 = 7,
+ SAY_LICH_7 = 7,
+ SAY_LICH_8 = 8,
+ SAY_LICH_9 = 9,
+ SAY_LICH_10 = 10,
+ SAY_LICH_11 = 11,
+ SAY_LICH_12 = 12,
};
-class npc_overlord_drakuru_betrayal : public CreatureScript
+enum BetrayalState
{
-public:
- npc_overlord_drakuru_betrayal() : CreatureScript("npc_overlord_drakuru_betrayal") { }
+ BETRAYAL_NOT_STARTED,
+ BETRAYAL_IN_PROGRESS,
+ BETRAYAL_EPILOGUE,
+ BETRAYAL_EVADE,
+};
- CreatureAI* GetAI(Creature* creature) const override
+struct npc_overlord_drakuru_betrayal : public ScriptedAI
+{
+ npc_overlord_drakuru_betrayal(Creature* creature) : ScriptedAI(creature), _summons(me), _state(BETRAYAL_NOT_STARTED)
{
- return new npc_overlord_drakuru_betrayalAI(creature);
+ me->SetCombatMovement(false);
}
- struct npc_overlord_drakuru_betrayalAI : public ScriptedAI
+ void EnterEvadeMode(EvadeReason why) override
{
- npc_overlord_drakuru_betrayalAI(Creature* creature) : ScriptedAI(creature), summons(me)
- {
- }
+ if (_state != BETRAYAL_EVADE)
+ return;
+ me->SetFaction(FACTION_UNDEAD_SCOURGE);
+ me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
+ ScriptedAI::EnterEvadeMode(why);
+ }
- EventMap events;
- SummonList summons;
- ObjectGuid playerGUID;
- ObjectGuid lichGUID;
+ void Reset() override
+ {
+ events.Reset();
+ scheduler.CancelAll();
+ _summons.DespawnAll();
+ _playerGUID.Clear();
+ _lichGUID.Clear();
+ me->SetFaction(FACTION_UNDEAD_SCOURGE);
+ me->SetVisible(false);
+ DoAction(ACTION_SUMMON_DRAKURU_LAST_WISH);
+ me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
+ me->SetImmuneToPC(true);
+ _state = BETRAYAL_NOT_STARTED;
+ DoAction(ACTION_REMOVE_SPOTLIGHTS);
+ }
- void EnterEvadeMode(EvadeReason why) override
+ void DoAction(int32 action) override
+ {
+ switch (action)
{
- if (playerGUID)
- if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
- if (player->IsWithinDistInMap(me, 80))
- return;
- me->SetFaction(FACTION_UNDEAD_SCOURGE);
- me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- ScriptedAI::EnterEvadeMode(why);
+ case ACTION_SUMMON_DRAKURU_LAST_WISH:
+ if (!me->FindNearestGameObject(GO_DRAKURUS_LAST_WISH, 80.0f))
+ me->SummonGameObject(GO_DRAKURUS_LAST_WISH, 6185.989, -2029.6979, 590.87787, 0, 0, 0, 0, 0, 0, true, GO_SUMMON_TIMED_DESPAWN);
+ break;
+ case ACTION_DESTROY_DRAKURU_LAST_WISH:
+ if (GameObject* go = me->FindNearestGameObject(GO_DRAKURUS_LAST_WISH, 80.0f))
+ go->Delete();
+ break;
+ case ACTION_REMOVE_SPOTLIGHTS:
+ {
+ std::list<Creature*> creatures;
+ me->GetCreatureListWithEntryInGrid(creatures, NPC_TOTALLY_GENERIC_BUNNY, 55.0f);
+ for (Creature* creature : creatures)
+ creature->RemoveAurasDueToSpell(SPELL_SCOURGE_SPOTLIGHT);
+ }
}
+ }
- void Reset() override
- {
- events.Reset();
- summons.DespawnAll();
- playerGUID.Clear();
- lichGUID.Clear();
- me->SetFaction(FACTION_UNDEAD_SCOURGE);
- me->SetVisible(false);
- me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- }
+ bool IsPlayerOnQuest(Player* player)
+ {
+ return player->GetQuestStatus(QUEST_BETRAYAL) == QUEST_STATUS_INCOMPLETE;
+ }
- void MoveInLineOfSight(Unit* who) override
+ void MoveInLineOfSight(Unit* who) override
+ {
+ if (Player* player = who->ToPlayer())
{
- if (who->IsPlayer())
+ bool shouldStartEvent = (_state == BETRAYAL_NOT_STARTED) && IsPlayerOnQuest(player) && player->HasAura(SPELL_SCOURGE_DISGUISE) && player->IsWithinDistInMap(me, 80.0f);
+ if (shouldStartEvent)
{
- if (playerGUID)
- {
- if (who->GetGUID() != playerGUID)
- {
- Player* player = ObjectAccessor::GetPlayer(*me, playerGUID);
- if (player && player->IsWithinDistInMap(me, 80))
- who->ToPlayer()->NearTeleportTo(6143.76f, -1969.7f, 417.57f, 2.08f);
- else
- {
- EnterEvadeMode(EVADE_REASON_OTHER);
- return;
- }
- }
- else
- ScriptedAI::MoveInLineOfSight(who);
- }
- else if (who->ToPlayer()->GetQuestStatus(QUEST_BETRAYAL) == QUEST_STATUS_INCOMPLETE && who->HasAura(SPELL_SCOURGE_DISGUISE))
- {
- me->SetVisible(true);
- playerGUID = who->GetGUID();
- events.ScheduleEvent(EVENT_BETRAYAL_1, 5s);
- }
+ me->SetVisible(true);
+ _state = BETRAYAL_IN_PROGRESS;
+ DoAction(ACTION_DESTROY_DRAKURU_LAST_WISH);
+ _playerGUID = who->GetGUID();
+ events.ScheduleEvent(EVENT_BETRAYAL_INTRO_1, 6s);
+ events.ScheduleEvent(EVENT_BETRAYAL_EVADE_CHECK, 10s);
}
- else
- ScriptedAI::MoveInLineOfSight(who);
}
+ else
+ ScriptedAI::MoveInLineOfSight(who);
+ }
- void JustSummoned(Creature* cr) override
+ void JustSummoned(Creature* summon) override
+ {
+ _summons.Summon(summon);
+ switch (summon->GetEntry())
{
- summons.Summon(cr);
- if (cr->GetEntry() == NPC_BLIGHTBLOOD_TROLL)
- cr->CastSpell(cr, SPELL_TELEPORT_EFFECT, true);
- else
- {
- me->SetFacingToObject(cr);
- lichGUID = cr->GetGUID();
- float o = me->GetAngle(cr);
- cr->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(o) * 6.0f, me->GetPositionY() + std::sin(o) * 6.0f, me->GetPositionZ());
- }
+ case NPC_BLIGHTBLOOD_TROLL:
+ if (Creature* target = summon->FindNearestCreature(NPC_TOTALLY_GENERIC_BUNNY, 10.0f, true))
+ target->CastSpell(target, SPELL_TELEPORT_EFFECT, true);
+ break;
+ case NPC_LICH_KING:
+ me->SetFacingToObject(summon);
+ _lichGUID = summon->GetGUID();
+ summon->GetMotionMaster()->MovePoint(0, 6164.2695, -2016.8978, 590.8636);
+ break;
+ default:
+ break;
}
+ }
- void JustEngagedWith(Unit*) override
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ scheduler.Schedule(0s, [this](TaskContext context)
{
- Talk(SAY_DRAKURU_3);
- events.ScheduleEvent(EVENT_BETRAYAL_SHADOW_BOLT, 2s);
- events.ScheduleEvent(EVENT_BETRAYAL_CRYSTAL, 5s);
- events.ScheduleEvent(EVENT_BETRAYAL_COMBAT_TALK, 20s);
- }
+ if (!me->IsWithinMeleeRange(me->GetVictim()))
+ DoCastVictim(SPELL_SHADOW_BOLT);
+ context.Repeat(2s);
+ }).Schedule(5s, [this](TaskContext context)
+ {
+ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
+ DoCast(target, SPELL_THROW_BRIGHT_CRYSTAL);
+ context.Repeat(6s, 15s);
+ }).Schedule(20s, [this](TaskContext context)
+ {
+ Talk(SAY_DRAKURU_4);
+ context.Repeat(10s, 20s);
+ });
+ }
- void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
+ void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*dmgType*/, SpellSchoolMask /*school*/) override
+ {
+ if (damage >= me->GetHealth() && !me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
{
- if (damage >= me->GetHealth() && !me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
- {
- damage = 0;
- me->RemoveAllAuras();
- me->CombatStop();
- me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- me->SetFaction(FACTION_FRIENDLY);
- events.Reset();
- events.ScheduleEvent(EVENT_BETRAYAL_4, 1s);
- }
+ damage = 0;
+ me->RemoveAllAuras();
+ me->CombatStop();
+ me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
+ me->SetFaction(2082);
+ me->SetImmuneToPC(true);
+ events.Reset();
+ scheduler.CancelAll();
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_1, 4200ms);
+ _state = BETRAYAL_EPILOGUE;
}
+ }
- void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
+ void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
+ {
+ switch (spellInfo->Id)
{
- if (spellInfo->Id == SPELL_THROW_PORTAL_CRYSTAL)
+ case SPELL_THROW_PORTAL_CRYSTAL:
if (Aura* aura = target->AddAura(SPELL_ARTHAS_PORTAL, target))
- aura->SetDuration(48000);
+ aura->SetDuration(77'000);
+ break;
+ case SPELL_DRAKURUS_SKULL_MISSILE:
+ target->CastSpell(target, SPELL_SUMMON_SKULL, true);
+ break;
+ case SPELL_DROP_DISGUISE:
+ target->CastSpell(target, SPELL_SCOURGE_DISGUISE_EXPIRING, true);
+ break;
}
+ }
- void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
+ void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ if (spellInfo->Id == SPELL_TOUCH_OF_DEATH)
{
- if (spellInfo->Id == SPELL_TOUCH_OF_DEATH)
- {
- me->CastSpell(me, SPELL_DRAKURU_DEATH, true);
- me->CastSpell(me, SPELL_SUMMON_SKULL, true);
- }
+ DoCastAOE(SPELL_DRAKURUS_SKULL_MISSILE, true);
+ DoCastSelf(SPELL_BLOATED_ABOMINATION_FEIGN_DEATH, true);
+ DoCastSelf(SPELL_BURST_AT_THE_SEAMS_BONE, true);
+ DoCastSelf(SPELL_BURST_AT_THE_SEAMS_BONE, true);
+ DoCastSelf(SPELL_BURST_AT_THE_SEAMS_BONE, true);
+ DoCastSelf(SPELL_EXPLODE_ABOMINATION_MEAT, true);
+ DoCastSelf(SPELL_EXPLODE_ABOMINATION_BLOODY_MEAT, true);
+ DoCastSelf(SPELL_EXPLODE_ABOMINATION_BLOODY_MEAT, true);
+ DoCastSelf(SPELL_EXPLODE_ABOMINATION_BLOODY_MEAT, true);
+ DoCastSelf(SPELL_DRAKURU_DEATH, true);
+ DoAction(ACTION_SUMMON_DRAKURU_LAST_WISH);
+ me->SetImmuneToPC(true);
}
+ }
- void UpdateAI(uint32 diff) override
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+ switch (events.ExecuteEvent())
{
- events.Update(diff);
- switch (events.ExecuteEvent())
+ case EVENT_BETRAYAL_EVADE_CHECK:
{
- case EVENT_BETRAYAL_1:
- Talk(SAY_DRAKURU_0);
- events.ScheduleEvent(EVENT_BETRAYAL_2, 5s);
- break;
- case EVENT_BETRAYAL_2:
- me->SummonCreature(NPC_BLIGHTBLOOD_TROLL, 6184.1f, -1969.9f, 586.76f, 4.5f);
- me->SummonCreature(NPC_BLIGHTBLOOD_TROLL, 6222.9f, -2026.5f, 586.76f, 2.9f);
- me->SummonCreature(NPC_BLIGHTBLOOD_TROLL, 6166.2f, -2065.4f, 586.76f, 1.4f);
- me->SummonCreature(NPC_BLIGHTBLOOD_TROLL, 6127.5f, -2008.7f, 586.76f, 0.0f);
- events.ScheduleEvent(EVENT_BETRAYAL_3, 5s);
- break;
- case EVENT_BETRAYAL_3:
- Talk(SAY_DRAKURU_1);
- Talk(SAY_DRAKURU_2);
- if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
- player->CastSpell(player, SPELL_SCOURGE_DISGUISE_EXPIRING, true);
- if (Aura* aur = me->AddAura(SPELL_BLIGHT_FOG, me))
- aur->SetDuration(22000);
- break;
- case EVENT_BETRAYAL_4:
- Talk(SAY_DRAKURU_5);
- events.ScheduleEvent(EVENT_BETRAYAL_5, 6s);
- break;
- case EVENT_BETRAYAL_5:
- Talk(SAY_DRAKURU_6);
- me->CastSpell(me, SPELL_THROW_PORTAL_CRYSTAL, true);
- events.ScheduleEvent(EVENT_BETRAYAL_6, 8s);
- break;
- case EVENT_BETRAYAL_6:
- me->SummonCreature(NPC_LICH_KING, 6142.9f, -2011.6f, 590.86f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 41000);
- events.ScheduleEvent(EVENT_BETRAYAL_7, 8s);
- break;
- case EVENT_BETRAYAL_7:
- Talk(SAY_DRAKURU_7);
- events.ScheduleEvent(EVENT_BETRAYAL_8, 5s);
- break;
- case EVENT_BETRAYAL_8:
- if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
- lich->AI()->Talk(SAY_LICH_7);
- events.ScheduleEvent(EVENT_BETRAYAL_9, 6s);
- break;
- case EVENT_BETRAYAL_9:
- if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
+ if (_state == BETRAYAL_IN_PROGRESS)
+ {
+ float radius = 80.0f;
+ std::list<Player*> players;
+ Acore::AnyPlayerInObjectRangeCheck checker(me, radius, true, true);
+ Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(me, players, checker);
+ Cell::VisitObjects(me, searcher, radius);
+ if (std::ranges::any_of(players, [this](Player* player)
{
- lich->AI()->Talk(SAY_LICH_8);
- lich->CastSpell(me, SPELL_TOUCH_OF_DEATH, false);
+ return IsPlayerOnQuest(player);
+ }))
+ {
+ events.Repeat(10s);
}
- events.ScheduleEvent(EVENT_BETRAYAL_10, 4s);
- break;
- case EVENT_BETRAYAL_10:
- me->SetVisible(false);
- if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
- lich->AI()->Talk(SAY_LICH_9);
- events.ScheduleEvent(EVENT_BETRAYAL_11, 4s);
- break;
- case EVENT_BETRAYAL_11:
- if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
- lich->AI()->Talk(SAY_LICH_10);
- events.ScheduleEvent(EVENT_BETRAYAL_12, 6s);
- break;
- case EVENT_BETRAYAL_12:
- if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
- lich->AI()->Talk(SAY_LICH_11);
- events.ScheduleEvent(EVENT_BETRAYAL_13, 3s);
- break;
- case EVENT_BETRAYAL_13:
- if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
+ else
{
- lich->AI()->Talk(SAY_LICH_12);
- lich->GetMotionMaster()->MovePoint(0, 6143.8f, -2011.5f, 590.9f);
+ _state = BETRAYAL_EVADE;
+ EnterEvadeMode(EVADE_REASON_OTHER);
}
- events.ScheduleEvent(EVENT_BETRAYAL_14, 7s);
- break;
- case EVENT_BETRAYAL_14:
- playerGUID.Clear();
- EnterEvadeMode(EVADE_REASON_OTHER);
- break;
+ }
+ break;
}
+ case EVENT_BETRAYAL_INTRO_1:
+ Talk(SAY_DRAKURU_0);
+ events.ScheduleEvent(EVENT_BETRAYAL_INTRO_2, 4s);
+ events.ScheduleEvent(EVENT_BETRAYAL_INTRO_3, 6600ms);
+ break;
+ case EVENT_BETRAYAL_INTRO_2:
+ me->SummonCreatureGroup(SUMMON_GROUP_BLIGHTBLOOD_TROLL);
+ break;
+ case EVENT_BETRAYAL_INTRO_3:
+ Talk(SAY_DRAKURU_1);
+ DoCastAOE(SPELL_DROP_DISGUISE);
+ events.ScheduleEvent(EVENT_BETRAYAL_INTRO_4, 9600ms);
+ break;
+ case EVENT_BETRAYAL_INTRO_4:
+ {
+ Talk(SAY_DRAKURU_2);
+ Talk(SAY_DRAKURU_3);
+ me->SetImmuneToPC(false);
+ std::list<Creature*> creatures;
+ me->GetCreatureListWithEntryInGrid(creatures, NPC_TOTALLY_GENERIC_BUNNY, 55.0f);
+ for (Creature* creature : creatures)
+ creature->CastSpell(creature, SPELL_SCOURGE_SPOTLIGHT, true);
+ break;
+ }
+ case EVENT_BETRAYAL_EPILOGUE_1:
+ {
+ Talk(SAY_DRAKURU_5);
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_2, 4800ms);
+ DoAction(ACTION_REMOVE_SPOTLIGHTS);
+ break;
+ }
+ case EVENT_BETRAYAL_EPILOGUE_2:
+ Talk(SAY_DRAKURU_6);
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_3, 1800ms);
+ break;
+ case EVENT_BETRAYAL_EPILOGUE_3:
+ DoCastSelf(SPELL_THROW_PORTAL_CRYSTAL, true);
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_4, 3600ms);
+ break;
+ case EVENT_BETRAYAL_EPILOGUE_4:
+ me->SummonCreature(NPC_LICH_KING, 6140.4233, -2010.9938, 589.1911, 6.126106, TEMPSUMMON_TIMED_DESPAWN, 77'000);
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_5, 8400ms);
+ break;
+ case EVENT_BETRAYAL_EPILOGUE_5:
+ Talk(SAY_DRAKURU_7);
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_6, 9600ms);
+ break;
+ case EVENT_BETRAYAL_EPILOGUE_6:
+ if (Creature* lich = ObjectAccessor::GetCreature(*me, _lichGUID))
+ {
+ lich->AI()->Talk(SAY_LICH_7);
+ lich->AI()->Talk(SAY_LICH_8, 5400ms);
+ }
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_7, 7800ms);
+ break;
+ case EVENT_BETRAYAL_EPILOGUE_7:
+ if (Creature* lich = ObjectAccessor::GetCreature(*me, _lichGUID))
+ lich->CastSpell(me, SPELL_TOUCH_OF_DEATH, false);
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_8, 4200ms);
+ break;
+ case EVENT_BETRAYAL_EPILOGUE_8:
+ me->SetVisible(false);
+ if (Creature* lich = ObjectAccessor::GetCreature(*me, _lichGUID))
+ {
+ lich->AI()->Talk(SAY_LICH_9, 3600ms);
+ lich->AI()->Talk(SAY_LICH_10, 8400ms);
+ lich->AI()->Talk(SAY_LICH_11, 22800ms);
+ lich->AI()->Talk(SAY_LICH_12, 27600ms);
+ }
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_9, 32600ms);
+ events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_10, 37200ms);
+ break;
+ case EVENT_BETRAYAL_EPILOGUE_9:
+ if (Creature* lich = ObjectAccessor::GetCreature(*me, _lichGUID))
+ lich->GetMotionMaster()->MovePoint(0, 6141.2393, -2011.2728, 589.8653);
+ break;
+ case EVENT_BETRAYAL_EPILOGUE_10:
+ EnterEvadeMode(EVADE_REASON_OTHER);
+ break;
+ }
- if (me->GetFaction() == FACTION_FRIENDLY || me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED))
- return;
+ if (me->GetFaction() == 2082 || me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED))
+ return;
- if (!UpdateVictim())
- return;
+ if (!UpdateVictim())
+ return;
- switch (events.ExecuteEvent())
- {
- case EVENT_BETRAYAL_SHADOW_BOLT:
- if (!me->IsWithinMeleeRange(me->GetVictim()))
- me->CastSpell(me->GetVictim(), SPELL_SHADOW_BOLT, false);
- events.Repeat(2s);
- break;
- case EVENT_BETRAYAL_CRYSTAL:
- if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
- me->CastSpell(player, SPELL_THROW_BRIGHT_CRYSTAL, true);
- events.Repeat(6s, 15s);
- break;
- case EVENT_BETRAYAL_COMBAT_TALK:
- Talk(SAY_DRAKURU_4);
- events.Repeat(20s);
- break;
- }
+ scheduler.Update(diff);
+ DoMeleeAttackIfReady();
+ }
- DoMeleeAttackIfReady();
- }
- };
+private:
+ SummonList _summons;
+ ObjectGuid _playerGUID;
+ ObjectGuid _lichGUID;
+ BetrayalState _state;
};
/*####
@@ -864,11 +945,32 @@ class spell_scourge_disguise_instability : public AuraScript
}
};
+// 54105 - Blight Fog
+class spell_blight_fog : public SpellScript
+{
+ PrepareSpellScript(spell_blight_fog);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if([](WorldObject* target) -> bool
+ {
+ float z = target->GetPositionZ();
+ bool isInBlightFog = (582.0f <= z && z <= 583.0f) || (586.0f <= z && z <= 587.0f);
+ return !isInBlightFog;
+ });
+ }
+
+ void Register() override
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blight_fog::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+};
+
void AddSC_zuldrak()
{
new npc_finklestein();
new go_finklestein_cauldron();
- new npc_overlord_drakuru_betrayal();
+ RegisterCreatureAI(npc_overlord_drakuru_betrayal);
new npc_drakuru_shackles();
new npc_captured_rageclaw();
new npc_released_offspring_harkoa();
@@ -876,4 +978,5 @@ void AddSC_zuldrak()
new go_scourge_enclosure();
RegisterSpellScript(spell_scourge_disguise_instability);
+ RegisterSpellScript(spell_blight_fog);
}