From 9b3b61139a497ef801522b0274356c619512a8bc Mon Sep 17 00:00:00 2001 From: patou01 <2592673+patou01@users.noreply.github.com> Date: Thu, 16 Dec 2021 12:14:29 +0100 Subject: [PATCH] fix(Scripts/BRD): Magmus, Emperor, Priestess, Arena improvements (#8102) --- .../rev_1632675335691344600.sql | 43 ++++ .../BlackrockDepths/blackrock_depths.cpp | 230 ++++++++++++------ .../BlackrockDepths/blackrock_depths.h | 81 +++++- .../BlackrockDepths/boss_anubshiah.cpp | 118 ++++----- .../boss_emperor_dagran_thaurissan.cpp | 104 ++++---- .../BlackrockDepths/boss_eviscerator.cpp | 110 +++++++++ .../boss_gorosh_the_dervish.cpp | 77 ++++-- .../BlackrockDepths/boss_grizzle.cpp | 66 +++-- .../BlackrockDepths/boss_hedrum.cpp | 102 ++++++++ .../BlackrockDepths/boss_magmus.cpp | 59 +++-- .../boss_moira_bronzebeard.cpp | 197 ++++++++++----- .../BlackrockDepths/boss_okthor.cpp | 126 ++++++++++ .../instance_blackrock_depths.cpp | 214 ++++++++++++++-- .../eastern_kingdoms_script_loader.cpp | 8 + 14 files changed, 1203 insertions(+), 332 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1632675335691344600.sql create mode 100644 src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_eviscerator.cpp create mode 100644 src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_hedrum.cpp create mode 100644 src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_okthor.cpp diff --git a/data/sql/updates/pending_db_world/rev_1632675335691344600.sql b/data/sql/updates/pending_db_world/rev_1632675335691344600.sql new file mode 100644 index 000000000..cc759b075 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1632675335691344600.sql @@ -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); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp index 22bfef0a9..dc81dc30a 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp @@ -23,16 +23,18 @@ #include "ScriptedGossip.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 { public: - go_shadowforge_brazier() : GameObjectScript("go_shadowforge_brazier") { } + go_shadowforge_brazier() : GameObjectScript("go_shadowforge_brazier") {} bool OnGossipHello(Player* /*player*/, GameObject* go) override { @@ -46,68 +48,101 @@ public: return false; } - // 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)) + // should only happen on first brazier + if (instance->GetData(TYPE_LYCEUM) == NOT_STARTED) { - if (instance->GetData(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); + instance->SetData(TYPE_LYCEUM, IN_PROGRESS); } + + // 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; + }; +}; + +class ironhand_guardian : public CreatureScript +{ +public: + ironhand_guardian() : CreatureScript("brd_ironhand_guardian") {} + + CreatureAI* GetAI(Creature* creature) const override + { + return GetBlackrockDepthsAI(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, - GO_BANNER_OF_PROVOCATION = 181058, - GO_ARENA_SPOILS = 181074, - - NPC_GRIMSTONE = 10096, - NPC_THELDREN = 16059, + uint32 entry; + uint32 amount; }; -uint32 theldrenTeam[] = +static Wave RingMobs[] = // different amounts based on the type { - 16053, 16055, 16050, 16051, 16049, 16052, 16054, 16058 -}; - -uint32 RingMob[] = -{ - 8925, // Dredge Worm - 8926, // Deep Stinger - 8927, // Dark Screecher - 8928, // Burrowing Thundersnout - 8933, // Cave Creeper - 8932, // Borer Beetle -}; + {NPC_DREDGE_WORM, 3}, + {NPC_DEEP_STINGER, 3}, + {NPC_DARK_SCREECHER, 3}, + {NPC_THUNDERSNOUT, 2}, + {NPC_CAVE_CREEPER, 3}, + {NPC_BORER_BEETLE, 6}}; uint32 RingBoss[] = { - 9027, // Gorosh - 9028, // Grizzle - 9029, // Eviscerator - 9030, // Ok'thor - 9031, // Anub'shiah - 9032, // Hedrum + NPC_GOROSH, + NPC_GRIZZLE, + NPC_EVISCERATOR, + NPC_OKTHOR, + NPC_ANUBSHIAH, + NPC_HEDRUM }; class at_ring_of_law : public AreaTriggerScript @@ -119,13 +154,18 @@ public: { 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) + { 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); - player->SummonCreature(NPC_GRIMSTONE, 625.559f, -205.618f, -52.735f, 2.609f, TEMPSUMMON_DEAD_DESPAWN, 0); - - return false; + return true; } return false; } @@ -157,9 +197,11 @@ public: npc_grimstoneAI(Creature* creature) : npc_escortAI(creature), summons(me) { 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; eventTimer = 1000; + resetTimer = 0; theldrenEvent = false; summons.DespawnAll(); } @@ -169,7 +211,9 @@ public: uint8 eventPhase; uint32 eventTimer; + uint32 resetTimer; uint8 MobSpawnId; + uint8 BossSpawnId; bool theldrenEvent; void Reset() override @@ -189,7 +233,10 @@ public: summons.Despawn(summon); // All Summons killed, next phase if (summons.empty()) + { + resetTimer = 0; eventTimer = 5000; + } } 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); } 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 @@ -251,6 +336,17 @@ public: if (!instance) 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 <= diff) @@ -277,35 +373,30 @@ public: case 4: SetEscortPaused(false); me->SetVisible(false); - me->SummonCreature(RingMob[MobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0); - eventTimer = 8000; + SpawnWave(MobSpawnId); // wave 1 + eventTimer = 15000; break; case 5: - me->SummonCreature(RingMob[MobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0); - me->SummonCreature(RingMob[MobSpawnId], 608.960f, -235.322f, -53.907f, 1.857f, TEMPSUMMON_DEAD_DESPAWN, 0); - eventTimer = 8000; + SpawnWave(MobSpawnId); // wave 2 + eventTimer = 0; // will be set from SummonedCreatureDies break; 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); HandleGameObject(DATA_ARENA1, false); Talk(SAY_TEXT6); SetEscortPaused(false); eventTimer = 0; break; - case 8: + case 7: HandleGameObject(DATA_ARENA2, true); eventTimer = 5000; break; - case 9: + case 8: me->SetVisible(false); SummonBoss(); eventTimer = 0; break; - case 10: + case 9: 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)) @@ -614,4 +705,5 @@ void AddSC_blackrock_depths() new npc_phalanx(); new npc_lokhtos_darkbargainer(); new npc_rocknot(); + new ironhand_guardian(); } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h index 8574f0e26..67fe9be83 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.h @@ -21,6 +21,13 @@ #include "CreatureAIImpl.h" #define BRDScriptName "instance_blackrock_depths" +enum FactionIds +{ + FACTION_NEUTRAL = 674, + FACTION_HOSTILE = 754, + FACTION_FRIEND = 35 +}; + enum BRDBosses { BOSS_AMBASSADOR_FLAMELASH = 0, @@ -56,22 +63,86 @@ enum DataTypes DATA_SF_BRAZIER_N = 25, DATA_SF_BRAZIER_S = 26, DATA_MOIRA = 27, - + DATA_PRIESTESS = 28, DATA_OPEN_COFFER_DOORS = 30, DATA_GOLEM_LORD_ARGELMACH_INIT = 31, DATA_GOLEM_LORD_ARGELMACH_ADDS = 32, - 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 inline AI* GetBlackrockDepthsAI(T* obj) { diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp index a5a490cdf..38bb6971e 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp @@ -21,11 +21,20 @@ enum Spells { - SPELL_SHADOWBOLT = 17228, - SPELL_CURSEOFTONGUES = 15470, - SPELL_CURSEOFWEAKNESS = 17227, - SPELL_DEMONARMOR = 11735, - SPELL_ENVELOPINGWEB = 15471 + SPELL_SHADOWBOLT = 15472, + SPELL_CURSE_TONGUES = 15470, + SPELL_CURSE_WEAKNESS = 12493, + SPELL_DEMON_ARMOR = 13787, + 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 @@ -38,75 +47,68 @@ public: return GetBlackrockDepthsAI(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; - uint32 CurseOfTongues_Timer; - uint32 CurseOfWeakness_Timer; - uint32 DemonArmor_Timer; - uint32 EnvelopingWeb_Timer; - - void Reset() override + void EnterCombat(Unit* /*who*/) override { - ShadowBolt_Timer = 7000; - CurseOfTongues_Timer = 24000; - CurseOfWeakness_Timer = 12000; - DemonArmor_Timer = 3000; - EnvelopingWeb_Timer = 16000; + _EnterCombat(); + events.ScheduleEvent(SPELL_SHADOWBOLT, 0.2 * (int)TIMER_SHADOWBOLT); + events.ScheduleEvent(SPELL_CURSE_TONGUES, 0.2 * (int)TIMER_CURSE_TONGUES); + events.ScheduleEvent(SPELL_CURSE_WEAKNESS, 0.2 * (int)TIMER_CURSE_WEAKNESS); + 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 { //Return since we have no target if (!UpdateVictim()) + { return; - - //ShadowBolt_Timer - if (ShadowBolt_Timer <= diff) - { - DoCastVictim(SPELL_SHADOWBOLT); - ShadowBolt_Timer = 7000; } - else ShadowBolt_Timer -= diff; + events.Update(diff); - //CurseOfTongues_Timer - if (CurseOfTongues_Timer <= diff) + if (me->HasUnitState(UNIT_STATE_CASTING)) { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_CURSEOFTONGUES); - CurseOfTongues_Timer = 18000; + return; } - else CurseOfTongues_Timer -= diff; - - //CurseOfWeakness_Timer - if (CurseOfWeakness_Timer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - DoCastVictim(SPELL_CURSEOFWEAKNESS); - CurseOfWeakness_Timer = 45000; + switch (eventId) + { + 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(); } }; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp index 19c564bb1..63ad65c57 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_emperor_dagran_thaurissan.cpp @@ -21,16 +21,19 @@ enum Yells { - SAY_AGGRO = 0, - SAY_SLAY = 1 + YELL_SENATORS_ALIVE = 0, + YELL_SENATORS_DEAD = 1, + SAY_SLAY = 2 }; enum Spells { - SPELL_HANDOFTHAURISSAN = 17492, - SPELL_AVATAROFFLAME = 15636 + SPELL_HANDOFTHAURISSAN = 17492, + SPELL_AVATAROFFLAME = 15636 }; +#define DATA_PERCENT_DEAD_SENATORS 0 + class boss_emperor_dagran_thaurissan : public CreatureScript { public: @@ -41,29 +44,27 @@ public: return GetBlackrockDepthsAI(creature); } - struct boss_draganthaurissanAI : public ScriptedAI + struct boss_draganthaurissanAI : public BossAI { - boss_draganthaurissanAI(Creature* creature) : ScriptedAI(creature) - { - instance = me->GetInstanceScript(); - } + uint32 hasYelled = 0; + uint32 SenatorYells[5] = {3, 4, 5, 6, 7}; // IDs in creature_text database - InstanceScript* instance; - uint32 HandOfThaurissan_Timer; - uint32 AvatarOfFlame_Timer; - //uint32 Counter; - - void Reset() override - { - HandOfThaurissan_Timer = 4000; - AvatarOfFlame_Timer = 25000; - //Counter= 0; - } + boss_draganthaurissanAI(Creature* creature) : BossAI(creature, DATA_EMPEROR){} void EnterCombat(Unit* /*who*/) override { - Talk(SAY_AGGRO); + if (hasYelled != 5) + { + Talk(YELL_SENATORS_ALIVE); + } + else + { + Talk(YELL_SENATORS_DEAD); + } + me->CallForHelp(VISIBLE_RANGE); + events.ScheduleEvent(SPELL_HANDOFTHAURISSAN, urand(4000, 7000)); + events.ScheduleEvent(SPELL_AVATAROFFLAME, urand(10000, 12000)); } void KilledUnit(Unit* /*victim*/) override @@ -71,11 +72,27 @@ public: 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 { if (Creature* Moira = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MOIRA))) { Moira->AI()->EnterEvadeMode(); + Moira->AI()->Talk(0); Moira->SetFaction(FACTION_FRIENDLY); } } @@ -86,33 +103,28 @@ public: if (!UpdateVictim()) 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)) - DoCast(target, SPELL_HANDOFTHAURISSAN); - - //3 Hands of Thaurissan will be cast - //if (Counter < 3) - //{ - // HandOfThaurissan_Timer = 1000; - // ++Counter; - //} - //else - //{ - HandOfThaurissan_Timer = 5000; - //Counter = 0; - //} + switch (eventId) + { + case SPELL_HANDOFTHAURISSAN: + DoCast(SelectTarget(SELECT_TARGET_RANDOM), SPELL_HANDOFTHAURISSAN); + //DoCastVictim(SPELL_HANDOFTHAURISSAN); + events.ScheduleEvent(SPELL_HANDOFTHAURISSAN, urand(4000, 7000)); + break; + case SPELL_AVATAROFFLAME: + DoCastSelf(SPELL_AVATAROFFLAME); + events.ScheduleEvent(SPELL_AVATAROFFLAME, urand(23000, 27000)); + break; + default: + break; + } } - else HandOfThaurissan_Timer -= diff; - - //AvatarOfFlame_Timer - if (AvatarOfFlame_Timer <= diff) - { - DoCastVictim(SPELL_AVATAROFFLAME); - AvatarOfFlame_Timer = 18000; - } - else AvatarOfFlame_Timer -= diff; - DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_eviscerator.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_eviscerator.cpp new file mode 100644 index 000000000..6790e2069 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_eviscerator.cpp @@ -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 . + */ + +#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(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(); +} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp index d715e0219..96f7ba615 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp @@ -21,8 +21,16 @@ enum Spells { - SPELL_WHIRLWIND = 15589, - SPELL_MORTALSTRIKE = 24573 + SPELL_WHIRLWIND = 15589, + SPELL_MORTALSTRIKE = 15708, + SPELL_BLOODLUST = 21049 +}; + +enum Timers +{ + TIMER_WHIRLWIND = 12000, + TIMER_MORTAL = 22000, + TIMER_BLOODLUST = 30000 }; class boss_gorosh_the_dervish : public CreatureScript @@ -35,45 +43,62 @@ public: return GetBlackrockDepthsAI(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 MortalStrike_Timer; - - void Reset() override - { - WhirlWind_Timer = 12000; - MortalStrike_Timer = 22000; - } + uint32 nextWhirlwindTime; 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 { - //Return since we have no target + // Return since we have no target if (!UpdateVictim()) + { return; - - //WhirlWind_Timer - if (WhirlWind_Timer <= diff) - { - DoCast(me, SPELL_WHIRLWIND); - WhirlWind_Timer = 15000; } - else WhirlWind_Timer -= diff; + events.Update(diff); - //MortalStrike_Timer - if (MortalStrike_Timer <= diff) + if (me->HasUnitState(UNIT_STATE_CASTING)) { - DoCastVictim(SPELL_MORTALSTRIKE); - MortalStrike_Timer = 15000; + return; + } + 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(); } }; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp index 100d62528..919835e82 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp @@ -22,10 +22,16 @@ enum Grizzle { SPELL_GROUNDTREMOR = 6524, - SPELL_FRENZY = 28371, + SPELL_FRENZY = 8269, EMOTE_FRENZY_KILL = 0 }; +enum Timer +{ + TIMER_GROUNDTREMOR = 10000, + TIMER_FRENZY = 15000 +}; + class boss_grizzle : public CreatureScript { public: @@ -36,48 +42,58 @@ public: return GetBlackrockDepthsAI(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 Frenzy_Timer; + uint32 nextTremorTime; - void Reset() override + void EnterCombat(Unit* /*who*/) override { - GroundTremor_Timer = 12000; - Frenzy_Timer = 0; + _EnterCombat(); + 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 { //Return since we have no target if (!UpdateVictim()) + { return; - - //GroundTremor_Timer - if (GroundTremor_Timer <= diff) - { - DoCastVictim(SPELL_GROUNDTREMOR); - GroundTremor_Timer = 8000; } - else GroundTremor_Timer -= diff; + events.Update(diff); - //Frenzy_Timer - if (HealthBelowPct(51)) + if (me->HasUnitState(UNIT_STATE_CASTING)) { - 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); - - Frenzy_Timer = 15000; + break; + default: + break; } - else Frenzy_Timer -= diff; } - DoMeleeAttackIfReady(); } }; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_hedrum.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_hedrum.cpp new file mode 100644 index 000000000..0ab186a03 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_hedrum.cpp @@ -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 . + */ + +#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(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(); +} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp index 2f514e172..4f33b3922 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_magmus.cpp @@ -25,6 +25,14 @@ enum Spells 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 { public: @@ -35,54 +43,53 @@ public: return GetBlackrockDepthsAI(creature); } - struct boss_magmusAI : public ScriptedAI + struct boss_magmusAI : public BossAI { - boss_magmusAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 FieryBurst_Timer; - uint32 WarStomp_Timer; + boss_magmusAI(Creature* creature) : BossAI(creature, TYPE_IRON_HALL) {} void Reset() override { - FieryBurst_Timer = 5000; - WarStomp_Timer = 0; + _Reset(); + 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 { //Return since we have no target if (!UpdateVictim()) + { return; - - //FieryBurst_Timer - if (FieryBurst_Timer <= diff) - { - DoCastVictim(SPELL_FIERYBURST); - FieryBurst_Timer = 6000; } - else FieryBurst_Timer -= diff; + events.Update(diff); - //WarStomp_Timer - if (HealthBelowPct(51)) + while (uint32 eventId = events.ExecuteEvent()) { - if (WarStomp_Timer <= diff) + switch (eventId) { + case 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(); } - // 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); - } }; }; diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp index ff908e653..ceeeffb7c 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp @@ -21,12 +21,134 @@ enum Spells { - SPELL_HEAL = 10917, - SPELL_RENEW = 10929, - SPELL_SHIELD = 10901, - SPELL_MINDBLAST = 10947, - SPELL_SHADOWWORDPAIN = 10894, - SPELL_SMITE = 10934 + SPELL_HEAL = 15586, + SPELL_RENEW = 8362, + SPELL_MINDBLAST = 15587, + SPELL_SHADOWBOLT = 15537, + SPELL_WORDPAIN = 15654, +}; + +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 @@ -38,60 +160,25 @@ public: { return GetBlackrockDepthsAI(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) { } - - 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; - } - }; + return GetBlackrockDepthsAI(creature); + } }; void AddSC_boss_moira_bronzebeard() { new boss_moira_bronzebeard(); } + +void AddSC_boss_high_priestess_thaurissan() +{ + new boss_high_priestess_thaurissan(); +} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_okthor.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_okthor.cpp new file mode 100644 index 000000000..609eb9b43 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_okthor.cpp @@ -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 . + */ + +#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(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(); +} diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp index 79c50c858..ba8b879c0 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp @@ -29,28 +29,16 @@ enum Timers TIMER_TOMB_RESET = 15000 }; -enum Creatures +enum Distances { - 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, + RADIUS_RING_OF_LAW = 80, + DISTANCE_EMPEROR_ROOM = 125 +}; - 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 +enum PrincessQuests +{ + PRINCESS_QUEST_HORDE = 4004, + PRINCESS_QUEST_ALLIANCE = 4363 }; enum GameObjects @@ -127,6 +115,8 @@ public: ObjectGuid PhalanxGUID; ObjectGuid MagmusGUID; ObjectGuid MoiraGUID; + ObjectGuid PriestessGUID; + ObjectGuid IronhandGUID[6]; ObjectGuid CorenGUID; ObjectGuid GoArena1GUID; @@ -158,10 +148,68 @@ public: uint32 TombTimer; uint32 TombEventCounter; uint32 OpenedCoofers; + uint32 IronhandCounter; GuidList ArgelmachAdds; 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 ArenaSpectators; + Position CenterOfRingOfLaw = Position(595.289, -186.56); + + ObjectGuid EmperorSenators[5]; + std::vector 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 { memset(&encounter, 0, sizeof(encounter)); @@ -170,8 +218,14 @@ public: GhostKillCount = 0; TombTimer = TIMER_TOMB_START; TombEventCounter = 0; - OpenedCoofers = 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 @@ -214,7 +268,7 @@ public: case NPC_MAGMUS: MagmusGUID = creature->GetGUID(); 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; case NPC_WEAPON_TECHNICIAN: case NPC_DOOMFORGE_ARCANASMITH: @@ -228,6 +282,38 @@ public: case NPC_GOLEM_LORD_ARGELMACH: ArgelmachGUID = creature->GetGUID(); 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: break; } @@ -309,6 +395,7 @@ public: void OnUnitDeath(Unit* unit) override { + uint32 deadSenators = 0; switch (unit->GetEntry()) { case NPC_WEAPON_TECHNICIAN: @@ -317,6 +404,28 @@ public: case NPC_WRATH_HAMMER_CONSTRUCT: ArgelmachAdds.remove(unit->GetGUID()); 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_DOPEREL: case NPC_HATEREL: @@ -343,6 +452,33 @@ public: { case TYPE_RING_OF_LAW: 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; case TYPE_VAULT: encounter[1] = data; @@ -370,9 +506,37 @@ public: break; case TYPE_LYCEUM: 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; case TYPE_IRON_HALL: 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; case DATA_OPEN_COFFER_DOORS: OpenedCoofers += 1; @@ -492,6 +656,12 @@ public: return encounter[4]; case TYPE_IRON_HALL: return encounter[5]; + case DATA_TIME_RING_FAIL: + return timeRingFail; + case DATA_ARENA_MOBS: + return arenaMobsToSpawn; + case DATA_ARENA_BOSS: + return arenaBossToSpawn; } return 0; } diff --git a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp index 40bc88c23..24ac104c6 100644 --- a/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp +++ b/src/server/scripts/EasternKingdoms/eastern_kingdoms_script_loader.cpp @@ -28,9 +28,13 @@ void AddSC_boss_draganthaurissan(); void AddSC_boss_general_angerforge(); void AddSC_boss_gorosh_the_dervish(); 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_magmus(); void AddSC_boss_moira_bronzebeard(); +void AddSC_boss_high_priestess_thaurissan(); void AddSC_boss_tomb_of_seven(); void AddSC_instance_blackrock_depths(); void AddSC_boss_drakkisath(); //Blackrock Spire @@ -172,9 +176,13 @@ void AddEasternKingdomsScripts() AddSC_boss_general_angerforge(); AddSC_boss_gorosh_the_dervish(); AddSC_boss_grizzle(); + AddSC_boss_okthor(); + AddSC_boss_eviscerator(); + AddSC_boss_hedrum(); AddSC_boss_high_interrogator_gerstahn(); AddSC_boss_magmus(); AddSC_boss_moira_bronzebeard(); + AddSC_boss_high_priestess_thaurissan(); AddSC_boss_tomb_of_seven(); AddSC_instance_blackrock_depths(); AddSC_boss_drakkisath(); //Blackrock Spire