fix(Scripts/BRD): Magmus, Emperor, Priestess, Arena improvements (#8102)

This commit is contained in:
patou01
2021-12-16 12:14:29 +01:00
committed by GitHub
parent 886ea162e8
commit 9b3b61139a
14 changed files with 1203 additions and 332 deletions
@@ -0,0 +1,43 @@
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1632675335691344600');
-- add yells emperor
DELETE FROM `creature_text` WHERE `CreatureID` = 9019;
INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`COMMENT`) VALUES
(9019,0,0,'Come to aid the Throne!',14,0,100,0,0,0,0,0,'Aggro line council alive'),
(9019,1,0,'I will crush you into little tiny pieces!',14,0,100,0,0,0,5457,0,'Aggro line council dead'),
(9019,2,0,'Hail to the king, baby!',14,0,100,0,0,0,5431,0,'Killing player'),
(9019,3,0,'Your efforts are utterly pointless, fools! You will never be able to defeat me!',14,0,100,0,0,0,5312,0,'Killing council 1'),
(9019,4,0,'They were just getting in the way anyways.',14,0,100,0,0,0,5313,0,'Killing council 2'),
(9019,5,0,'Ha! You can''t even begin to imagine the futility of your efforts.',14,0,100,0,0,0,5314,0,'Killing council 3'),
(9019,6,0,'Is that the best you can do? Do you really expect that you could defeat someone as awe inspiring as me?',14,0,100,0,0,0,5315,0,'Killing council 4'),
(9019,7,0,'Thank you for clearing out those foolish senators. Now prepare to meet your doom at the hands of Ragnaros'' most powerful servant.',14,0,100,0,0,0,5311,0,'Killing all council');
-- priestess yell
UPDATE `creature_template` SET `ScriptName` = 'boss_high_priestess_thaurissan' WHERE (`entry` = 10076);
DELETE FROM `creature_text` where `CreatureID` = 10076;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `BroadcastTextId`)
VALUES (10076, 0, 0, 'You will not harm Emperor Thaurissan!', 14, 0);
-- ironhand guardians, add cpp script, remove smartAI and smartscripts
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'brd_ironhand_guardian' WHERE (`entry` = 8982);
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 8982) AND (`source_type` = 0) AND (`id` IN (0, 1));
-- flamekeepers
DELETE FROM `pool_template` WHERE `entry` = 1550;
INSERT INTO `pool_template` (`entry`, `max_limit`, `description`)
VALUES (1550, 2, 'BRD Lyceum shadowforge flame keepers');
DELETE FROM `pool_creature` WHERE `guid` IN (47302, 47303, 91119, 91120);
INSERT INTO `pool_creature` (`guid`, `pool_entry`, `chance`, `description`) VALUES
(47302, 1550, 0, 'BRD Lyceum shadowforge flame keepers'),
(47303, 1550, 0, 'BRD Lyceum shadowforge flame keepers'),
(91119, 1550, 0, 'BRD Lyceum shadowforge flame keepers'),
(91120, 1550, 0, 'BRD Lyceum shadowforge flame keepers');
-- moira and priestess are mages, not paladins.
UPDATE `creature_template` SET `unit_class` = 8 WHERE `entry` IN (8929, 10076);
-- scripts for bosses in arena
UPDATE `creature_template` SET `ScriptName` = 'boss_eviscerator' WHERE (`entry` = 9029);
UPDATE `creature_template` SET `ScriptName` = 'boss_okthor' WHERE (`entry` = 9030);
UPDATE `creature_template` SET `ScriptName` = 'boss_hedrum' WHERE (`entry` = 9032);
@@ -23,16 +23,18 @@
#include "ScriptedGossip.h" #include "ScriptedGossip.h"
#include "WorldSession.h" #include "WorldSession.h"
enum ShadowforgeBrazier enum IronhandData
{ {
SAY_MAGMUS_BRAZIER_LIT = 0 IRONHAND_FLAMES_TIMER = 16000,
IRONHAND_FLAMES_TIMER_RAND = 3000,
IRONHAND_N_GROUPS = 3,
SPELL_GOUT_OF_FLAMES = 15529
}; };
//go_shadowforge_brazier
class go_shadowforge_brazier : public GameObjectScript class go_shadowforge_brazier : public GameObjectScript
{ {
public: public:
go_shadowforge_brazier() : GameObjectScript("go_shadowforge_brazier") { } go_shadowforge_brazier() : GameObjectScript("go_shadowforge_brazier") {}
bool OnGossipHello(Player* /*player*/, GameObject* go) override bool OnGossipHello(Player* /*player*/, GameObject* go) override
{ {
@@ -46,68 +48,101 @@ public:
return false; return false;
} }
// Check if the opposite brazier is lit - if it is, open the gates. // should only happen on first brazier
if ((go->GetGUID() == northBrazier->GetGUID() && southBrazier->GetGoState() == GO_STATE_ACTIVE) if (instance->GetData(TYPE_LYCEUM) == NOT_STARTED)
|| (go->GetGUID() == southBrazier->GetGUID() && northBrazier->GetGoState() == GO_STATE_ACTIVE))
{ {
if (instance->GetData(TYPE_LYCEUM) == IN_PROGRESS) instance->SetData(TYPE_LYCEUM, IN_PROGRESS);
{
instance->SetData(TYPE_LYCEUM, DONE);
}
else
{
instance->SetData(TYPE_LYCEUM, IN_PROGRESS);
}
if (Creature* magmus = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_MAGMUS)))
{
if (magmus->IsAlive())
{
magmus->AI()->Talk(SAY_MAGMUS_BRAZIER_LIT);
}
}
instance->HandleGameObject(instance->GetGuidData(DATA_GOLEM_DOOR_N), true);
instance->HandleGameObject(instance->GetGuidData(DATA_GOLEM_DOOR_S), true);
} }
// Check if the opposite brazier is lit - if it is, open the gates.
if ((go->GetGUID() == northBrazier->GetGUID() && southBrazier->GetGoState() == GO_STATE_ACTIVE) || (go->GetGUID() == southBrazier->GetGUID() && northBrazier->GetGoState() == GO_STATE_ACTIVE))
{
instance->SetData(TYPE_LYCEUM, DONE);
}
return false;
} }
return false; return false;
};
};
class ironhand_guardian : public CreatureScript
{
public:
ironhand_guardian() : CreatureScript("brd_ironhand_guardian") {}
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockDepthsAI<ironhand_guardianAI>(creature);
} }
struct ironhand_guardianAI : public CreatureAI
{
ironhand_guardianAI(Creature* creature) : CreatureAI(creature) {}
bool flames_enabled = false;
void SetData(uint32 id, uint32 value) override
{
if (id == 0)
{
if (value == 0 || value == 1)
{
flames_enabled = (bool) (value);
events.ScheduleEvent(SPELL_GOUT_OF_FLAMES, urand(1, IRONHAND_N_GROUPS) * IRONHAND_FLAMES_TIMER / IRONHAND_N_GROUPS);
}
}
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
if (flames_enabled)
{
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case SPELL_GOUT_OF_FLAMES:
DoCast(SPELL_GOUT_OF_FLAMES);
events.RescheduleEvent(SPELL_GOUT_OF_FLAMES, urand(IRONHAND_FLAMES_TIMER - IRONHAND_FLAMES_TIMER_RAND, IRONHAND_FLAMES_TIMER + IRONHAND_FLAMES_TIMER_RAND));
break;
default:
break;
}
}
}
}
EventMap events;
};
}; };
enum eChallenge struct Wave
{ {
QUEST_THE_CHALLENGE = 9015, uint32 entry;
GO_BANNER_OF_PROVOCATION = 181058, uint32 amount;
GO_ARENA_SPOILS = 181074,
NPC_GRIMSTONE = 10096,
NPC_THELDREN = 16059,
}; };
uint32 theldrenTeam[] = static Wave RingMobs[] = // different amounts based on the type
{ {
16053, 16055, 16050, 16051, 16049, 16052, 16054, 16058 {NPC_DREDGE_WORM, 3},
}; {NPC_DEEP_STINGER, 3},
{NPC_DARK_SCREECHER, 3},
uint32 RingMob[] = {NPC_THUNDERSNOUT, 2},
{ {NPC_CAVE_CREEPER, 3},
8925, // Dredge Worm {NPC_BORER_BEETLE, 6}};
8926, // Deep Stinger
8927, // Dark Screecher
8928, // Burrowing Thundersnout
8933, // Cave Creeper
8932, // Borer Beetle
};
uint32 RingBoss[] = uint32 RingBoss[] =
{ {
9027, // Gorosh NPC_GOROSH,
9028, // Grizzle NPC_GRIZZLE,
9029, // Eviscerator NPC_EVISCERATOR,
9030, // Ok'thor NPC_OKTHOR,
9031, // Anub'shiah NPC_ANUBSHIAH,
9032, // Hedrum NPC_HEDRUM
}; };
class at_ring_of_law : public AreaTriggerScript class at_ring_of_law : public AreaTriggerScript
@@ -119,13 +154,18 @@ public:
{ {
if (InstanceScript* instance = player->GetInstanceScript()) if (InstanceScript* instance = player->GetInstanceScript())
{ {
time_t now = time(nullptr);
if (instance->GetData(TYPE_RING_OF_LAW) == IN_PROGRESS || instance->GetData(TYPE_RING_OF_LAW) == DONE) if (instance->GetData(TYPE_RING_OF_LAW) == IN_PROGRESS || instance->GetData(TYPE_RING_OF_LAW) == DONE)
{
return false; return false;
}
if (now - instance->GetData(DATA_TIME_RING_FAIL) < 2 * 60) // in case of wipe, so people can rez.
{
return false;
}
instance->SetData(TYPE_RING_OF_LAW, IN_PROGRESS); instance->SetData(TYPE_RING_OF_LAW, IN_PROGRESS);
player->SummonCreature(NPC_GRIMSTONE, 625.559f, -205.618f, -52.735f, 2.609f, TEMPSUMMON_DEAD_DESPAWN, 0); return true;
return false;
} }
return false; return false;
} }
@@ -157,9 +197,11 @@ public:
npc_grimstoneAI(Creature* creature) : npc_escortAI(creature), summons(me) npc_grimstoneAI(Creature* creature) : npc_escortAI(creature), summons(me)
{ {
instance = creature->GetInstanceScript(); instance = creature->GetInstanceScript();
MobSpawnId = rand() % 6; MobSpawnId = instance ? instance->GetData(DATA_ARENA_MOBS) : urand(0, 5);
BossSpawnId = instance ? instance->GetData(DATA_ARENA_BOSS) : urand(0, 5);
eventPhase = 0; eventPhase = 0;
eventTimer = 1000; eventTimer = 1000;
resetTimer = 0;
theldrenEvent = false; theldrenEvent = false;
summons.DespawnAll(); summons.DespawnAll();
} }
@@ -169,7 +211,9 @@ public:
uint8 eventPhase; uint8 eventPhase;
uint32 eventTimer; uint32 eventTimer;
uint32 resetTimer;
uint8 MobSpawnId; uint8 MobSpawnId;
uint8 BossSpawnId;
bool theldrenEvent; bool theldrenEvent;
void Reset() override void Reset() override
@@ -189,7 +233,10 @@ public:
summons.Despawn(summon); summons.Despawn(summon);
// All Summons killed, next phase // All Summons killed, next phase
if (summons.empty()) if (summons.empty())
{
resetTimer = 0;
eventTimer = 5000; eventTimer = 5000;
}
} }
void WaypointReached(uint32 waypointId) override void WaypointReached(uint32 waypointId) override
@@ -243,7 +290,45 @@ public:
me->SummonCreature(theldrenTeam[i], 644.300f, -175.989f, -53.739f, 3.418f, TEMPSUMMON_DEAD_DESPAWN, 0); me->SummonCreature(theldrenTeam[i], 644.300f, -175.989f, -53.739f, 3.418f, TEMPSUMMON_DEAD_DESPAWN, 0);
} }
else else
me->SummonCreature(RingBoss[rand() % 6], 644.300f, -175.989f, -53.739f, 3.418f, TEMPSUMMON_DEAD_DESPAWN, 0); me->SummonCreature(RingBoss[BossSpawnId], 644.300f, -175.989f, -53.739f, 3.418f, TEMPSUMMON_DEAD_DESPAWN, 0);
resetTimer = 30000;
}
bool updateReset(uint32 diff)
{
// as long as the summoned creatures have someone to attack, we reset the timer.
// once they don't find anyone, the timer will count down until it is smaller than diff and reset.
bool doReset = false;
if (resetTimer > 0)
{
for (const auto& sum : summons)
{
if (Creature* creature = ObjectAccessor::GetCreature(*me, sum))
{
if (creature->IsAlive() && creature->GetVictim())
{
resetTimer = 30000;
break; // only need to find one.
}
}
}
resetTimer -= diff;
if (resetTimer <= diff)
{
doReset = true;
}
}
return doReset;
}
void SpawnWave(uint32 mobId)
{
for (uint32 i = 0; i < RingMobs[mobId].amount; i++)
{
me->SummonCreature(RingMobs[mobId].entry, 608.960f + 0.4f * i, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0);
}
resetTimer = 30000;
} }
void UpdateEscortAI(uint32 diff) override void UpdateEscortAI(uint32 diff) override
@@ -251,6 +336,17 @@ public:
if (!instance) if (!instance)
return; return;
// reset if our mobs don't have a target.
if (updateReset(diff))
{
summons.DespawnAll();
HandleGameObject(DATA_ARENA4, true);
HandleGameObject(DATA_ARENA3, false);
HandleGameObject(DATA_ARENA2, false);
HandleGameObject(DATA_ARENA1, false);
instance->SetData(TYPE_RING_OF_LAW, FAIL);
}
if (eventTimer) if (eventTimer)
{ {
if (eventTimer <= diff) if (eventTimer <= diff)
@@ -277,35 +373,30 @@ public:
case 4: case 4:
SetEscortPaused(false); SetEscortPaused(false);
me->SetVisible(false); me->SetVisible(false);
me->SummonCreature(RingMob[MobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0); SpawnWave(MobSpawnId); // wave 1
eventTimer = 8000; eventTimer = 15000;
break; break;
case 5: case 5:
me->SummonCreature(RingMob[MobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0); SpawnWave(MobSpawnId); // wave 2
me->SummonCreature(RingMob[MobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0); eventTimer = 0; // will be set from SummonedCreatureDies
eventTimer = 8000;
break; break;
case 6: case 6:
me->SummonCreature(RingMob[MobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0);
eventTimer = 0;
break;
case 7:
me->SetVisible(true); me->SetVisible(true);
HandleGameObject(DATA_ARENA1, false); HandleGameObject(DATA_ARENA1, false);
Talk(SAY_TEXT6); Talk(SAY_TEXT6);
SetEscortPaused(false); SetEscortPaused(false);
eventTimer = 0; eventTimer = 0;
break; break;
case 8: case 7:
HandleGameObject(DATA_ARENA2, true); HandleGameObject(DATA_ARENA2, true);
eventTimer = 5000; eventTimer = 5000;
break; break;
case 9: case 8:
me->SetVisible(false); me->SetVisible(false);
SummonBoss(); SummonBoss();
eventTimer = 0; eventTimer = 0;
break; break;
case 10: case 9:
if (theldrenEvent) if (theldrenEvent)
{ {
if (GameObject* go = me->SummonGameObject(GO_ARENA_SPOILS, 596.48f, -187.91f, -54.14f, 4.9f, 0.0f, 0.0f, 0.0f, 0.0f, 300)) if (GameObject* go = me->SummonGameObject(GO_ARENA_SPOILS, 596.48f, -187.91f, -54.14f, 4.9f, 0.0f, 0.0f, 0.0f, 0.0f, 300))
@@ -614,4 +705,5 @@ void AddSC_blackrock_depths()
new npc_phalanx(); new npc_phalanx();
new npc_lokhtos_darkbargainer(); new npc_lokhtos_darkbargainer();
new npc_rocknot(); new npc_rocknot();
new ironhand_guardian();
} }
@@ -21,6 +21,13 @@
#include "CreatureAIImpl.h" #include "CreatureAIImpl.h"
#define BRDScriptName "instance_blackrock_depths" #define BRDScriptName "instance_blackrock_depths"
enum FactionIds
{
FACTION_NEUTRAL = 674,
FACTION_HOSTILE = 754,
FACTION_FRIEND = 35
};
enum BRDBosses enum BRDBosses
{ {
BOSS_AMBASSADOR_FLAMELASH = 0, BOSS_AMBASSADOR_FLAMELASH = 0,
@@ -56,22 +63,86 @@ enum DataTypes
DATA_SF_BRAZIER_N = 25, DATA_SF_BRAZIER_N = 25,
DATA_SF_BRAZIER_S = 26, DATA_SF_BRAZIER_S = 26,
DATA_MOIRA = 27, DATA_MOIRA = 27,
DATA_PRIESTESS = 28,
DATA_OPEN_COFFER_DOORS = 30, DATA_OPEN_COFFER_DOORS = 30,
DATA_GOLEM_LORD_ARGELMACH_INIT = 31, DATA_GOLEM_LORD_ARGELMACH_INIT = 31,
DATA_GOLEM_LORD_ARGELMACH_ADDS = 32, DATA_GOLEM_LORD_ARGELMACH_ADDS = 32,
DATA_MAGMUS = 33, DATA_MAGMUS = 33,
DATA_COREN = 34 DATA_COREN = 34,
DATA_ANUBSHIAH,
DATA_EVISCERATOR,
DATA_GOROSH,
DATA_GRIZZLE,
DATA_HEDRUM,
DATA_OKTHOR,
DATA_TIME_RING_FAIL,
DATA_ARENA_MOBS,
DATA_ARENA_BOSS
}; };
enum CreatureIds enum Creatures
{ {
NPC_MAGMUS = 9938 NPC_EMPEROR = 9019,
NPC_PHALANX = 9502,
NPC_ANGERREL = 9035,
NPC_DOPEREL = 9040,
NPC_HATEREL = 9034,
NPC_VILEREL = 9036,
NPC_SEETHREL = 9038,
NPC_GLOOMREL = 9037,
NPC_DOOMREL = 9039,
NPC_MOIRA = 8929,
NPC_PRIESTESS = 10076,
NPC_WATCHMAN_DOOMGRIP = 9476,
NPC_WEAPON_TECHNICIAN = 8920,
NPC_DOOMFORGE_ARCANASMITH = 8900,
NPC_RAGEREAVER_GOLEM = 8906,
NPC_WRATH_HAMMER_CONSTRUCT = 8907,
NPC_GOLEM_LORD_ARGELMACH = 8983,
NPC_COREN_DIREBREW = 23872,
NPC_IRONHAND_GUARDIAN = 8982,
NPC_ARENA_SPECTATOR = 8916,
NPC_SHADOWFORGE_PEASANT = 8896,
NPC_SHADOWFORCE_CITIZEN = 8902,
NPC_SHADOWFORGE_SENATOR = 8904,
NPC_MAGMUS = 9938,
NPC_DREDGE_WORM = 8925,
NPC_DEEP_STINGER = 8926,
NPC_DARK_SCREECHER = 8927,
NPC_THUNDERSNOUT = 8928,
NPC_BORER_BEETLE = 8932,
NPC_CAVE_CREEPER = 8933,
NPC_GOROSH = 9027,
NPC_GRIZZLE = 9028,
NPC_EVISCERATOR = 9029,
NPC_OKTHOR = 9030,
NPC_ANUBSHIAH = 9031,
NPC_HEDRUM = 9032
}; };
enum eChallenge
{
QUEST_THE_CHALLENGE = 9015,
GO_BANNER_OF_PROVOCATION = 181058,
GO_ARENA_SPOILS = 181074,
NPC_GRIMSTONE = 10096,
NPC_THELDREN = 16059,
};
const uint32 theldrenTeam[] = {16053, 16055, 16050, 16051, 16049, 16052, 16054, 16058};
template <class AI, class T> template <class AI, class T>
inline AI* GetBlackrockDepthsAI(T* obj) inline AI* GetBlackrockDepthsAI(T* obj)
{ {
@@ -21,11 +21,20 @@
enum Spells enum Spells
{ {
SPELL_SHADOWBOLT = 17228, SPELL_SHADOWBOLT = 15472,
SPELL_CURSEOFTONGUES = 15470, SPELL_CURSE_TONGUES = 15470,
SPELL_CURSEOFWEAKNESS = 17227, SPELL_CURSE_WEAKNESS = 12493,
SPELL_DEMONARMOR = 11735, SPELL_DEMON_ARMOR = 13787,
SPELL_ENVELOPINGWEB = 15471 SPELL_ENVELOPING_WEB = 15471
};
enum Timers
{
TIMER_SHADOWBOLT = 7000,
TIMER_CURSE_TONGUES = 24000,
TIMER_CURSE_WEAKNESS = 12000,
TIMER_DEMON_ARMOR = 3000, // virtually only cast once
TIMER_ENVELOPING_WEB = 16000
}; };
class boss_anubshiah : public CreatureScript class boss_anubshiah : public CreatureScript
@@ -38,75 +47,68 @@ public:
return GetBlackrockDepthsAI<boss_anubshiahAI>(creature); return GetBlackrockDepthsAI<boss_anubshiahAI>(creature);
} }
struct boss_anubshiahAI : public ScriptedAI struct boss_anubshiahAI : public BossAI
{ {
boss_anubshiahAI(Creature* creature) : ScriptedAI(creature) { } boss_anubshiahAI(Creature* creature) : BossAI(creature, DATA_ANUBSHIAH) { }
uint32 ShadowBolt_Timer; void EnterCombat(Unit* /*who*/) override
uint32 CurseOfTongues_Timer;
uint32 CurseOfWeakness_Timer;
uint32 DemonArmor_Timer;
uint32 EnvelopingWeb_Timer;
void Reset() override
{ {
ShadowBolt_Timer = 7000; _EnterCombat();
CurseOfTongues_Timer = 24000; events.ScheduleEvent(SPELL_SHADOWBOLT, 0.2 * (int)TIMER_SHADOWBOLT);
CurseOfWeakness_Timer = 12000; events.ScheduleEvent(SPELL_CURSE_TONGUES, 0.2 * (int)TIMER_CURSE_TONGUES);
DemonArmor_Timer = 3000; events.ScheduleEvent(SPELL_CURSE_WEAKNESS, 0.2 * (int)TIMER_CURSE_WEAKNESS);
EnvelopingWeb_Timer = 16000; events.ScheduleEvent(SPELL_DEMON_ARMOR, 0.2 * (int)TIMER_DEMON_ARMOR);
events.ScheduleEvent(SPELL_ENVELOPING_WEB, 0.2 * (int)TIMER_ENVELOPING_WEB);
} }
void EnterCombat(Unit* /*who*/) override { }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
//Return since we have no target //Return since we have no target
if (!UpdateVictim()) if (!UpdateVictim())
{
return; return;
//ShadowBolt_Timer
if (ShadowBolt_Timer <= diff)
{
DoCastVictim(SPELL_SHADOWBOLT);
ShadowBolt_Timer = 7000;
} }
else ShadowBolt_Timer -= diff; events.Update(diff);
//CurseOfTongues_Timer if (me->HasUnitState(UNIT_STATE_CASTING))
if (CurseOfTongues_Timer <= diff)
{ {
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) return;
DoCast(target, SPELL_CURSEOFTONGUES);
CurseOfTongues_Timer = 18000;
} }
else CurseOfTongues_Timer -= diff; while (uint32 eventId = events.ExecuteEvent())
//CurseOfWeakness_Timer
if (CurseOfWeakness_Timer <= diff)
{ {
DoCastVictim(SPELL_CURSEOFWEAKNESS); switch (eventId)
CurseOfWeakness_Timer = 45000; {
case SPELL_SHADOWBOLT:
DoCastVictim(SPELL_SHADOWBOLT);
events.ScheduleEvent(SPELL_SHADOWBOLT, urand(TIMER_SHADOWBOLT - 2000, TIMER_SHADOWBOLT + 2000));
break;
case SPELL_CURSE_TONGUES:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
DoCast(target, SPELL_CURSE_TONGUES);
}
events.ScheduleEvent(SPELL_CURSE_TONGUES, urand(TIMER_CURSE_TONGUES - 2000, TIMER_CURSE_TONGUES + 2000));
break;
case SPELL_CURSE_WEAKNESS:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
DoCast(target, SPELL_CURSE_WEAKNESS);
}
events.ScheduleEvent(SPELL_CURSE_WEAKNESS, urand(TIMER_CURSE_WEAKNESS - 2000, TIMER_CURSE_WEAKNESS + 2000));
break;
case SPELL_DEMON_ARMOR:
DoCast(me, SPELL_DEMON_ARMOR);
events.ScheduleEvent(SPELL_DEMON_ARMOR, TIMER_DEMON_ARMOR);
break;
case SPELL_ENVELOPING_WEB:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_ENVELOPING_WEB);
events.ScheduleEvent(SPELL_ENVELOPING_WEB, urand(TIMER_ENVELOPING_WEB - 2000, TIMER_ENVELOPING_WEB + 2000));
break;
default:
break;
}
} }
else CurseOfWeakness_Timer -= diff;
//DemonArmor_Timer
if (DemonArmor_Timer <= diff)
{
DoCast(me, SPELL_DEMONARMOR);
DemonArmor_Timer = 300000;
}
else DemonArmor_Timer -= diff;
//EnvelopingWeb_Timer
if (EnvelopingWeb_Timer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_ENVELOPINGWEB);
EnvelopingWeb_Timer = 12000;
}
else EnvelopingWeb_Timer -= diff;
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
}; };
@@ -21,16 +21,19 @@
enum Yells enum Yells
{ {
SAY_AGGRO = 0, YELL_SENATORS_ALIVE = 0,
SAY_SLAY = 1 YELL_SENATORS_DEAD = 1,
SAY_SLAY = 2
}; };
enum Spells enum Spells
{ {
SPELL_HANDOFTHAURISSAN = 17492, SPELL_HANDOFTHAURISSAN = 17492,
SPELL_AVATAROFFLAME = 15636 SPELL_AVATAROFFLAME = 15636
}; };
#define DATA_PERCENT_DEAD_SENATORS 0
class boss_emperor_dagran_thaurissan : public CreatureScript class boss_emperor_dagran_thaurissan : public CreatureScript
{ {
public: public:
@@ -41,29 +44,27 @@ public:
return GetBlackrockDepthsAI<boss_draganthaurissanAI>(creature); return GetBlackrockDepthsAI<boss_draganthaurissanAI>(creature);
} }
struct boss_draganthaurissanAI : public ScriptedAI struct boss_draganthaurissanAI : public BossAI
{ {
boss_draganthaurissanAI(Creature* creature) : ScriptedAI(creature) uint32 hasYelled = 0;
{ uint32 SenatorYells[5] = {3, 4, 5, 6, 7}; // IDs in creature_text database
instance = me->GetInstanceScript();
}
InstanceScript* instance; boss_draganthaurissanAI(Creature* creature) : BossAI(creature, DATA_EMPEROR){}
uint32 HandOfThaurissan_Timer;
uint32 AvatarOfFlame_Timer;
//uint32 Counter;
void Reset() override
{
HandOfThaurissan_Timer = 4000;
AvatarOfFlame_Timer = 25000;
//Counter= 0;
}
void EnterCombat(Unit* /*who*/) override void EnterCombat(Unit* /*who*/) override
{ {
Talk(SAY_AGGRO); if (hasYelled != 5)
{
Talk(YELL_SENATORS_ALIVE);
}
else
{
Talk(YELL_SENATORS_DEAD);
}
me->CallForHelp(VISIBLE_RANGE); me->CallForHelp(VISIBLE_RANGE);
events.ScheduleEvent(SPELL_HANDOFTHAURISSAN, urand(4000, 7000));
events.ScheduleEvent(SPELL_AVATAROFFLAME, urand(10000, 12000));
} }
void KilledUnit(Unit* /*victim*/) override void KilledUnit(Unit* /*victim*/) override
@@ -71,11 +72,27 @@ public:
Talk(SAY_SLAY); Talk(SAY_SLAY);
} }
void SetData(uint32 type, uint32 data) override
{
if (type == DATA_PERCENT_DEAD_SENATORS)
{
if (data >= 20 * (hasYelled + 1)) // map the 5 yells to %. Yell after 20,40,60,80,100%
{
if (hasYelled < 5)
{
Talk(SenatorYells[hasYelled]);
}
hasYelled++;
}
}
}
void JustDied(Unit* /*killer*/) override void JustDied(Unit* /*killer*/) override
{ {
if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MOIRA))) if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MOIRA)))
{ {
Moira->AI()->EnterEvadeMode(); Moira->AI()->EnterEvadeMode();
Moira->AI()->Talk(0);
Moira->SetFaction(FACTION_FRIENDLY); Moira->SetFaction(FACTION_FRIENDLY);
} }
} }
@@ -86,33 +103,28 @@ public:
if (!UpdateVictim()) if (!UpdateVictim())
return; return;
if (HandOfThaurissan_Timer <= diff) events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{ {
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) switch (eventId)
DoCast(target, SPELL_HANDOFTHAURISSAN); {
case SPELL_HANDOFTHAURISSAN:
//3 Hands of Thaurissan will be cast DoCast(SelectTarget(SELECT_TARGET_RANDOM), SPELL_HANDOFTHAURISSAN);
//if (Counter < 3) //DoCastVictim(SPELL_HANDOFTHAURISSAN);
//{ events.ScheduleEvent(SPELL_HANDOFTHAURISSAN, urand(4000, 7000));
// HandOfThaurissan_Timer = 1000; break;
// ++Counter; case SPELL_AVATAROFFLAME:
//} DoCastSelf(SPELL_AVATAROFFLAME);
//else events.ScheduleEvent(SPELL_AVATAROFFLAME, urand(23000, 27000));
//{ break;
HandOfThaurissan_Timer = 5000; default:
//Counter = 0; break;
//} }
} }
else HandOfThaurissan_Timer -= diff;
//AvatarOfFlame_Timer
if (AvatarOfFlame_Timer <= diff)
{
DoCastVictim(SPELL_AVATAROFFLAME);
AvatarOfFlame_Timer = 18000;
}
else AvatarOfFlame_Timer -= diff;
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
}; };
@@ -0,0 +1,110 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "blackrock_depths.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h"
enum Spells
{
SPELL_SHADOWBOLT_VOLLEY = 15245,
SPELL_REND = 14331,
SPELL_SHIELD = 7121
};
enum Timers
{
TIMER_SHADOWBOLT_VOLLEY = 7000,
TIMER_REND = 20000,
TIMER_SHIELD = 12000
};
class boss_eviscerator : public CreatureScript
{
public:
boss_eviscerator() : CreatureScript("boss_eviscerator") {}
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockDepthsAI<boss_evisceratorAI>(creature);
}
struct boss_evisceratorAI : public BossAI
{
boss_evisceratorAI(Creature* creature) : BossAI(creature, DATA_EVISCERATOR) {}
bool SpellShieldReady = false;
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
events.ScheduleEvent(SPELL_SHADOWBOLT_VOLLEY, 0.2 * (int)TIMER_SHADOWBOLT_VOLLEY);
events.ScheduleEvent(SPELL_REND, 0.2 * (int) TIMER_REND);
events.ScheduleEvent(SPELL_SHIELD, 0.2 * (int) TIMER_SHIELD);
}
void DamageTaken(Unit* /* doneBy */, uint32& /* damage */, DamageEffectType /* damagetype */, SpellSchoolMask damageSchoolMask) override
{
if ((damageSchoolMask & SPELL_SCHOOL_MASK_MAGIC) && SpellShieldReady)
{
DoCast(SPELL_SHIELD);
SpellShieldReady = false;
events.ScheduleEvent(SPELL_SHIELD, TIMER_SHIELD);
}
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
{
return;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case SPELL_SHADOWBOLT_VOLLEY:
DoCastVictim(SPELL_SHADOWBOLT_VOLLEY);
events.ScheduleEvent(SPELL_SHADOWBOLT_VOLLEY, urand(TIMER_SHADOWBOLT_VOLLEY - 2000, TIMER_SHADOWBOLT_VOLLEY + 2000));
break;
case SPELL_REND:
DoCastVictim(SPELL_REND);
events.ScheduleEvent(SPELL_REND, urand(TIMER_REND - 2000, TIMER_REND + 2000));
break;
case SPELL_SHIELD:
SpellShieldReady = true;
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_eviscerator()
{
new boss_eviscerator();
}
@@ -21,8 +21,16 @@
enum Spells enum Spells
{ {
SPELL_WHIRLWIND = 15589, SPELL_WHIRLWIND = 15589,
SPELL_MORTALSTRIKE = 24573 SPELL_MORTALSTRIKE = 15708,
SPELL_BLOODLUST = 21049
};
enum Timers
{
TIMER_WHIRLWIND = 12000,
TIMER_MORTAL = 22000,
TIMER_BLOODLUST = 30000
}; };
class boss_gorosh_the_dervish : public CreatureScript class boss_gorosh_the_dervish : public CreatureScript
@@ -35,45 +43,62 @@ public:
return GetBlackrockDepthsAI<boss_gorosh_the_dervishAI>(creature); return GetBlackrockDepthsAI<boss_gorosh_the_dervishAI>(creature);
} }
struct boss_gorosh_the_dervishAI : public ScriptedAI struct boss_gorosh_the_dervishAI : public BossAI
{ {
boss_gorosh_the_dervishAI(Creature* creature) : ScriptedAI(creature) { } boss_gorosh_the_dervishAI(Creature* creature) : BossAI(creature, DATA_GOROSH) { }
uint32 WhirlWind_Timer; uint32 nextWhirlwindTime;
uint32 MortalStrike_Timer;
void Reset() override
{
WhirlWind_Timer = 12000;
MortalStrike_Timer = 22000;
}
void EnterCombat(Unit* /*who*/) override void EnterCombat(Unit* /*who*/) override
{ {
_EnterCombat();
events.ScheduleEvent(SPELL_WHIRLWIND, 0.2 * (int) TIMER_WHIRLWIND);
events.ScheduleEvent(SPELL_MORTALSTRIKE, 0.2 * (int) TIMER_MORTAL);
events.ScheduleEvent(SPELL_BLOODLUST, 0.2 * (int) TIMER_BLOODLUST);
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
//Return since we have no target // Return since we have no target
if (!UpdateVictim()) if (!UpdateVictim())
{
return; return;
//WhirlWind_Timer
if (WhirlWind_Timer <= diff)
{
DoCast(me, SPELL_WHIRLWIND);
WhirlWind_Timer = 15000;
} }
else WhirlWind_Timer -= diff; events.Update(diff);
//MortalStrike_Timer if (me->HasUnitState(UNIT_STATE_CASTING))
if (MortalStrike_Timer <= diff)
{ {
DoCastVictim(SPELL_MORTALSTRIKE); return;
MortalStrike_Timer = 15000; }
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case SPELL_WHIRLWIND:
if (me->GetDistance2d(me->GetVictim()) < 10.0f)
{
DoCastVictim(SPELL_WHIRLWIND);
nextWhirlwindTime = urand(TIMER_WHIRLWIND - 2000, TIMER_WHIRLWIND + 2000);
}
else
{
// reschedule sooner
nextWhirlwindTime = 0.3 * urand(TIMER_WHIRLWIND - 2000, TIMER_WHIRLWIND + 2000);
}
events.ScheduleEvent(SPELL_WHIRLWIND, nextWhirlwindTime);
break;
case SPELL_MORTALSTRIKE:
DoCastVictim(SPELL_MORTALSTRIKE);
events.ScheduleEvent(SPELL_MORTALSTRIKE, urand(TIMER_MORTAL - 2000, TIMER_MORTAL + 2000));
break;
case SPELL_BLOODLUST:
DoCastSelf(SPELL_BLOODLUST);
events.ScheduleEvent(SPELL_BLOODLUST, urand(TIMER_BLOODLUST - 2000, TIMER_BLOODLUST + 2000));
break;
default:
break;
}
} }
else MortalStrike_Timer -= diff;
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
}; };
@@ -22,10 +22,16 @@
enum Grizzle enum Grizzle
{ {
SPELL_GROUNDTREMOR = 6524, SPELL_GROUNDTREMOR = 6524,
SPELL_FRENZY = 28371, SPELL_FRENZY = 8269,
EMOTE_FRENZY_KILL = 0 EMOTE_FRENZY_KILL = 0
}; };
enum Timer
{
TIMER_GROUNDTREMOR = 10000,
TIMER_FRENZY = 15000
};
class boss_grizzle : public CreatureScript class boss_grizzle : public CreatureScript
{ {
public: public:
@@ -36,48 +42,58 @@ public:
return GetBlackrockDepthsAI<boss_grizzleAI>(creature); return GetBlackrockDepthsAI<boss_grizzleAI>(creature);
} }
struct boss_grizzleAI : public ScriptedAI struct boss_grizzleAI : public BossAI
{ {
boss_grizzleAI(Creature* creature) : ScriptedAI(creature) { } boss_grizzleAI(Creature* creature) : BossAI(creature, DATA_GRIZZLE) {}
uint32 GroundTremor_Timer; uint32 nextTremorTime;
uint32 Frenzy_Timer;
void Reset() override void EnterCombat(Unit* /*who*/) override
{ {
GroundTremor_Timer = 12000; _EnterCombat();
Frenzy_Timer = 0; events.ScheduleEvent(SPELL_GROUNDTREMOR, 0.2 * (int) TIMER_GROUNDTREMOR);
events.ScheduleEvent(SPELL_FRENZY, 0.2 * (int) TIMER_FRENZY);
} }
void EnterCombat(Unit* /*who*/) override { }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
//Return since we have no target //Return since we have no target
if (!UpdateVictim()) if (!UpdateVictim())
{
return; return;
//GroundTremor_Timer
if (GroundTremor_Timer <= diff)
{
DoCastVictim(SPELL_GROUNDTREMOR);
GroundTremor_Timer = 8000;
} }
else GroundTremor_Timer -= diff; events.Update(diff);
//Frenzy_Timer if (me->HasUnitState(UNIT_STATE_CASTING))
if (HealthBelowPct(51))
{ {
if (Frenzy_Timer <= diff) return;
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{ {
DoCast(me, SPELL_FRENZY); case SPELL_GROUNDTREMOR:
if (me->GetDistance2d(me->GetVictim()) < 10.0f)
{
DoCastVictim(SPELL_GROUNDTREMOR);
nextTremorTime = urand(TIMER_GROUNDTREMOR - 2000, TIMER_GROUNDTREMOR + 2000);
}
else
{
nextTremorTime = 0.3*urand(TIMER_GROUNDTREMOR - 2000, TIMER_GROUNDTREMOR + 2000);
}
events.ScheduleEvent(SPELL_GROUNDTREMOR, nextTremorTime);
break;
case SPELL_FRENZY:
DoCastSelf(SPELL_FRENZY);
events.ScheduleEvent(SPELL_FRENZY, urand(TIMER_FRENZY - 2000, TIMER_FRENZY + 2000));
Talk(EMOTE_FRENZY_KILL); Talk(EMOTE_FRENZY_KILL);
break;
Frenzy_Timer = 15000; default:
break;
} }
else Frenzy_Timer -= diff;
} }
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
}; };
@@ -0,0 +1,102 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "blackrock_depths.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h"
enum Spells
{
SPELL_PARALYZING = 3609,
SPELL_BANEFUL = 15475,
SPELL_WEB_EXPLOSION = 15474
};
enum Timers
{
TIMER_PARALYZING = 20000,
TIMER_BANEFUL = 24000,
TIMER_WEB_EXPLOSION = 20000
};
class boss_hedrum : public CreatureScript
{
public:
boss_hedrum() : CreatureScript("boss_hedrum") {}
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockDepthsAI<boss_hedrumAI>(creature);
}
struct boss_hedrumAI : public BossAI
{
boss_hedrumAI(Creature* creature) : BossAI(creature, DATA_HEDRUM) {}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
events.ScheduleEvent(SPELL_PARALYZING, 0.2 * (int) TIMER_PARALYZING);
events.ScheduleEvent(SPELL_BANEFUL, 0.2 * (int) TIMER_BANEFUL);
events.ScheduleEvent(SPELL_WEB_EXPLOSION, 0.2 * (int) TIMER_WEB_EXPLOSION);
}
void UpdateAI(uint32 diff) override
{
// Return since we have no target
if (!UpdateVictim())
{
return;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case SPELL_PARALYZING:
DoCastVictim(SPELL_PARALYZING);
events.ScheduleEvent(SPELL_PARALYZING, urand(TIMER_PARALYZING - 2000, TIMER_PARALYZING + 2000));
break;
case SPELL_BANEFUL:
DoCastVictim(SPELL_BANEFUL);
events.ScheduleEvent(SPELL_BANEFUL, urand(TIMER_BANEFUL - 2000, TIMER_BANEFUL + 2000));
break;
case SPELL_WEB_EXPLOSION:
if (me->GetDistance2d(me->GetVictim()) < 100.0f)
{
DoCast(SPELL_WEB_EXPLOSION);
}
events.ScheduleEvent(SPELL_WEB_EXPLOSION, urand(TIMER_WEB_EXPLOSION - 2000, TIMER_WEB_EXPLOSION + 2000));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_hedrum()
{
new boss_hedrum();
}
@@ -25,6 +25,14 @@ enum Spells
SPELL_WARSTOMP = 24375 SPELL_WARSTOMP = 24375
}; };
enum SpellTimers
{
SPELL_FIERYBURST_MIN = 4000,
SPELL_FIERYBURST_MAX = 8000,
SPELL_WARSTOMP_MIN = 8000,
SPELL_WARSTOMP_MAX = 12000
};
class boss_magmus : public CreatureScript class boss_magmus : public CreatureScript
{ {
public: public:
@@ -35,54 +43,53 @@ public:
return GetBlackrockDepthsAI<boss_magmusAI>(creature); return GetBlackrockDepthsAI<boss_magmusAI>(creature);
} }
struct boss_magmusAI : public ScriptedAI struct boss_magmusAI : public BossAI
{ {
boss_magmusAI(Creature* creature) : ScriptedAI(creature) { } boss_magmusAI(Creature* creature) : BossAI(creature, TYPE_IRON_HALL) {}
uint32 FieryBurst_Timer;
uint32 WarStomp_Timer;
void Reset() override void Reset() override
{ {
FieryBurst_Timer = 5000; _Reset();
WarStomp_Timer = 0; instance->SetData(TYPE_IRON_HALL, NOT_STARTED);
} }
void EnterCombat(Unit* /*who*/) override { } void EnterCombat(Unit* /*who*/) override
{
instance->SetData(TYPE_IRON_HALL, IN_PROGRESS);
_EnterCombat();
events.ScheduleEvent(SPELL_FIERYBURST, urand(SPELL_FIERYBURST_MIN, SPELL_FIERYBURST_MAX));
events.ScheduleEvent(SPELL_WARSTOMP, urand(SPELL_WARSTOMP_MIN, SPELL_WARSTOMP_MAX));
}
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
//Return since we have no target //Return since we have no target
if (!UpdateVictim()) if (!UpdateVictim())
{
return; return;
//FieryBurst_Timer
if (FieryBurst_Timer <= diff)
{
DoCastVictim(SPELL_FIERYBURST);
FieryBurst_Timer = 6000;
} }
else FieryBurst_Timer -= diff; events.Update(diff);
//WarStomp_Timer while (uint32 eventId = events.ExecuteEvent())
if (HealthBelowPct(51))
{ {
if (WarStomp_Timer <= diff) switch (eventId)
{ {
case SPELL_WARSTOMP:
DoCastVictim(SPELL_WARSTOMP); DoCastVictim(SPELL_WARSTOMP);
WarStomp_Timer = 8000; events.ScheduleEvent(SPELL_WARSTOMP, urand(SPELL_WARSTOMP_MIN, SPELL_WARSTOMP_MAX));
break;
case SPELL_FIERYBURST:
DoCastVictim(SPELL_FIERYBURST);
events.ScheduleEvent(SPELL_FIERYBURST, urand(SPELL_FIERYBURST_MIN, SPELL_FIERYBURST_MAX));
break;
default:
break;
} }
else WarStomp_Timer -= diff;
} }
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
// When he die open door to last chamber
void JustDied(Unit* killer) override
{
if (InstanceScript* instance = killer->GetInstanceScript())
instance->HandleGameObject(instance->GetGuidData(DATA_THRONE_DOOR), true);
}
}; };
}; };
@@ -21,12 +21,134 @@
enum Spells enum Spells
{ {
SPELL_HEAL = 10917, SPELL_HEAL = 15586,
SPELL_RENEW = 10929, SPELL_RENEW = 8362,
SPELL_SHIELD = 10901, SPELL_MINDBLAST = 15587,
SPELL_MINDBLAST = 10947, SPELL_SHADOWBOLT = 15537,
SPELL_SHADOWWORDPAIN = 10894, SPELL_WORDPAIN = 15654,
SPELL_SMITE = 10934 };
enum SpellTimers
{
TIMER_HEAL = 12000,
TIMER_MINDBLAST = 16000,
TIMER_RENEW = 12000,
TIMER_SHADOWBOLT = 16000,
TIMER_WORDPAIN = 12000,
};
struct boss_moira_bronzebeardAI : public BossAI
{
// use a default value so we can inherit for priestess
boss_moira_bronzebeardAI(Creature* creature, uint32 data = DATA_MOIRA) : BossAI(creature, data) {}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
events.ScheduleEvent(SPELL_MINDBLAST, 0.5 * (int) TIMER_MINDBLAST);
events.ScheduleEvent(SPELL_HEAL, 0.5 * (int) TIMER_HEAL);
events.ScheduleEvent(SPELL_RENEW, 0.5 * (int) TIMER_RENEW);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
return;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case SPELL_MINDBLAST:
DoCastVictim(SPELL_MINDBLAST);
events.ScheduleEvent(SPELL_MINDBLAST, urand(TIMER_MINDBLAST - 2000, TIMER_MINDBLAST + 2000));
break;
case SPELL_HEAL:
CastOnEmperorIfPossible(SPELL_HEAL, TIMER_HEAL);
break;
case SPELL_RENEW:
CastOnEmperorIfPossible(SPELL_RENEW, TIMER_RENEW);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void CastOnEmperorIfPossible(uint32 spell, uint32 timer)
{
Creature* emperor = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EMPEROR));
if (emperor && emperor->HealthBelowPct(90))
{
DoCast(emperor, spell);
}
else if (HealthBelowPct(90))
{
DoCastSelf(spell);
}
events.ScheduleEvent(spell, urand(timer - 2000, timer + 2000));
}
};
// high priestess should be fairly identical to Moira.
// Running away when emperor dies is handled through GUID from emperor, therefore not relevant here.
struct boss_high_priestess_thaurissanAI : public boss_moira_bronzebeardAI
{
boss_high_priestess_thaurissanAI(Creature* creature) : boss_moira_bronzebeardAI(creature, DATA_PRIESTESS) {}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
Talk(0);
events.ScheduleEvent(SPELL_WORDPAIN, 0.5 * (int)TIMER_WORDPAIN);
events.ScheduleEvent(SPELL_HEAL, 0.5 * (int) TIMER_HEAL);
events.ScheduleEvent(SPELL_RENEW, 0.5 * (int) TIMER_RENEW);
events.ScheduleEvent(SPELL_SHADOWBOLT, 0.5 * (int) TIMER_SHADOWBOLT);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
return;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case SPELL_WORDPAIN:
DoCastVictim(SPELL_WORDPAIN);
events.ScheduleEvent(SPELL_WORDPAIN, urand(TIMER_WORDPAIN - 2000, TIMER_WORDPAIN + 2000));
break;
case SPELL_HEAL:
CastOnEmperorIfPossible(SPELL_HEAL, TIMER_HEAL);
break;
case SPELL_RENEW:
CastOnEmperorIfPossible(SPELL_RENEW, TIMER_RENEW);
break;
case SPELL_SHADOWBOLT:
DoCastVictim(SPELL_SHADOWBOLT);
events.ScheduleEvent(SPELL_SHADOWBOLT, urand(TIMER_SHADOWBOLT - 2000, TIMER_SHADOWBOLT + 2000));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
}; };
class boss_moira_bronzebeard : public CreatureScript class boss_moira_bronzebeard : public CreatureScript
@@ -38,60 +160,25 @@ public:
{ {
return GetBlackrockDepthsAI<boss_moira_bronzebeardAI>(creature); return GetBlackrockDepthsAI<boss_moira_bronzebeardAI>(creature);
} }
};
struct boss_moira_bronzebeardAI : public ScriptedAI class boss_high_priestess_thaurissan : public CreatureScript
{
public:
boss_high_priestess_thaurissan() : CreatureScript("boss_high_priestess_thaurissan") {}
CreatureAI* GetAI(Creature* creature) const override
{ {
boss_moira_bronzebeardAI(Creature* creature) : ScriptedAI(creature) { } return GetBlackrockDepthsAI<boss_high_priestess_thaurissanAI>(creature);
}
uint32 Heal_Timer;
uint32 MindBlast_Timer;
uint32 ShadowWordPain_Timer;
uint32 Smite_Timer;
void Reset() override
{
Heal_Timer = 12000; //These times are probably wrong
MindBlast_Timer = 16000;
ShadowWordPain_Timer = 2000;
Smite_Timer = 8000;
}
void EnterCombat(Unit* /*who*/) override { }
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
//MindBlast_Timer
if (MindBlast_Timer <= diff)
{
DoCastVictim(SPELL_MINDBLAST);
MindBlast_Timer = 14000;
}
else MindBlast_Timer -= diff;
//ShadowWordPain_Timer
if (ShadowWordPain_Timer <= diff)
{
DoCastVictim(SPELL_SHADOWWORDPAIN);
ShadowWordPain_Timer = 18000;
}
else ShadowWordPain_Timer -= diff;
//Smite_Timer
if (Smite_Timer <= diff)
{
DoCastVictim(SPELL_SMITE);
Smite_Timer = 10000;
}
else Smite_Timer -= diff;
}
};
}; };
void AddSC_boss_moira_bronzebeard() void AddSC_boss_moira_bronzebeard()
{ {
new boss_moira_bronzebeard(); new boss_moira_bronzebeard();
} }
void AddSC_boss_high_priestess_thaurissan()
{
new boss_high_priestess_thaurissan();
}
@@ -0,0 +1,126 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "blackrock_depths.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h"
enum Spells
{
SPELL_ARCANE_BOLT = 13748,
SPELL_ARCANE_EXPLOSION = 1467,
SPELL_POLYMORPH = 15534,
SPELL_SLOW = 19137
};
enum Timers
{
TIMER_ARCANE_BOLT = 7000,
TIMER_ARCANE_EXPLOSION = 24000,
TIMER_POLYMORPH = 12000,
TIMER_SLOW = 15000
};
class boss_okthor : public CreatureScript
{
public:
boss_okthor() : CreatureScript("boss_okthor") {}
CreatureAI* GetAI(Creature* creature) const override
{
return GetBlackrockDepthsAI<boss_okthorAI>(creature);
}
struct boss_okthorAI : public BossAI
{
boss_okthorAI(Creature* creature) : BossAI(creature, DATA_OKTHOR) {}
uint32 nextArcaneExplosionTime;
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
events.ScheduleEvent(SPELL_ARCANE_BOLT, 0.2 * (int) TIMER_ARCANE_BOLT);
events.ScheduleEvent(SPELL_ARCANE_EXPLOSION, 0.2 * (int) TIMER_ARCANE_EXPLOSION);
events.ScheduleEvent(SPELL_POLYMORPH, 0.2 * (int) TIMER_POLYMORPH);
events.ScheduleEvent(SPELL_SLOW, 500);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
{
return;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case SPELL_ARCANE_BOLT:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
DoCast(target, SPELL_ARCANE_BOLT);
}
events.ScheduleEvent(SPELL_ARCANE_BOLT, urand(TIMER_ARCANE_BOLT - 2000, TIMER_ARCANE_BOLT + 2000));
break;
case SPELL_ARCANE_EXPLOSION:
if (me->GetDistance2d(me->GetVictim()) < 50.0f)
{
DoCast(SPELL_ARCANE_EXPLOSION);
nextArcaneExplosionTime = urand(TIMER_ARCANE_EXPLOSION - 2000, TIMER_ARCANE_EXPLOSION + 2000);
}
else
{
nextArcaneExplosionTime = 0.3*urand(TIMER_ARCANE_EXPLOSION - 2000, TIMER_ARCANE_EXPLOSION + 2000);
}
events.ScheduleEvent(SPELL_ARCANE_EXPLOSION, nextArcaneExplosionTime);
break;
case SPELL_POLYMORPH:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
DoCast(target, SPELL_POLYMORPH);
}
events.ScheduleEvent(SPELL_POLYMORPH, urand(TIMER_POLYMORPH - 2000, TIMER_POLYMORPH + 2000));
break;
case SPELL_SLOW:
if (me->GetDistance2d(me->GetVictim()) < 50.0f)
{
DoCast(SPELL_SLOW);
}
events.ScheduleEvent(SPELL_SLOW, TIMER_SLOW);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_okthor()
{
new boss_okthor();
}
@@ -29,28 +29,16 @@ enum Timers
TIMER_TOMB_RESET = 15000 TIMER_TOMB_RESET = 15000
}; };
enum Creatures enum Distances
{ {
NPC_EMPEROR = 9019, RADIUS_RING_OF_LAW = 80,
NPC_PHALANX = 9502, DISTANCE_EMPEROR_ROOM = 125
NPC_ANGERREL = 9035, };
NPC_DOPEREL = 9040,
NPC_HATEREL = 9034,
NPC_VILEREL = 9036,
NPC_SEETHREL = 9038,
NPC_GLOOMREL = 9037,
NPC_DOOMREL = 9039,
NPC_MOIRA = 8929,
NPC_WATCHMAN_DOOMGRIP = 9476, enum PrincessQuests
{
NPC_WEAPON_TECHNICIAN = 8920, PRINCESS_QUEST_HORDE = 4004,
NPC_DOOMFORGE_ARCANASMITH = 8900, PRINCESS_QUEST_ALLIANCE = 4363
NPC_RAGEREAVER_GOLEM = 8906,
NPC_WRATH_HAMMER_CONSTRUCT = 8907,
NPC_GOLEM_LORD_ARGELMACH = 8983,
NPC_COREN_DIREBREW = 23872
}; };
enum GameObjects enum GameObjects
@@ -127,6 +115,8 @@ public:
ObjectGuid PhalanxGUID; ObjectGuid PhalanxGUID;
ObjectGuid MagmusGUID; ObjectGuid MagmusGUID;
ObjectGuid MoiraGUID; ObjectGuid MoiraGUID;
ObjectGuid PriestessGUID;
ObjectGuid IronhandGUID[6];
ObjectGuid CorenGUID; ObjectGuid CorenGUID;
ObjectGuid GoArena1GUID; ObjectGuid GoArena1GUID;
@@ -158,10 +148,68 @@ public:
uint32 TombTimer; uint32 TombTimer;
uint32 TombEventCounter; uint32 TombEventCounter;
uint32 OpenedCoofers; uint32 OpenedCoofers;
uint32 IronhandCounter;
GuidList ArgelmachAdds; GuidList ArgelmachAdds;
ObjectGuid ArgelmachGUID; ObjectGuid ArgelmachGUID;
TempSummon* TempSummonGrimstone = nullptr;
Position GrimstonePositon = Position(625.559f, -205.618f, -52.735f, 2.609f);
time_t timeRingFail = 0;
uint8 arenaMobsToSpawn;
uint8 arenaBossToSpawn;
std::vector<ObjectGuid> ArenaSpectators;
Position CenterOfRingOfLaw = Position(595.289, -186.56);
ObjectGuid EmperorSenators[5];
std::vector<ObjectGuid> EmperorSenatorsVector;
Position EmperorSpawnPos = Position(1380.52, -831, 115);
void OnPlayerEnter(Player* /* player */) override
{
ReplaceMoiraIfSaved(); // In case a player joins the party during the run
// SetData(TYPE_RING_OF_LAW, DONE);
}
void ReplaceMoiraIfSaved()
{
ObjectGuid* GUIDToReplace = &PriestessGUID; // default to having Moira
ObjectGuid* GUIDToSpawn = &MoiraGUID;
uint32 NPCEntry = NPC_MOIRA;
bool MoiraSaved = true;
// check if all players saved her.
Map::PlayerList const& lPlayers = instance->GetPlayers();
if (!lPlayers.isEmpty())
{
for (Map::PlayerList::const_iterator itr = lPlayers.begin(); itr != lPlayers.end(); ++itr)
{
if (Player* player = itr->GetSource())
{
// set to false if this player hasn't saved her. Another player can't put it to true.
MoiraSaved = MoiraSaved && ((player->GetQuestStatus(PRINCESS_QUEST_HORDE) == QUEST_STATUS_REWARDED)
|| (player->GetQuestStatus(PRINCESS_QUEST_ALLIANCE) == QUEST_STATUS_REWARDED));
}
}
}
// assign correct GUIDs and spawn targets
if (MoiraSaved)
{
GUIDToReplace = &MoiraGUID;
GUIDToSpawn = &PriestessGUID;
NPCEntry = NPC_PRIESTESS;
}
if (Creature* CreatureToReplace = instance->GetCreature(*GUIDToReplace))
{
Creature* NewSpawn = instance->SummonCreature(NPCEntry, CreatureToReplace->GetPosition());
CreatureToReplace->RemoveFromWorld();
*GUIDToSpawn = NewSpawn->GetGUID();
}
}
void Initialize() override void Initialize() override
{ {
memset(&encounter, 0, sizeof(encounter)); memset(&encounter, 0, sizeof(encounter));
@@ -170,8 +218,14 @@ public:
GhostKillCount = 0; GhostKillCount = 0;
TombTimer = TIMER_TOMB_START; TombTimer = TIMER_TOMB_START;
TombEventCounter = 0; TombEventCounter = 0;
OpenedCoofers = 0;
tombResetTimer = 0; tombResetTimer = 0;
OpenedCoofers = 0;
IronhandCounter = 0;
ArenaSpectators.clear();
// these are linked to the dungeon and not how many times the arena started.
arenaMobsToSpawn = urand(0, 5);
arenaBossToSpawn = urand(0, 5);
} }
void OnCreatureCreate(Creature* creature) override void OnCreatureCreate(Creature* creature) override
@@ -214,7 +268,7 @@ public:
case NPC_MAGMUS: case NPC_MAGMUS:
MagmusGUID = creature->GetGUID(); MagmusGUID = creature->GetGUID();
if (!creature->IsAlive()) if (!creature->IsAlive())
HandleGameObject(GetGuidData(DATA_THRONE_DOOR), true); // if Magmus is dead open door to last boss HandleGameObject(GoThroneGUID, true); // if Magmus is dead open door to last boss
break; break;
case NPC_WEAPON_TECHNICIAN: case NPC_WEAPON_TECHNICIAN:
case NPC_DOOMFORGE_ARCANASMITH: case NPC_DOOMFORGE_ARCANASMITH:
@@ -228,6 +282,38 @@ public:
case NPC_GOLEM_LORD_ARGELMACH: case NPC_GOLEM_LORD_ARGELMACH:
ArgelmachGUID = creature->GetGUID(); ArgelmachGUID = creature->GetGUID();
break; break;
case NPC_IRONHAND_GUARDIAN:
IronhandGUID[IronhandCounter] = creature->GetGUID();
IronhandCounter++;
break;
case NPC_ARENA_SPECTATOR:
ArenaSpectators.push_back(creature->GetGUID());
if (encounter[TYPE_RING_OF_LAW] == DONE) // added for crashes
{
creature->SetFaction(FACTION_NEUTRAL);
creature->SetReactState(REACT_DEFENSIVE);
}
break;
case NPC_SHADOWFORGE_PEASANT:
case NPC_SHADOWFORCE_CITIZEN: // both do the same
if (creature->GetDistance2d(CenterOfRingOfLaw.GetPositionX(), CenterOfRingOfLaw.GetPositionY()) < (float)RADIUS_RING_OF_LAW)
{
ArenaSpectators.push_back(creature->GetGUID());
}
if (encounter[TYPE_RING_OF_LAW] == DONE) // added for crashes
{
creature->SetFaction(FACTION_NEUTRAL);
creature->SetReactState(REACT_DEFENSIVE);
}
break;
case NPC_SHADOWFORGE_SENATOR:
// keep track of Senators that are not too far from emperor. Can't really use emperor as creature due to him possibly not being spawned.
// some senators spawn at ring of law
if (creature->GetDistance2d(EmperorSpawnPos.GetPositionX(), EmperorSpawnPos.GetPositionY()) < (float)DISTANCE_EMPEROR_ROOM)
{
EmperorSenatorsVector.push_back(creature->GetGUID());
}
break;
default: default:
break; break;
} }
@@ -309,6 +395,7 @@ public:
void OnUnitDeath(Unit* unit) override void OnUnitDeath(Unit* unit) override
{ {
uint32 deadSenators = 0;
switch (unit->GetEntry()) switch (unit->GetEntry())
{ {
case NPC_WEAPON_TECHNICIAN: case NPC_WEAPON_TECHNICIAN:
@@ -317,6 +404,28 @@ public:
case NPC_WRATH_HAMMER_CONSTRUCT: case NPC_WRATH_HAMMER_CONSTRUCT:
ArgelmachAdds.remove(unit->GetGUID()); ArgelmachAdds.remove(unit->GetGUID());
break; break;
case NPC_MAGMUS:
SetData(TYPE_IRON_HALL, DONE);
break;
case NPC_SHADOWFORGE_SENATOR:
deadSenators = 1; //hacky, but we cannot count the unit that just died through its state because OnUnitDeath() is called before the state is set.
for (const auto &senatorGUID: EmperorSenatorsVector)
{
if (Creature* senator = instance->GetCreature(senatorGUID))
{
if (!senator->IsAlive() || senator->isDying())
{
deadSenators++;
}
}
}
if (Creature* emperor = instance->GetCreature(EmperorGUID))
{
// send % of senators that died
emperor->AI()->SetData(0, (100 * deadSenators) / EmperorSenatorsVector.size());
}
break;
case NPC_ANGERREL: case NPC_ANGERREL:
case NPC_DOPEREL: case NPC_DOPEREL:
case NPC_HATEREL: case NPC_HATEREL:
@@ -343,6 +452,33 @@ public:
{ {
case TYPE_RING_OF_LAW: case TYPE_RING_OF_LAW:
encounter[0] = data; encounter[0] = data;
switch(data)
{
case IN_PROGRESS:
TempSummonGrimstone = instance->SummonCreature(NPC_GRIMSTONE, GrimstonePositon);
break;
case FAIL:
if (TempSummonGrimstone)
{
TempSummonGrimstone->RemoveFromWorld();
TempSummonGrimstone = nullptr;
timeRingFail = time(nullptr);
}
SetData(TYPE_RING_OF_LAW, NOT_STARTED);
break;
case DONE:
for (const auto& itr : ArenaSpectators)
{
if (Creature* spectator = instance->GetCreature(itr))
{
spectator->SetFaction(FACTION_NEUTRAL);
spectator->SetReactState(REACT_DEFENSIVE);
}
}
break;
default:
break;
}
break; break;
case TYPE_VAULT: case TYPE_VAULT:
encounter[1] = data; encounter[1] = data;
@@ -370,9 +506,37 @@ public:
break; break;
case TYPE_LYCEUM: case TYPE_LYCEUM:
encounter[4] = data; encounter[4] = data;
if (data == DONE)
{
HandleGameObject(GetGuidData(DATA_GOLEM_DOOR_N), true);
HandleGameObject(GetGuidData(DATA_GOLEM_DOOR_S), true);
if (Creature* magmus = instance->GetCreature(MagmusGUID))
{
magmus->AI()->Talk(0);
}
ReplaceMoiraIfSaved(); // Need to place the correct final boss, but we need her to be spawned first.
}
break; break;
case TYPE_IRON_HALL: case TYPE_IRON_HALL:
encounter[5] = data; encounter[5] = data;
switch (data)
{
case NOT_STARTED:
case IN_PROGRESS:
for (int i = 0; i < 6; i++)
{
if (Creature* ironhand = instance->GetCreature(IronhandGUID[i]))
{
ironhand->AI()->SetData(0, data == IN_PROGRESS);
}
}
break;
case DONE:
HandleGameObject(GetGuidData(DATA_THRONE_DOOR), true);
break;
default:
break;
}
break; break;
case DATA_OPEN_COFFER_DOORS: case DATA_OPEN_COFFER_DOORS:
OpenedCoofers += 1; OpenedCoofers += 1;
@@ -492,6 +656,12 @@ public:
return encounter[4]; return encounter[4];
case TYPE_IRON_HALL: case TYPE_IRON_HALL:
return encounter[5]; return encounter[5];
case DATA_TIME_RING_FAIL:
return timeRingFail;
case DATA_ARENA_MOBS:
return arenaMobsToSpawn;
case DATA_ARENA_BOSS:
return arenaBossToSpawn;
} }
return 0; return 0;
} }
@@ -28,9 +28,13 @@ void AddSC_boss_draganthaurissan();
void AddSC_boss_general_angerforge(); void AddSC_boss_general_angerforge();
void AddSC_boss_gorosh_the_dervish(); void AddSC_boss_gorosh_the_dervish();
void AddSC_boss_grizzle(); void AddSC_boss_grizzle();
void AddSC_boss_eviscerator();
void AddSC_boss_okthor();
void AddSC_boss_hedrum();
void AddSC_boss_high_interrogator_gerstahn(); void AddSC_boss_high_interrogator_gerstahn();
void AddSC_boss_magmus(); void AddSC_boss_magmus();
void AddSC_boss_moira_bronzebeard(); void AddSC_boss_moira_bronzebeard();
void AddSC_boss_high_priestess_thaurissan();
void AddSC_boss_tomb_of_seven(); void AddSC_boss_tomb_of_seven();
void AddSC_instance_blackrock_depths(); void AddSC_instance_blackrock_depths();
void AddSC_boss_drakkisath(); //Blackrock Spire void AddSC_boss_drakkisath(); //Blackrock Spire
@@ -172,9 +176,13 @@ void AddEasternKingdomsScripts()
AddSC_boss_general_angerforge(); AddSC_boss_general_angerforge();
AddSC_boss_gorosh_the_dervish(); AddSC_boss_gorosh_the_dervish();
AddSC_boss_grizzle(); AddSC_boss_grizzle();
AddSC_boss_okthor();
AddSC_boss_eviscerator();
AddSC_boss_hedrum();
AddSC_boss_high_interrogator_gerstahn(); AddSC_boss_high_interrogator_gerstahn();
AddSC_boss_magmus(); AddSC_boss_magmus();
AddSC_boss_moira_bronzebeard(); AddSC_boss_moira_bronzebeard();
AddSC_boss_high_priestess_thaurissan();
AddSC_boss_tomb_of_seven(); AddSC_boss_tomb_of_seven();
AddSC_instance_blackrock_depths(); AddSC_instance_blackrock_depths();
AddSC_boss_drakkisath(); //Blackrock Spire AddSC_boss_drakkisath(); //Blackrock Spire