From e5b259fb4ad5f48d22f3e47443bb727698c1b5fd Mon Sep 17 00:00:00 2001 From: Malcrom Date: Sun, 10 Nov 2013 03:22:22 -0330 Subject: Scripting/Arcatraz: Move Zereketh the Unbound, Dalliah the Doomsayer, & Wrath-Scryer Soccothrates to cpp scripting and some cleanup. --- src/server/game/Scripting/ScriptLoader.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/server/game/Scripting/ScriptLoader.cpp') diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 17fb3f33eca..779c9be6c0e 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -619,6 +619,9 @@ void AddSC_boss_omor_the_unscarred(); void AddSC_boss_vazruden_the_herald(); void AddSC_instance_ramparts(); void AddSC_arcatraz(); //TK Arcatraz +void AddSC_boss_zereketh_the_unbound(); +void AddSC_boss_dalliah_the_doomsayer(); +void AddSC_boss_wrath_scryer_soccothrates(); void AddSC_boss_harbinger_skyriss(); void AddSC_instance_arcatraz(); void AddSC_boss_high_botanist_freywinn(); //TK Botanica @@ -1140,6 +1143,9 @@ void AddOutlandScripts() AddSC_boss_vazruden_the_herald(); AddSC_instance_ramparts(); AddSC_arcatraz(); //TK Arcatraz + AddSC_boss_zereketh_the_unbound(); + AddSC_boss_dalliah_the_doomsayer(); + AddSC_boss_wrath_scryer_soccothrates(); AddSC_boss_harbinger_skyriss(); AddSC_instance_arcatraz(); AddSC_boss_high_botanist_freywinn(); //TK Botanica -- cgit v1.2.3 From 8332cee0522b9166bd73903b85a3220a84b57a5f Mon Sep 17 00:00:00 2001 From: Malcrom Date: Sun, 10 Nov 2013 10:53:43 -0330 Subject: Scripting/The Slave Pens: Moved boss_mennu_the_betrayer from EAI to CPP. --- sql/updates/world/2013_11_10_01_world_misc.sql | 3 + src/server/game/Scripting/ScriptLoader.cpp | 27 +++- src/server/scripts/Outland/CMakeLists.txt | 4 +- .../TheSlavePens/boss_mennu_the_betrayer.cpp | 143 +++++++++++++++++++++ .../TheSlavePens/instance_the_slave_pens.cpp | 3 +- .../TheSlavePens/the_slave_pens.h | 32 +++++ 6 files changed, 203 insertions(+), 9 deletions(-) create mode 100644 sql/updates/world/2013_11_10_01_world_misc.sql create mode 100644 src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp create mode 100644 src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h (limited to 'src/server/game/Scripting/ScriptLoader.cpp') diff --git a/sql/updates/world/2013_11_10_01_world_misc.sql b/sql/updates/world/2013_11_10_01_world_misc.sql new file mode 100644 index 00000000000..72881a96924 --- /dev/null +++ b/sql/updates/world/2013_11_10_01_world_misc.sql @@ -0,0 +1,3 @@ +UPDATE `creature_template` SET `AIName` = '', `ScriptName`= 'boss_mennu_the_betrayer' WHERE entry=17991; +DELETE FROM creature_ai_scripts WHERE creature_id=17991; +DELETE FROM creature_ai_texts WHERE entry BETWEEN -98 AND -93; diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 779c9be6c0e..bc29d96d1b8 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -575,7 +575,8 @@ void AddSC_boss_grandmaster_vorpil(); void AddSC_boss_murmur(); void AddSC_instance_shadow_labyrinth(); -void AddSC_black_temple(); //Black Temple +//Black Temple +void AddSC_black_temple(); void AddSC_boss_illidan(); void AddSC_boss_shade_of_akama(); void AddSC_boss_supremus(); @@ -586,22 +587,33 @@ void AddSC_boss_teron_gorefiend(); void AddSC_boss_najentus(); void AddSC_boss_illidari_council(); void AddSC_instance_black_temple(); -void AddSC_boss_fathomlord_karathress(); //CR Serpent Shrine Cavern + +//Coilfang Reservoir - Serpent Shrine Cavern +void AddSC_boss_fathomlord_karathress(); void AddSC_boss_hydross_the_unstable(); void AddSC_boss_lady_vashj(); void AddSC_boss_leotheras_the_blind(); void AddSC_boss_morogrim_tidewalker(); void AddSC_instance_serpentshrine_cavern(); void AddSC_boss_the_lurker_below(); -void AddSC_boss_hydromancer_thespia(); //CR Steam Vault + +//Coilfang Reservoir - The Steam Vault +void AddSC_boss_hydromancer_thespia(); void AddSC_boss_mekgineer_steamrigger(); void AddSC_boss_warlord_kalithresh(); void AddSC_instance_steam_vault(); -void AddSC_instance_the_slave_pens(); //The Slave Pens -void AddSC_boss_hungarfen(); //CR Underbog -void AddSC_boss_the_black_stalker(); + +//Coilfang Reservoir - The Slave Pens +void AddSC_instance_the_slave_pens(); +void AddSC_boss_mennu_the_betrayer(); + +//Coilfang Reservoir - The Underbog void AddSC_instance_the_underbog(); -void AddSC_boss_gruul(); //Gruul's Lair +void AddSC_boss_hungarfen(); +void AddSC_boss_the_black_stalker(); + +//Gruul's Lair +void AddSC_boss_gruul(); void AddSC_boss_high_king_maulgar(); void AddSC_instance_gruuls_lair(); void AddSC_boss_broggok(); //HC Blood Furnace @@ -1122,6 +1134,7 @@ void AddOutlandScripts() AddSC_boss_warlord_kalithresh(); AddSC_instance_steam_vault(); AddSC_instance_the_slave_pens(); //The Slave Pens + AddSC_boss_mennu_the_betrayer(); AddSC_boss_hungarfen(); //CR Underbog AddSC_boss_the_black_stalker(); AddSC_instance_the_underbog(); diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt index 45db8a80a26..e07424a77d2 100644 --- a/src/server/scripts/Outland/CMakeLists.txt +++ b/src/server/scripts/Outland/CMakeLists.txt @@ -43,9 +43,11 @@ set(scripts_STAT_SRCS Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp Outland/CoilfangReservoir/SerpentShrine/boss_morogrim_tidewalker.cpp Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp + Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h + Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp + Outland/CoilfangReservoir/TheUnderbog/instance_the_underbog.cpp Outland/CoilfangReservoir/TheUnderbog/boss_hungarfen.cpp Outland/CoilfangReservoir/TheUnderbog/boss_the_black_stalker.cpp - Outland/CoilfangReservoir/TheUnderbog/instance_the_underbog.cpp Outland/zone_shattrath_city.cpp Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp new file mode 100644 index 00000000000..d015919d978 --- /dev/null +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 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 . + */ + +/* ScriptData +SDName: boss_mennu_the_betrayer +SD%Complete: 100% +SDComment: +SDCategory: Coilfang Reservoir, The Slave Pens +EndScriptData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "the_slave_pens.h" + +enum Say +{ + SAY_AGGRO = 0, + SAY_SLAY = 1, + SAY_DEATH = 2 +}; + +enum Spells +{ + SPELL_TAINTED_STONESKIN_TOTEM = 31985, + SPELL_TAINTED_EARTHGRAB_TOTEM = 31981, + SPELL_CORRUPTED_NOVA_TOTEM = 31991, + SPELL_MENNUS_HEALING_WARD = 34980, + SPELL_LIGHTNING_BOLT = 35010 +}; + +enum Events +{ + EVENT_TAINTED_STONESKIN_TOTEM = 1, + EVENT_TAINTED_EARTHGRAB_TOTEM = 2, + EVENT_CORRUPTED_NOVA_TOTEM = 3, + EVENT_LIGHTNING_BOLT = 4 +}; + +class boss_mennu_the_betrayer : public CreatureScript +{ + public: + boss_mennu_the_betrayer() : CreatureScript("boss_mennu_the_betrayer") { } + + struct boss_mennu_the_betrayerAI : public BossAI + { + boss_mennu_the_betrayerAI(Creature* creature) : BossAI(creature, DATA_MENNU_THE_BETRAYER) { } + + void Reset() OVERRIDE + { + _Reset(); + healingWardDropped = false; + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + Talk(SAY_DEATH); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + events.ScheduleEvent(EVENT_TAINTED_STONESKIN_TOTEM, 18000); + events.ScheduleEvent(EVENT_TAINTED_EARTHGRAB_TOTEM, 19000); + events.ScheduleEvent(EVENT_CORRUPTED_NOVA_TOTEM, 20000); + events.ScheduleEvent(EVENT_LIGHTNING_BOLT, urand(5000, 8000)); + Talk(SAY_AGGRO); + } + + void KilledUnit(Unit* /*victim*/) OVERRIDE + { + Talk(SAY_SLAY); + } + + 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 EVENT_TAINTED_STONESKIN_TOTEM: + DoCast(me, SPELL_TAINTED_STONESKIN_TOTEM); + break; + case EVENT_TAINTED_EARTHGRAB_TOTEM: + DoCast(me, SPELL_TAINTED_EARTHGRAB_TOTEM); + break; + case EVENT_CORRUPTED_NOVA_TOTEM: + DoCast(me, SPELL_CORRUPTED_NOVA_TOTEM); + break; + case EVENT_LIGHTNING_BOLT: + DoCastVictim(SPELL_LIGHTNING_BOLT, true); + events.ScheduleEvent(EVENT_LIGHTNING_BOLT, urand(7000, 11000)); + break; + default: + break; + } + } + + if (HealthBelowPct(60) && !healingWardDropped) + { + DoCast(me, SPELL_MENNUS_HEALING_WARD); + healingWardDropped = true; + } + + DoMeleeAttackIfReady(); + } + + private: + bool healingWardDropped; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new boss_mennu_the_betrayerAI(creature); + } +}; + +void AddSC_boss_mennu_the_betrayer() +{ + new boss_mennu_the_betrayer(); +} diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp index cd11e2e1bf1..1c31bee7d4f 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp @@ -24,11 +24,12 @@ gets instead the deserter debuff. #include "ScriptMgr.h" #include "InstanceScript.h" +#include "the_slave_pens.h" class instance_the_slave_pens : public InstanceMapScript { public: - instance_the_slave_pens() : InstanceMapScript("instance_the_slave_pens", 547) { } + instance_the_slave_pens() : InstanceMapScript(SPScriptName, 547) { } InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE { diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h new file mode 100644 index 00000000000..624ead7ef08 --- /dev/null +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 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 . + */ + +#ifndef SLAVE_PENS_H +#define SLAVE_PENS_H + +uint32 const EncounterCount = 3; + +#define SPScriptName "instance_the_slave_pens" + +enum DataTypes +{ + DATA_MENNU_THE_BETRAYER = 1, + DATA_ROKMAR_THE_CRACKLER = 2, + DATA_QUAGMIRRAN = 3 +}; + +#endif // SLAVE_PENS_H -- cgit v1.2.3 From 113735690a06217a9648ddd6c8de2aa932c89db8 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Sun, 10 Nov 2013 18:00:15 -0330 Subject: Scripts/The Slave Pens: Fix up Mennu the Betrayer and add Rokmar the Cracker & Quagmirran. --- sql/updates/world/2013_11_10_02_world_misc.sql | 13 +++ src/server/game/Scripting/ScriptLoader.cpp | 43 ++++--- src/server/scripts/Outland/CMakeLists.txt | 2 + .../TheSlavePens/boss_mennu_the_betrayer.cpp | 44 ++++--- .../TheSlavePens/boss_quagmirran.cpp | 124 ++++++++++++++++++++ .../TheSlavePens/boss_rokmar_the_crackler.cpp | 127 +++++++++++++++++++++ 6 files changed, 316 insertions(+), 37 deletions(-) create mode 100644 sql/updates/world/2013_11_10_02_world_misc.sql create mode 100644 src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_quagmirran.cpp create mode 100644 src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_rokmar_the_crackler.cpp (limited to 'src/server/game/Scripting/ScriptLoader.cpp') diff --git a/sql/updates/world/2013_11_10_02_world_misc.sql b/sql/updates/world/2013_11_10_02_world_misc.sql new file mode 100644 index 00000000000..6049724f6d3 --- /dev/null +++ b/sql/updates/world/2013_11_10_02_world_misc.sql @@ -0,0 +1,13 @@ +UPDATE `creature_template` SET `AIName` = '', `ScriptName`= 'boss_rokmar_the_crackler' WHERE entry=17991; +DELETE FROM creature_ai_scripts WHERE creature_id=17991; +UPDATE `creature_template` SET `AIName` = '', `ScriptName`= 'boss_mennu_the_betrayer' WHERE entry=17941; +DELETE FROM creature_ai_scripts WHERE creature_id=17941; +DELETE FROM creature_ai_texts WHERE entry BETWEEN -98 AND -93; +UPDATE `creature_template` SET `AIName` = '', `ScriptName`= 'boss_quagmirran' WHERE entry=17942; +DELETE FROM creature_ai_scripts WHERE creature_id=17942; + +-- Add missing spelldifficulty_dbc values +DELETE FROM `spelldifficulty_dbc` WHERE `id` IN (31956,34780); +INSERT INTO `spelldifficulty_dbc` (`id`,`spellid0`,`spellid1`) VALUES +(31956,31956,39005), -- Rokmar the Crackler +(34780,34780,39340); -- Quagmirran diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index bc29d96d1b8..28fe883feb9 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -575,7 +575,7 @@ void AddSC_boss_grandmaster_vorpil(); void AddSC_boss_murmur(); void AddSC_instance_shadow_labyrinth(); -//Black Temple +// Black Temple void AddSC_black_temple(); void AddSC_boss_illidan(); void AddSC_boss_shade_of_akama(); @@ -588,7 +588,7 @@ void AddSC_boss_najentus(); void AddSC_boss_illidari_council(); void AddSC_instance_black_temple(); -//Coilfang Reservoir - Serpent Shrine Cavern +// Coilfang Reservoir - Serpent Shrine Cavern void AddSC_boss_fathomlord_karathress(); void AddSC_boss_hydross_the_unstable(); void AddSC_boss_lady_vashj(); @@ -597,22 +597,24 @@ void AddSC_boss_morogrim_tidewalker(); void AddSC_instance_serpentshrine_cavern(); void AddSC_boss_the_lurker_below(); -//Coilfang Reservoir - The Steam Vault +// Coilfang Reservoir - The Steam Vault void AddSC_boss_hydromancer_thespia(); void AddSC_boss_mekgineer_steamrigger(); void AddSC_boss_warlord_kalithresh(); void AddSC_instance_steam_vault(); -//Coilfang Reservoir - The Slave Pens +// Coilfang Reservoir - The Slave Pens void AddSC_instance_the_slave_pens(); void AddSC_boss_mennu_the_betrayer(); +void AddSC_boss_rokmar_the_crackler(); +void AddSC_boss_quagmirran(); -//Coilfang Reservoir - The Underbog +// Coilfang Reservoir - The Underbog void AddSC_instance_the_underbog(); void AddSC_boss_hungarfen(); void AddSC_boss_the_black_stalker(); -//Gruul's Lair +// Gruul's Lair void AddSC_boss_gruul(); void AddSC_boss_high_king_maulgar(); void AddSC_instance_gruuls_lair(); @@ -1111,7 +1113,8 @@ void AddOutlandScripts() AddSC_boss_murmur(); AddSC_instance_shadow_labyrinth(); - AddSC_black_temple(); //Black Temple + // Black Temple + AddSC_black_temple(); AddSC_boss_illidan(); AddSC_boss_shade_of_akama(); AddSC_boss_supremus(); @@ -1122,23 +1125,35 @@ void AddOutlandScripts() AddSC_boss_najentus(); AddSC_boss_illidari_council(); AddSC_instance_black_temple(); - AddSC_boss_fathomlord_karathress(); //CR Serpent Shrine Cavern + + // Coilfang Reservoir - Serpent Shrine Cavern + AddSC_boss_fathomlord_karathress(); AddSC_boss_hydross_the_unstable(); AddSC_boss_lady_vashj(); AddSC_boss_leotheras_the_blind(); AddSC_boss_morogrim_tidewalker(); AddSC_instance_serpentshrine_cavern(); AddSC_boss_the_lurker_below(); - AddSC_boss_hydromancer_thespia(); //CR Steam Vault + + // Coilfang Reservoir - The Steam Vault + AddSC_instance_steam_vault(); + AddSC_boss_hydromancer_thespia(); AddSC_boss_mekgineer_steamrigger(); AddSC_boss_warlord_kalithresh(); - AddSC_instance_steam_vault(); - AddSC_instance_the_slave_pens(); //The Slave Pens + + // Coilfang Reservoir - The Slave Pens + AddSC_instance_the_slave_pens(); AddSC_boss_mennu_the_betrayer(); - AddSC_boss_hungarfen(); //CR Underbog - AddSC_boss_the_black_stalker(); + AddSC_boss_rokmar_the_crackler(); + AddSC_boss_quagmirran(); + + // Coilfang Reservoir - The Underbog AddSC_instance_the_underbog(); - AddSC_boss_gruul(); //Gruul's Lair + AddSC_boss_hungarfen(); + AddSC_boss_the_black_stalker(); + + // Gruul's Lair + AddSC_boss_gruul(); AddSC_boss_high_king_maulgar(); AddSC_instance_gruuls_lair(); AddSC_boss_broggok(); //HC Blood Furnace diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt index e07424a77d2..ab10ee2dfe4 100644 --- a/src/server/scripts/Outland/CMakeLists.txt +++ b/src/server/scripts/Outland/CMakeLists.txt @@ -45,6 +45,8 @@ set(scripts_STAT_SRCS Outland/CoilfangReservoir/TheSlavePens/instance_the_slave_pens.cpp Outland/CoilfangReservoir/TheSlavePens/the_slave_pens.h Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp + Outland/CoilfangReservoir/TheSlavePens/boss_rokmar_the_crackler.cpp + Outland/CoilfangReservoir/TheSlavePens/boss_quagmirran.cpp Outland/CoilfangReservoir/TheUnderbog/instance_the_underbog.cpp Outland/CoilfangReservoir/TheUnderbog/boss_hungarfen.cpp Outland/CoilfangReservoir/TheUnderbog/boss_the_black_stalker.cpp diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp index d015919d978..ba59aa3b463 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_mennu_the_betrayer.cpp @@ -17,7 +17,7 @@ /* ScriptData SDName: boss_mennu_the_betrayer -SD%Complete: 100% +SD%Complete: 95% SDComment: SDCategory: Coilfang Reservoir, The Slave Pens EndScriptData */ @@ -35,11 +35,11 @@ enum Say enum Spells { - SPELL_TAINTED_STONESKIN_TOTEM = 31985, - SPELL_TAINTED_EARTHGRAB_TOTEM = 31981, - SPELL_CORRUPTED_NOVA_TOTEM = 31991, - SPELL_MENNUS_HEALING_WARD = 34980, - SPELL_LIGHTNING_BOLT = 35010 + SPELL_TAINTED_STONESKIN_TOTEM = 31985, // every 30 sec if health below 100% + SPELL_TAINTED_EARTHGRAB_TOTEM = 31981, // ? + SPELL_CORRUPTED_NOVA_TOTEM = 31991, // ? + SPELL_MENNUS_HEALING_WARD = 34980, // every 14 - 25 sec + SPELL_LIGHTNING_BOLT = 35010 // every 14 - 19 sec }; enum Events @@ -47,7 +47,8 @@ enum Events EVENT_TAINTED_STONESKIN_TOTEM = 1, EVENT_TAINTED_EARTHGRAB_TOTEM = 2, EVENT_CORRUPTED_NOVA_TOTEM = 3, - EVENT_LIGHTNING_BOLT = 4 + EVENT_MENNUS_HEALING_WARD = 4, + EVENT_LIGHTNING_BOLT = 5 }; class boss_mennu_the_betrayer : public CreatureScript @@ -62,7 +63,6 @@ class boss_mennu_the_betrayer : public CreatureScript void Reset() OVERRIDE { _Reset(); - healingWardDropped = false; } void JustDied(Unit* /*killer*/) OVERRIDE @@ -74,10 +74,11 @@ class boss_mennu_the_betrayer : public CreatureScript void EnterCombat(Unit* /*who*/) OVERRIDE { _EnterCombat(); - events.ScheduleEvent(EVENT_TAINTED_STONESKIN_TOTEM, 18000); - events.ScheduleEvent(EVENT_TAINTED_EARTHGRAB_TOTEM, 19000); - events.ScheduleEvent(EVENT_CORRUPTED_NOVA_TOTEM, 20000); - events.ScheduleEvent(EVENT_LIGHTNING_BOLT, urand(5000, 8000)); + events.ScheduleEvent(EVENT_TAINTED_STONESKIN_TOTEM, 30000); + events.ScheduleEvent(EVENT_TAINTED_EARTHGRAB_TOTEM, 20000); + events.ScheduleEvent(EVENT_CORRUPTED_NOVA_TOTEM, 60000); + events.ScheduleEvent(EVENT_MENNUS_HEALING_WARD, urand(14000, 25000)); + events.ScheduleEvent(EVENT_LIGHTNING_BOLT, urand(14000, 19000)); Talk(SAY_AGGRO); } @@ -101,7 +102,9 @@ class boss_mennu_the_betrayer : public CreatureScript switch (eventId) { case EVENT_TAINTED_STONESKIN_TOTEM: - DoCast(me, SPELL_TAINTED_STONESKIN_TOTEM); + if (HealthBelowPct(100)) + DoCast(me, SPELL_TAINTED_STONESKIN_TOTEM); + events.ScheduleEvent(EVENT_TAINTED_STONESKIN_TOTEM, 30000); break; case EVENT_TAINTED_EARTHGRAB_TOTEM: DoCast(me, SPELL_TAINTED_EARTHGRAB_TOTEM); @@ -109,26 +112,21 @@ class boss_mennu_the_betrayer : public CreatureScript case EVENT_CORRUPTED_NOVA_TOTEM: DoCast(me, SPELL_CORRUPTED_NOVA_TOTEM); break; + case EVENT_MENNUS_HEALING_WARD: + DoCast(me, SPELL_MENNUS_HEALING_WARD); + events.ScheduleEvent(EVENT_MENNUS_HEALING_WARD, urand(14000, 25000)); + break; case EVENT_LIGHTNING_BOLT: DoCastVictim(SPELL_LIGHTNING_BOLT, true); - events.ScheduleEvent(EVENT_LIGHTNING_BOLT, urand(7000, 11000)); + events.ScheduleEvent(EVENT_LIGHTNING_BOLT, urand(14000, 25000)); break; default: break; } } - if (HealthBelowPct(60) && !healingWardDropped) - { - DoCast(me, SPELL_MENNUS_HEALING_WARD); - healingWardDropped = true; - } - DoMeleeAttackIfReady(); } - - private: - bool healingWardDropped; }; CreatureAI* GetAI(Creature* creature) const OVERRIDE diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_quagmirran.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_quagmirran.cpp new file mode 100644 index 00000000000..6cef7291542 --- /dev/null +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_quagmirran.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 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 . + */ + +/* ScriptData +SDName: boss_quagmirran +SD%Complete: 100% +SDComment: +SDCategory: Coilfang Reservoir, The Slave Pens +EndScriptData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "the_slave_pens.h" + +enum Spells +{ + SPELL_ACID_SPRAY = 38153, + SPELL_CLEAVE = 40504, + SPELL_UPPERCUT = 32055, + SPELL_POISON_BOLT_VOLLEY = 34780 // 39340 +}; + +enum Events +{ + EVENT_ACID_SPRAY = 1, + EVENT_CLEAVE = 2, + EVENT_UPPERCUT = 3, + EVENT_POISON_BOLT_VOLLEY = 4 +}; + +class boss_quagmirran : public CreatureScript +{ + public: + boss_quagmirran() : CreatureScript("boss_quagmirran") { } + + struct boss_quagmirranAI : public BossAI + { + boss_quagmirranAI(Creature* creature) : BossAI(creature, DATA_QUAGMIRRAN) { } + + void Reset() OVERRIDE + { + _Reset(); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + events.ScheduleEvent(EVENT_ACID_SPRAY, 25000); + events.ScheduleEvent(EVENT_CLEAVE, 9000); + events.ScheduleEvent(EVENT_UPPERCUT, 20000); + events.ScheduleEvent(EVENT_POISON_BOLT_VOLLEY, 31000); + } + + void KilledUnit(Unit* /*victim*/) OVERRIDE { } + + 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 EVENT_ACID_SPRAY: + DoCastAOE(SPELL_ACID_SPRAY); + events.ScheduleEvent(EVENT_ACID_SPRAY, urand(20000, 25000)); + break; + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE, true); + events.ScheduleEvent(EVENT_CLEAVE, urand(18000, 34000)); + break; + case EVENT_UPPERCUT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 10.0f, true)) + DoCast(target, SPELL_UPPERCUT); + events.ScheduleEvent(EVENT_UPPERCUT, 22000); + break; + case EVENT_POISON_BOLT_VOLLEY: + DoCast(me, SPELL_POISON_BOLT_VOLLEY); + events.ScheduleEvent(EVENT_POISON_BOLT_VOLLEY, 24000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new boss_quagmirranAI(creature); + } +}; + +void AddSC_boss_quagmirran() +{ + new boss_quagmirran(); +} diff --git a/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_rokmar_the_crackler.cpp b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_rokmar_the_crackler.cpp new file mode 100644 index 00000000000..a025df5c3ae --- /dev/null +++ b/src/server/scripts/Outland/CoilfangReservoir/TheSlavePens/boss_rokmar_the_crackler.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 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 . + */ + +/* ScriptData +SDName: boss_rokmar_the_crackler +SD%Complete: 100% +SDComment: +SDCategory: Coilfang Reservoir, The Slave Pens +EndScriptData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "the_slave_pens.h" + +enum Spells +{ + SPELL_GRIEVOUS_WOUND = 31956, + SPELL_ENSNARING_MOSS = 31948, + SPELL_WATER_SPIT = 35008, + SPELL_FRENZY = 34970 +}; + +enum Events +{ + EVENT_GRIEVOUS_WOUND = 1, + EVENT_ENSNARING_MOSS = 2, + EVENT_WATER_SPIT = 3 +}; + +class boss_rokmar_the_crackler : public CreatureScript +{ + public: + boss_rokmar_the_crackler() : CreatureScript("boss_rokmar_the_crackler") { } + + struct boss_rokmar_the_cracklerAI : public BossAI + { + boss_rokmar_the_cracklerAI(Creature* creature) : BossAI(creature, DATA_MENNU_THE_BETRAYER) { } + + void Reset() OVERRIDE + { + _Reset(); + rokmarFrenzy = false; + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + events.ScheduleEvent(EVENT_GRIEVOUS_WOUND, 10000); + events.ScheduleEvent(EVENT_ENSNARING_MOSS, 20000); + events.ScheduleEvent(EVENT_WATER_SPIT, 14000); + } + + void KilledUnit(Unit* /*victim*/) OVERRIDE { } + + 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 EVENT_GRIEVOUS_WOUND: + DoCastVictim(SPELL_GRIEVOUS_WOUND, true); + events.ScheduleEvent(EVENT_GRIEVOUS_WOUND, urand(20000, 30000)); + break; + case EVENT_ENSNARING_MOSS: + DoCastAOE(SPELL_ENSNARING_MOSS); + events.ScheduleEvent(EVENT_ENSNARING_MOSS, urand(20000, 30000)); + break; + case EVENT_WATER_SPIT: + DoCastAOE(SPELL_WATER_SPIT); + events.ScheduleEvent(EVENT_WATER_SPIT, urand(14000, 18000)); + break; + default: + break; + } + } + + if (HealthBelowPct(10) && !rokmarFrenzy) + { + DoCast(me, SPELL_FRENZY); + rokmarFrenzy = true; + } + + DoMeleeAttackIfReady(); + } + + private: + bool rokmarFrenzy; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new boss_rokmar_the_cracklerAI(creature); + } +}; + +void AddSC_boss_rokmar_the_crackler() +{ + new boss_rokmar_the_crackler(); +} -- cgit v1.2.3 From 89de7e74198e517dc7105f73af0f1d74c3629c64 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Sat, 7 Dec 2013 21:19:46 -0330 Subject: Scripting/Razorfen Downs: Additions and fixes for instance. Moved bosses Glutton, Mordresh Fire Eye, Tuten Kash to cpp. Cleaned up code for boss Amnennar The Coldbringer. Fixed up gong event for gong to have sound and proper spawning. Scripted quest 3525 "Extinguishing the Idol" so you can now fight Plagmaw the Rotting. --- sql/updates/world/2013_12_07_00_world_misc.sql | 77 +++++ src/server/game/Scripting/ScriptLoader.cpp | 10 +- src/server/scripts/Kalimdor/CMakeLists.txt | 5 +- .../boss_amnennar_the_coldbringer.cpp | 115 +++---- .../Kalimdor/RazorfenDowns/boss_glutton.cpp | 95 ++++++ .../RazorfenDowns/boss_mordresh_fire_eye.cpp | 136 ++++++++ .../Kalimdor/RazorfenDowns/boss_tuten_kash.cpp | 107 +++++++ .../RazorfenDowns/instance_razorfen_downs.cpp | 270 ++++++++-------- .../Kalimdor/RazorfenDowns/razorfen_downs.cpp | 345 +++++++++++++++++++-- .../Kalimdor/RazorfenDowns/razorfen_downs.h | 51 ++- 10 files changed, 988 insertions(+), 223 deletions(-) create mode 100644 sql/updates/world/2013_12_07_00_world_misc.sql create mode 100644 src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp create mode 100644 src/server/scripts/Kalimdor/RazorfenDowns/boss_mordresh_fire_eye.cpp create mode 100644 src/server/scripts/Kalimdor/RazorfenDowns/boss_tuten_kash.cpp (limited to 'src/server/game/Scripting/ScriptLoader.cpp') diff --git a/sql/updates/world/2013_12_07_00_world_misc.sql b/sql/updates/world/2013_12_07_00_world_misc.sql new file mode 100644 index 00000000000..42063be2e3a --- /dev/null +++ b/sql/updates/world/2013_12_07_00_world_misc.sql @@ -0,0 +1,77 @@ +-- Talk text for Mordresh Fire Eye from sniff +SET @ENTRY := 7357; +DELETE FROM `creature_text` WHERE `entry`=@ENTRY; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(@ENTRY,0,0,'We will enslave the quilboar!',12,0,100,1,0,5819, 'Mordresh Fire Eye - SAY_OOC_1'), +(@ENTRY,1,0,'We will spread across this barren land!',12,0,100,1,0,5820, 'Mordresh Fire Eye - SAY_OOC_2'), +(@ENTRY,2,0,'Soon, the Scourge will rule the world!',12,0,100,22,0,5821, 'Mordresh Fire Eye - SAY_OOC_3'), +(@ENTRY,3,0,'Slay them, my brethren! For the Scourge!',14,0,100,0,0,5822, 'Mordresh Fire Eye - SAY_AGGRO'); + +-- Talk text for Belnistrasz from sniff +SET @ENTRY := 8516; +DELETE FROM `creature_text` WHERE `entry`=@ENTRY; +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(@ENTRY,0,0,'All right, stay close. These fiends will jump right out of the shadows at you if you let your guard down.',12,0,100,0,0,0,'Belnistrasz SAY_QUEST_ACCEPTED'), +(@ENTRY,1,0,'Okay, here we go. It's going to take about five minutes to shut this thing down through the ritual. Once I start, keep the vermin off of me or it will be the end of us all!',12,0,100,0,0,0,'Belnistrasz SAY_EVENT_START'), +(@ENTRY,2,0,'Three minutes left -- I can feel the energy starting to build! Keep up the solid defense!',14,0,100,0,0,0,'Belnistrasz SAY_EVENT_THREE_MIN_LEFT'), +(@ENTRY,3,0,'Just two minutes to go! We're half way there, but don't let your guard down!',14,0,100,0,0,0,'Belnistrasz SAY_EVENT_TWO_MIN_LEFT'), +(@ENTRY,4,0,'One more minute! Hold on now, the ritual is about to take hold!',14,0,100,0,0,0,'Belnistrasz SAY_EVENT_ONE_MIN_LEFT'), +(@ENTRY,5,0,'That's it -- we made it! The ritual is set in motion, and idol fires are about to go out for good! You truly are the heroes I thought you would be!',14,0,100,4,0,0,'Belnistrasz SAY_EVENT_END'), +(@ENTRY,6,0,'You'll rue the day you crossed me, $N',12,0,100,0,0,0,'Belnistrasz SAY_AGGRO'); +(@ENTRY,7,0,'Watch out for the $N!',12,0,100,0,0,0,'Belnistrasz SAY_WATCH_OUT'); + +-- Fix trigger location +UPDATE `creature_template` SET `InhabitType`=4, `flags_extra`=`flags_extra`|128 WHERE `entry`=8662; + +-- Condition for spell Belnistrasz Idol Shutdown Visual +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=12774; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 12774, 0, 0, 31, 0, 3, 8662, 0, 0, 0, 0, '', 'Belnistrasz Idol Shutdown Visual targets Idol Oven Fire Target'); + +-- Add cpp scripts +UPDATE creature_template SET `AIName`= '',ScriptName = 'boss_tuten_kash' WHERE entry=7355; +UPDATE creature_template SET `AIName`= '',ScriptName = 'boss_mordresh_fire_eye' WHERE entry=7357; +UPDATE creature_template SET `AIName`= '',ScriptName = 'boss_glutton' WHERE entry=8567; +UPDATE creature_template SET `AIName`= '',ScriptName = 'npc_belnistrasz' WHERE entry=8516; +UPDATE creature_template SET `AIName`= '',ScriptName = 'npc_idol_room_spawner' WHERE entry=8611; +DELETE FROM `smart_scripts` WHERE `entryorguid` IN (7355,7357,8567,8516) AND `source_type`=0; + +-- Pathing for Belnistrasz Entry: 8516 +SET @NPC := 87171; +SET @PATH := @NPC * 10; +DELETE FROM `creature_template_addon` WHERE `entry`=8516; +INSERT INTO `creature_template_addon` (`entry`,`path_id`,`bytes2`,`mount`,`auras`) VALUES (8516,@PATH,1,0, ''); +DELETE FROM `waypoint_data` WHERE `id`=@PATH; +INSERT INTO `waypoint_data` (`id`,`point`,`position_x`,`position_y`,`position_z`,`orientation`,`delay`,`move_flag`,`action`,`action_chance`,`wpguid`) VALUES +(@PATH,1,2603.313,724.335,54.608,0,0,1,0,100,0), +(@PATH,2,2593.379,726.272,55.112,0,0,1,0,100,0), +(@PATH,3,2588.499,733.1947,55.3959,0,0,1,0,100,0), +(@PATH,4,2572.573,752.5162,54.71815,0,0,1,0,100,0), +(@PATH,5,2558.068,748.3008,54.3559,0,0,1,0,100,0), +(@PATH,6,2539.677,777.1356,46.95155,0,0,1,0,100,0), +(@PATH,7,2527.828,800.8403,44.74713,0,0,1,0,100,0), +(@PATH,8,2495.996,785.7536,39.51203,0,0,1,0,100,0), +(@PATH,9,2484.358,814.8914,43.57789,0,0,1,0,100,0), +(@PATH,10,2501.128,847.9614,47.5574,0,0,1,0,100,0), +(@PATH,11,2537.36,874.4713,47.67798,0,0,1,0,100,0), +(@PATH,12,2548.493,894.6515,47.69307,0,0,1,0,100,0), +(@PATH,13,2541.478,910.5101,46.17223,0,0,1,0,100,0), +(@PATH,14,2519.403,925.6332,46.51501,0,0,1,0,100,0), +(@PATH,15,2527.237,951.4606,49.2807,0,0,1,0,100,0), +(@PATH,16,2541.675,976.5887,50.41221,0,0,1,0,100,0), +(@PATH,17,2554.084,973.8665,50.36161,0,0,1,0,100,0), +(@PATH,18,2575.601,950.1381,52.84592,0,0,1,0,100,0); + +DELETE FROM `creature_questender` WHERE `id`=8516 AND `quest`=3525; +DELETE FROM `gameobject_questender` WHERE `id`=152097 AND `quest`=3525; +INSERT INTO `gameobject_questender` (`id`,`quest`) VALUES (152097,3525); + +-- Death's Head Geomancer SAI +SET @ENTRY := 7335; +UPDATE `creature_template` SET `AIName`="SmartAI" WHERE `entry`=@ENTRY; +DELETE FROM `smart_scripts` WHERE `entryorguid`=@ENTRY AND `source_type`=0; +INSERT INTO `smart_scripts` (`entryorguid`,`source_type`,`id`,`link`,`event_type`,`event_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action_type`,`action_param1`,`action_param2`,`action_param3`,`action_param4`,`action_param5`,`action_param6`,`target_type`,`target_param1`,`target_param2`,`target_param3`,`target_x`,`target_y`,`target_z`,`target_o`,`comment`) VALUES +(@ENTRY,0,0,0,0,0,100,2,0,0,3000,4000,11,9053,64,0,0,0,0,2,0,0,0,0,0,0,0,"Death's Head Geomancer - Combat - Cast Fireball (Normal Dungeon)"), +(@ENTRY,0,1,0,0,0,100,2,8000,10000,6000,15000,11,6725,0,0,0,0,0,5,0,0,0,0,0,0,0,"Death's Head Geomancer - Combat - Cast Flame Spike (Normal Dungeon)"), +(@ENTRY,0,2,0,0,0,100,2,12000,16000,8000,20000,11,11436,1,0,0,0,0,5,0,0,0,0,0,0,0,"Death's Head Geomancer - Combat - Cast Slow (Normal Dungeon)"), +(@ENTRY,0,3,0,2,0,100,3,0,15,0,0,25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,"Death's Head Geomancer - 0-15% Health - Flee For Assist (Normal Dungeon)"); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 28fe883feb9..b486eb45915 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -321,7 +321,10 @@ void AddSC_boss_ptheradras(); void AddSC_instance_maraudon(); void AddSC_boss_onyxia(); //Onyxia's Lair void AddSC_instance_onyxias_lair(); -void AddSC_boss_amnennar_the_coldbringer(); //Razorfen Downs +void AddSC_boss_tuten_kash(); //Razorfen Downs +void AddSC_boss_mordresh_fire_eye(); +void AddSC_boss_glutton(); +void AddSC_boss_amnennar_the_coldbringer(); void AddSC_razorfen_downs(); void AddSC_instance_razorfen_downs(); void AddSC_razorfen_kraul(); //Razorfen Kraul @@ -1032,7 +1035,10 @@ void AddKalimdorScripts() AddSC_instance_maraudon(); AddSC_boss_onyxia(); //Onyxia's Lair AddSC_instance_onyxias_lair(); - AddSC_boss_amnennar_the_coldbringer(); //Razorfen Downs + AddSC_boss_tuten_kash(); //Razorfen Downs + AddSC_boss_mordresh_fire_eye(); + AddSC_boss_glutton(); + AddSC_boss_amnennar_the_coldbringer(); AddSC_razorfen_downs(); AddSC_instance_razorfen_downs(); AddSC_razorfen_kraul(); //Razorfen Kraul diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt index 17c360a54b2..c02e896a87d 100644 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ b/src/server/scripts/Kalimdor/CMakeLists.txt @@ -15,12 +15,15 @@ set(scripts_STAT_SRCS Kalimdor/zone_moonglade.cpp Kalimdor/RazorfenDowns/razorfen_downs.cpp Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp + Kalimdor/RazorfenDowns/boss_tuten_kash.cpp + Kalimdor/RazorfenDowns/boss_mordresh_fire_eye.cpp + Kalimdor/RazorfenDowns/boss_glutton.cpp Kalimdor/RazorfenDowns/boss_amnennar_the_coldbringer.cpp Kalimdor/RazorfenDowns/razorfen_downs.h - Kalimdor/ZulFarrak/zulfarrak.h Kalimdor/ZulFarrak/zulfarrak.cpp Kalimdor/ZulFarrak/instance_zulfarrak.cpp Kalimdor/ZulFarrak/boss_zum_rah.cpp + Kalimdor/ZulFarrak/zulfarrak.h Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_epoch_hunter.cpp Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/old_hillsbrad.h Kalimdor/CavernsOfTime/EscapeFromDurnholdeKeep/boss_leutenant_drake.cpp diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/boss_amnennar_the_coldbringer.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/boss_amnennar_the_coldbringer.cpp index 4a4d7fe4b07..323fd92a8f6 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/boss_amnennar_the_coldbringer.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/boss_amnennar_the_coldbringer.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore - * Copyright (C) 2006-2009 ScriptDev2 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,63 +15,57 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Amnennar_the_coldbringer -SD%Complete: 100 -SDComment: -SDCategory: Razorfen Downs -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "razorfen_downs.h" -enum AmnennarTheColdbringer +enum Say { SAY_AGGRO = 0, SAY_SUMMON60 = 1, SAY_SUMMON30 = 2, SAY_HP = 3, - SAY_KILL = 4, + SAY_KILL = 4 +}; +enum Spells +{ SPELL_AMNENNARSWRATH = 13009, SPELL_FROSTBOLT = 15530, SPELL_FROST_NOVA = 15531, SPELL_FROST_SPECTRES = 12642 }; +enum Events +{ + EVENT_AMNENNARSWRATH = 1, + EVENT_FROSTBOLT = 2, + EVENT_FROST_NOVA = 3 +}; + class boss_amnennar_the_coldbringer : public CreatureScript { public: boss_amnennar_the_coldbringer() : CreatureScript("boss_amnennar_the_coldbringer") { } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_amnennar_the_coldbringerAI(creature); - } - - struct boss_amnennar_the_coldbringerAI : public ScriptedAI + struct boss_amnennar_the_coldbringerAI : public BossAI { - boss_amnennar_the_coldbringerAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 AmnenarsWrath_Timer; - uint32 FrostBolt_Timer; - uint32 FrostNova_Timer; - bool Spectrals60; - bool Spectrals30; - bool Hp; + boss_amnennar_the_coldbringerAI(Creature* creature) : BossAI(creature, DATA_AMNENNAR_THE_COLD_BRINGER) { } void Reset() OVERRIDE { - AmnenarsWrath_Timer = 8000; - FrostBolt_Timer = 1000; - FrostNova_Timer = urand(10000, 15000); - Spectrals30 = false; - Spectrals60 = false; - Hp = false; + _Reset(); + hp60Spectrals = false; + hp30Spectrals = false; + hp50 = false; } void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); + events.ScheduleEvent(EVENT_AMNENNARSWRATH, 8000); + events.ScheduleEvent(EVENT_FROSTBOLT, 1000); + events.ScheduleEvent(EVENT_FROST_NOVA, urand(10000, 15000)); Talk(SAY_AGGRO); } @@ -81,55 +74,73 @@ public: Talk(SAY_KILL); } + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + } + void UpdateAI(uint32 diff) OVERRIDE { if (!UpdateVictim()) return; - //AmnenarsWrath_Timer - if (AmnenarsWrath_Timer <= diff) - { - DoCastVictim(SPELL_AMNENNARSWRATH); - AmnenarsWrath_Timer = 12000; - } else AmnenarsWrath_Timer -= diff; + events.Update(diff); - //FrostBolt_Timer - if (FrostBolt_Timer <= diff) - { - DoCastVictim(SPELL_FROSTBOLT); - FrostBolt_Timer = 8000; - } else FrostBolt_Timer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (FrostNova_Timer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - DoCast(me, SPELL_FROST_NOVA); - FrostNova_Timer = 15000; - } else FrostNova_Timer -= diff; + switch (eventId) + { + case EVENT_AMNENNARSWRATH: + DoCastVictim(SPELL_AMNENNARSWRATH); + events.ScheduleEvent(EVENT_AMNENNARSWRATH, 12000); + break; + case EVENT_FROSTBOLT: + DoCastVictim(SPELL_FROSTBOLT); + events.ScheduleEvent(EVENT_FROSTBOLT, 8000); + break; + case EVENT_FROST_NOVA: + DoCast(me, SPELL_FROST_NOVA); + events.ScheduleEvent(EVENT_FROST_NOVA, 15000); + break; + } + } - if (!Spectrals60 && HealthBelowPct(60)) + if (!hp60Spectrals && HealthBelowPct(60)) { Talk(SAY_SUMMON60); DoCastVictim(SPELL_FROST_SPECTRES); - Spectrals60 = true; + hp60Spectrals = true; } - if (!Hp && HealthBelowPct(50)) + if (!hp50 && HealthBelowPct(50)) { Talk(SAY_HP); - Hp = true; + hp50 = true; } - if (!Spectrals30 && HealthBelowPct(30)) + if (!hp30Spectrals && HealthBelowPct(30)) { Talk(SAY_SUMMON30); DoCastVictim(SPELL_FROST_SPECTRES); - Spectrals30 = true; + hp30Spectrals = true; } DoMeleeAttackIfReady(); } + + private: + bool hp60Spectrals; + bool hp30Spectrals; + bool hp50; }; + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new boss_amnennar_the_coldbringerAI(creature); + } }; void AddSC_boss_amnennar_the_coldbringer() diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp new file mode 100644 index 00000000000..a249013bd6a --- /dev/null +++ b/src/server/scripts/Kalimdor/RazorfenDowns/boss_glutton.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 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 "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "razorfen_downs.h" + +enum Say +{ + SAY_HP50 = 0, + SAY_HP15 = 1 +}; + +enum Spells +{ + SPELL_DISEASE_CLOUD = 12627, + SPELL_FRENZY = 12795 +}; + +class boss_glutton : public CreatureScript +{ +public: + boss_glutton() : CreatureScript("boss_glutton") { } + + struct boss_gluttonAI : public BossAI + { + boss_gluttonAI(Creature* creature) : BossAI(creature, DATA_GLUTTON) { } + + void Reset() OVERRIDE + { + _Reset(); + hp50 = false; + hp15 = false; + } + + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + if (!UpdateVictim()) + return; + + if (!hp50 && HealthBelowPct(50)) + { + Talk(SAY_HP50); + hp50 = true; + } + + if (!hp15 && HealthBelowPct(15)) + { + Talk(SAY_HP15); + DoCast(me, SPELL_FRENZY); + hp15 = true; + } + + DoMeleeAttackIfReady(); + } + + private: + bool hp50; + bool hp15; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new boss_gluttonAI(creature); + } +}; + +void AddSC_boss_glutton() +{ + new boss_glutton(); +} diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/boss_mordresh_fire_eye.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/boss_mordresh_fire_eye.cpp new file mode 100644 index 00000000000..1f45de3c4c6 --- /dev/null +++ b/src/server/scripts/Kalimdor/RazorfenDowns/boss_mordresh_fire_eye.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 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 "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "razorfen_downs.h" + +enum Say +{ + SAY_OOC_1 = 0, + SAY_OOC_2 = 1, + SAY_OOC_3 = 2, + SAY_AGGRO = 3 +}; + +enum Spells +{ + SPELL_FIREBALL = 12466, + SPELL_FIRE_NOVA = 12470 +}; + +enum Events +{ + EVENT_OOC_1 = 1, + EVENT_OOC_2 = 2, + EVENT_OOC_3 = 3, + EVENT_OOC_4 = 4, + EVENT_FIREBALL = 5, + EVENT_FIRE_NOVA = 6 +}; + +class boss_mordresh_fire_eye : public CreatureScript +{ +public: + boss_mordresh_fire_eye() : CreatureScript("boss_mordresh_fire_eye") { } + + struct boss_mordresh_fire_eyeAI : public BossAI + { + boss_mordresh_fire_eyeAI(Creature* creature) : BossAI(creature, DATA_MORDRESH_FIRE_EYE) { } + + void Reset() OVERRIDE + { + _Reset(); + events.ScheduleEvent(EVENT_OOC_1, 10000); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + events.Reset(); + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_FIREBALL, 100); + events.ScheduleEvent(EVENT_FIRE_NOVA, urand(8000, 12000)); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + } + + void UpdateAI(uint32 diff) OVERRIDE + { + events.Update(diff); + + if (!UpdateVictim()) + { + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_OOC_1: + Talk(SAY_OOC_1); + events.ScheduleEvent(EVENT_OOC_2, 8000); + break; + case EVENT_OOC_2: + Talk(SAY_OOC_2); + events.ScheduleEvent(EVENT_OOC_3, 3000); + break; + case EVENT_OOC_3: + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + events.ScheduleEvent(EVENT_OOC_4, 6000); + break; + case EVENT_OOC_4: + Talk(SAY_OOC_3); + events.ScheduleEvent(EVENT_OOC_1, 14000); + break; + } + } + return; + } + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FIREBALL: + DoCastVictim(SPELL_FIREBALL); + events.ScheduleEvent(EVENT_FIREBALL, urand(2400, 3800)); + break; + case EVENT_FIRE_NOVA: + DoCast(me, SPELL_FIRE_NOVA); + events.ScheduleEvent(EVENT_FIRE_NOVA, urand(11000, 16000)); + break; + } + } + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new boss_mordresh_fire_eyeAI(creature); + } +}; + +void AddSC_boss_mordresh_fire_eye() +{ + new boss_mordresh_fire_eye(); +} diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/boss_tuten_kash.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/boss_tuten_kash.cpp new file mode 100644 index 00000000000..5cf8a2992a3 --- /dev/null +++ b/src/server/scripts/Kalimdor/RazorfenDowns/boss_tuten_kash.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008-2013 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 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 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 "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "razorfen_downs.h" + +enum Spells +{ + SPELL_THRASH = 8876, + SPELL_WEB_SPRAY = 12252, + SPELL_VIRULENT_POISON = 12254, + SPELL_CURSE_OF_TUTENKASH = 12255 +}; + +enum Events +{ + EVENT_WEB_SPRAY = 1, + EVENT_CURSE_OF_TUTENKASH = 2 +}; + +class boss_tuten_kash : public CreatureScript +{ +public: + boss_tuten_kash() : CreatureScript("boss_tuten_kash") { } + + struct boss_tuten_kashAI : public BossAI + { + boss_tuten_kashAI(Creature* creature) : BossAI(creature, DATA_TUTEN_KASH) { } + + void Reset() OVERRIDE + { + _Reset(); + if (!me->HasAura(SPELL_THRASH)) + DoCast(me, SPELL_THRASH); + if (!me->HasAura(SPELL_VIRULENT_POISON)) + DoCast(me, SPELL_VIRULENT_POISON); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + events.ScheduleEvent(EVENT_WEB_SPRAY, urand(3000, 5000)); + events.ScheduleEvent(EVENT_CURSE_OF_TUTENKASH, urand(9000, 14000)); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + } + + 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 EVENT_WEB_SPRAY: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, false)) + { + if (!target->HasAura(SPELL_WEB_SPRAY)) + DoCast(target, SPELL_WEB_SPRAY); + } + events.ScheduleEvent(EVENT_WEB_SPRAY, urand(6000, 8000)); + break; + case EVENT_CURSE_OF_TUTENKASH: + DoCast(me, SPELL_CURSE_OF_TUTENKASH); + events.ScheduleEvent(EVENT_CURSE_OF_TUTENKASH, urand(15000, 25000)); + break; + } + } + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new boss_tuten_kashAI(creature); + } +}; + +void AddSC_boss_tuten_kash() +{ + new boss_tuten_kash(); +} diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp index 091c7e46585..097f340891a 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/instance_razorfen_downs.cpp @@ -16,199 +16,219 @@ */ #include "ScriptMgr.h" +#include "ObjectMgr.h" #include "InstanceScript.h" #include "razorfen_downs.h" #include "Player.h" #include "TemporarySummon.h" -#define MAX_ENCOUNTER 1 +Position const PosSummonTutenkash[15] = +{ + // 7349 Tomb Fiend + { 2487.339f, 805.9111f, 43.08361f, 2.844887f }, + { 2485.405f, 804.1145f, 43.68511f, 3.054326f }, + { 2488.431f, 801.2809f, 42.70374f, 4.29351f }, + { 2489.914f, 804.7949f, 43.25175f, 1.658063f }, + { 2541.246f, 907.0941f, 46.64201f, 2.024582f }, + { 2544.701f, 907.6331f, 46.38007f, 1.605703f }, + { 2541.49f, 911.1756f, 46.26493f, 4.817109f }, + { 2544.693f, 912.8887f, 46.39912f, 2.129302f }, + { 2524.036f, 834.4852f, 48.37031f, 0.8028514f }, + { 2527.017f, 829.9793f, 48.06498f, 0.6981317f }, + // 7351 Tomb Reaver + { 2542.818f, 904.9359f, 46.80911f, 4.642576f }, + { 2543.287f, 911.2448f, 46.32785f, 0.6806784f }, + { 2489.083f, 806.5914f, 43.21102f, 3.682645f }, + { 2486.828f, 802.8737f, 43.19883f, 2.9147f }, + // 7355 Tuten'kash + { 2487.939f, 804.2224f, 43.10735f, 1.692969f } +}; class instance_razorfen_downs : public InstanceMapScript { public: - instance_razorfen_downs() : InstanceMapScript("instance_razorfen_downs", 129) { } - - InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE - { - return new instance_razorfen_downs_InstanceMapScript(map); - } + instance_razorfen_downs() : InstanceMapScript(RFDScriptName, 129) { } struct instance_razorfen_downs_InstanceMapScript : public InstanceScript { instance_razorfen_downs_InstanceMapScript(Map* map) : InstanceScript(map) { + SetBossNumber(EncounterCount); } - uint64 uiGongGUID; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - - uint16 uiGongWaves; - - std::string str_data; - void Initialize() OVERRIDE { - uiGongGUID = 0; - - uiGongWaves = 0; - - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - } - - std::string GetSaveData() OVERRIDE - { - OUT_SAVE_INST_DATA; - - std::ostringstream saveStream; - - saveStream << "T C " << m_auiEncounter[0] - << ' ' << uiGongWaves; - - str_data = saveStream.str(); - - OUT_SAVE_INST_DATA_COMPLETE; - return str_data; + goGongGUID = 0; + gongWave = 0; + fiendsKilled = 0; + reaversKilled = 0; + summonLowRange = 0; + summonHighRange = 0; + summonCreature = 0; } - void Load(const char* in) OVERRIDE + void OnGameObjectCreate(GameObject* gameObject) OVERRIDE { - if (!in) + switch (gameObject->GetEntry()) { - OUT_LOAD_INST_DATA_FAIL; - return; + case GO_GONG: + goGongGUID = gameObject->GetGUID(); + if (GetBossState(DATA_TUTEN_KASH) == DONE) + gameObject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + break; + case GO_IDOL_OVEN_FIRE: + case GO_IDOL_CUP_FIRE: + case GO_IDOL_MOUTH_FIRE: + if (GetBossState(DATA_EXTINGUISHING_THE_IDOL) == DONE) + gameObject->Delete(); + break; + default: + break; } - - OUT_LOAD_INST_DATA(in); - - char dataHead1, dataHead2; - uint16 data0, data1; - - std::istringstream loadStream(in); - loadStream >> dataHead1 >> dataHead2 >> data0 >> data1; - - if (dataHead1 == 'T' && dataHead2 == 'C') - { - m_auiEncounter[0] = data0; - - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; - - uiGongWaves = data1; - } else OUT_LOAD_INST_DATA_FAIL; - - OUT_LOAD_INST_DATA_COMPLETE; } - void OnGameObjectCreate(GameObject* go) OVERRIDE + bool SetBossState(uint32 type, EncounterState state) OVERRIDE { - switch (go->GetEntry()) + if (!InstanceScript::SetBossState(type, state)) + return false; + + switch (type) { - case GO_GONG: - uiGongGUID = go->GetGUID(); - if (m_auiEncounter[0] == DONE) - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + case DATA_TUTEN_KASH: + case DATA_MORDRESH_FIRE_EYE: + case DATA_GLUTTON: + case DATA_AMNENNAR_THE_COLD_BRINGER: + case DATA_GONG: + case DATA_WAVE: + case DATA_EXTINGUISHING_THE_IDOL: break; default: break; } + return true; } - void SetData(uint32 uiType, uint32 uiData) OVERRIDE + void SetData(uint32 type, uint32 data) OVERRIDE { - if (uiType == DATA_GONG_WAVES) + if (type == DATA_WAVE) { - uiGongWaves = uiData; - - switch (uiGongWaves) + switch (data) { - case 9: - case 14: - if (GameObject* go = instance->GetGameObject(uiGongGUID)) - go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - break; - case 1: - case 10: - case 16: + case IN_PROGRESS: { - GameObject* go = instance->GetGameObject(uiGongGUID); - - if (!go) - return; - - go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - - uint32 uiCreature = 0; - uint8 uiSummonTimes = 0; + if (GameObject* go = instance->GetGameObject(goGongGUID)) + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - switch (uiGongWaves) + switch (gongWave) { - case 1: - uiCreature = NPC_TOMB_FIEND; - uiSummonTimes = 7; - break; - case 10: - uiCreature = NPC_TOMB_REAVER; - uiSummonTimes = 3; + case 0: + summonLowRange = 0; + summonHighRange = 10; + summonCreature = NPC_TOMB_FIEND; break; - case 16: - uiCreature = NPC_TUTEN_KASH; + case 1: + summonLowRange = 10; + summonHighRange = 14; + summonCreature = NPC_TOMB_REAVER; break; - default: + case 2: + summonLowRange = 14; + summonHighRange = 15; + summonCreature = NPC_TUTEN_KASH; break; } - if (Creature* creature = go->SummonCreature(uiCreature, 2502.635f, 844.140f, 46.896f, 0.633f)) + if (GameObject* go = instance->GetGameObject(goGongGUID)) { - if (uiGongWaves == 10 || uiGongWaves == 1) + for (uint8 i = summonLowRange; i < summonHighRange; ++i) { - for (uint8 i = 0; i < uiSummonTimes; ++i) - { - if (Creature* summon = go->SummonCreature(uiCreature, 2502.635f + float(irand(-5, 5)), 844.140f + float(irand(-5, 5)), 46.896f, 0.633f)) - summon->GetMotionMaster()->MovePoint(0, 2533.479f + float(irand(-5, 5)), 870.020f + float(irand(-5, 5)), 47.678f); - } + Creature* creature = go->SummonCreature(summonCreature, PosSummonTutenkash[i]); + creature->GetMotionMaster()->MovePoint(0, 2533.479f + float(irand(-5, 5)), 870.020f + float(irand(-5, 5)), 47.678f); } - creature->GetMotionMaster()->MovePoint(0, 2533.479f + float(irand(-5, 5)), 870.020f + float(irand(-5, 5)), 47.678f); } + + ++gongWave; break; } - default: + case NPC_TOMB_FIEND: + if (++fiendsKilled == 10) + { + fiendsKilled = 0; + if (GameObject* go = instance->GetGameObject(goGongGUID)) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } + break; + case NPC_TOMB_REAVER: + if (++reaversKilled == 4) + { + reaversKilled = 0; + if (GameObject* go = instance->GetGameObject(goGongGUID)) + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } break; } + } - if (uiType == BOSS_TUTEN_KASH) - { - m_auiEncounter[0] = uiData; + } - if (uiData == DONE) - SaveToDB(); - } + std::string GetSaveData() OVERRIDE + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << "R D " << GetBossSaveData(); + + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); } - uint32 GetData(uint32 uiType) const OVERRIDE + void Load(const char* str) OVERRIDE { - switch (uiType) + if (!str) { - case DATA_GONG_WAVES: - return uiGongWaves; + OUT_LOAD_INST_DATA_FAIL; + return; } - return 0; - } + OUT_LOAD_INST_DATA(str); - uint64 GetData64(uint32 uiType) const OVERRIDE - { - switch (uiType) + char dataHead1, dataHead2; + + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; + + if (dataHead1 == 'R' && dataHead2 == 'D') { - case DATA_GONG: return uiGongGUID; + for (uint32 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + SetBossState(i, EncounterState(tmpState)); + } } + else + OUT_LOAD_INST_DATA_FAIL; - return 0; + OUT_LOAD_INST_DATA_COMPLETE; } + + protected: + uint64 goGongGUID; + uint16 gongWave; + uint8 fiendsKilled; + uint8 reaversKilled; + uint8 summonLowRange; + uint8 summonHighRange; + uint32 summonCreature; }; + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_razorfen_downs_InstanceMapScript(map); + } }; void AddSC_instance_razorfen_downs() diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp index 320c9970077..f81d634e019 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp +++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.cpp @@ -32,6 +32,11 @@ EndContentData */ #include "ScriptedGossip.h" #include "razorfen_downs.h" #include "Player.h" +#include "GridDefines.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "ObjectDefines.h" +#include "ObjectMgr.h" /*### # npc_henry_stern @@ -101,32 +106,272 @@ public: }; /*###### -## go_gong +## npc_belnistrasz for Quest 3525 "Extinguishing the Idol" ######*/ -class go_gong : public GameObjectScript +Position const PosSummonSpawner[3] = +{ + { 2582.789f, 954.3925f, 52.48214f, 3.787364f }, + { 2569.42f, 956.3801f, 52.27323f, 5.427974f }, + { 2570.62f, 942.3934f, 53.7433f, 0.715585f } +}; + +enum Belnistrasz +{ + EVENT_CHANNEL = 1, + EVENT_IDOL_ROOM_SPAWNER = 2, + EVENT_PROGRESS = 3, + EVENT_COMPLETE = 4, + EVENT_FIREBALL = 5, + EVENT_FROST_NOVA = 6, + + FACTION_ESCORT = 250, + + PATH_ESCORT = 871710, + POINT_REACH_IDOL = 17, + + QUEST_EXTINGUISHING_THE_IDOL = 3525, + + SAY_QUEST_ACCEPTED = 0, + SAY_EVENT_START = 1, + SAY_EVENT_THREE_MIN_LEFT = 2, + SAY_EVENT_TWO_MIN_LEFT = 3, + SAY_EVENT_ONE_MIN_LEFT = 4, + SAY_EVENT_END = 5, + SAY_AGGRO = 6, // Combat + SAY_WATCH_OUT = 7, // 25% chance to target random creature and say on wave spawn + + SPELL_ARCANE_INTELLECT = 13326, + SPELL_FIREBALL = 9053, + SPELL_FROST_NOVA = 11831, + SPELL_IDOL_SHUTDOWN_VISUAL = 12774, // Hits Unit Entry: 8662 + SPELL_IDOM_ROOM_CAMERA_SHAKE = 12816 // Dummy needs scripting +}; + +class npc_belnistrasz : public CreatureScript { public: - go_gong() : GameObjectScript("go_gong") { } + npc_belnistrasz() : CreatureScript("npc_belnistrasz") { } - bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE + struct npc_belnistraszAI : public ScriptedAI { - //basic support, not blizzlike data is missing... - InstanceScript* instance = go->GetInstanceScript(); + npc_belnistraszAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + eventInProgress = false; + } - if (instance) + void Reset() OVERRIDE { - instance->SetData(DATA_GONG_WAVES, instance->GetData(DATA_GONG_WAVES)+1); - return true; + if (!eventInProgress) + { + if (!me->HasAura(SPELL_ARCANE_INTELLECT)) + DoCast(me, SPELL_ARCANE_INTELLECT); + + channeling = false; + eventProgress = 0; + spawnerCount = 0; + me->SetFlag(UNIT_NPC_FLAGS, GOSSIP_OPTION_QUESTGIVER); + } } - return false; + void EnterCombat(Unit* who) OVERRIDE + { + if (channeling) + { + Talk(SAY_WATCH_OUT, who->GetGUID()); + } + else + { + events.ScheduleEvent(EVENT_FIREBALL, 1000); + events.ScheduleEvent(EVENT_FROST_NOVA, urand(8000, 12000)); + if (urand(0, 100) > 40) + Talk(SAY_AGGRO, who->GetGUID()); + } + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + instance->SetBossState(DATA_EXTINGUISHING_THE_IDOL, DONE); + me->DespawnOrUnsummon(5000); + } + + void sQuestAccept(Player* /*player*/, Quest const* quest) OVERRIDE + { + if (quest->GetQuestId() == QUEST_EXTINGUISHING_THE_IDOL) + { + eventInProgress = true; + Talk(SAY_QUEST_ACCEPTED); + me->RemoveFlag(UNIT_NPC_FLAGS, GOSSIP_OPTION_QUESTGIVER); + me->setFaction(FACTION_ESCORT); + me->GetMotionMaster()->MovePath(PATH_ESCORT, false); + } + } + + void MovementInform(uint32 type, uint32 id) OVERRIDE + { + if (type == WAYPOINT_MOTION_TYPE && id == POINT_REACH_IDOL) + { + channeling = true; + events.ScheduleEvent(EVENT_CHANNEL, 2000); + } + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!eventInProgress) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CHANNEL: + Talk(SAY_EVENT_START); + DoCast(me, SPELL_IDOL_SHUTDOWN_VISUAL); + events.ScheduleEvent(EVENT_IDOL_ROOM_SPAWNER, 100); + events.ScheduleEvent(EVENT_PROGRESS, 120000); + break; + case EVENT_IDOL_ROOM_SPAWNER: + if (Creature* creature = me->SummonCreature(NPC_IDOL_ROOM_SPAWNER, PosSummonSpawner[urand(0,2)], TEMPSUMMON_TIMED_DESPAWN, 4000)) + creature->AI()->SetData(0,spawnerCount); + if (++spawnerCount < 8) + events.ScheduleEvent(EVENT_IDOL_ROOM_SPAWNER, 35000); + break; + case EVENT_PROGRESS: + { + switch (eventProgress) + { + case 0: + Talk(SAY_EVENT_THREE_MIN_LEFT); + ++eventProgress; + events.ScheduleEvent(EVENT_PROGRESS, 60000); + break; + case 1: + Talk(SAY_EVENT_TWO_MIN_LEFT); + ++eventProgress; + events.ScheduleEvent(EVENT_PROGRESS, 60000); + break; + case 2: + Talk(SAY_EVENT_ONE_MIN_LEFT); + ++eventProgress; + events.ScheduleEvent(EVENT_PROGRESS, 60000); + break; + case 3: + events.CancelEvent(EVENT_IDOL_ROOM_SPAWNER); + me->InterruptSpell(CURRENT_CHANNELED_SPELL); + Talk(SAY_EVENT_END); + events.ScheduleEvent(EVENT_COMPLETE, 3000); + break; + } + break; + } + case EVENT_COMPLETE: + { + DoCast(me, SPELL_IDOM_ROOM_CAMERA_SHAKE); + me->SummonGameObject(GO_BELNISTRASZS_BRAZIER, 2577.196f, 947.0781f, 53.16757f, 2.356195f, 0, 0, 0.9238796f, 0.3826832f, 3600000); + std::list ClusterList; + Trinity::AllWorldObjectsInRange objects(me, 50.0f); + Trinity::WorldObjectListSearcher searcher(me, ClusterList, objects); + me->VisitNearbyObject(50.0f, searcher); + for (std::list::const_iterator itr = ClusterList.begin(); itr != ClusterList.end(); ++itr) + { + if (Player* player = (*itr)->ToPlayer()) + { + if (player->GetQuestStatus(QUEST_EXTINGUISHING_THE_IDOL) == QUEST_STATUS_INCOMPLETE) + player->CompleteQuest(QUEST_EXTINGUISHING_THE_IDOL); + } + else if (GameObject* go = (*itr)->ToGameObject()) + { + if (go->GetEntry() == GO_IDOL_OVEN_FIRE || go->GetEntry() == GO_IDOL_CUP_FIRE || go->GetEntry() == GO_IDOL_MOUTH_FIRE) + go->Delete(); + } + } + instance->SetBossState(DATA_EXTINGUISHING_THE_IDOL, DONE); + me->DespawnOrUnsummon(); + break; + } + case EVENT_FIREBALL: + if (me->HasUnitState(UNIT_STATE_CASTING) || !UpdateVictim()) + return; + DoCastVictim(SPELL_FIREBALL); + events.ScheduleEvent(EVENT_FIREBALL, 8000); + break; + case EVENT_FROST_NOVA: + if (me->HasUnitState(UNIT_STATE_CASTING) || !UpdateVictim()) + return; + DoCast(me, SPELL_FROST_NOVA); + events.ScheduleEvent(EVENT_FROST_NOVA, 15000); + break; + } + } + if (!channeling) + DoMeleeAttackIfReady(); + } + + private: + InstanceScript* instance; + EventMap events; + bool eventInProgress; + bool channeling; + uint8 eventProgress; + uint8 spawnerCount; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_belnistraszAI(creature); } +}; + +class npc_idol_room_spawner : public CreatureScript +{ +public: + npc_idol_room_spawner() : CreatureScript("npc_idol_room_spawner") { } + + struct npc_idol_room_spawnerAI : public ScriptedAI + { + npc_idol_room_spawnerAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } + + void Reset() OVERRIDE { } + void SetData(uint32 /*type*/, uint32 data) OVERRIDE + { + if(!instance) + return; + + if (data < 7) + { + me->SummonCreature(NPC_WITHERED_BATTLE_BOAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + if (data > 0 && me->GetOrientation() < 4.0f) + me->SummonCreature(NPC_WITHERED_BATTLE_BOAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + me->SummonCreature(NPC_DEATHS_HEAD_GEOMANCER, me->GetPositionX() + (cos(me->GetOrientation() - (M_PI/2)) * 2), me->GetPositionY() + (sin(me->GetOrientation() - (M_PI/2)) * 2), me->GetPositionZ(), me->GetOrientation()); + me->SummonCreature(NPC_WITHERED_QUILGUARD, me->GetPositionX() + (cos(me->GetOrientation() + (M_PI/2)) * 2), me->GetPositionY() + (sin(me->GetOrientation() + (M_PI/2)) * 2), me->GetPositionZ(), me->GetOrientation()); + } + else if (data =7) + me->SummonCreature(NPC_PLAGUEMAW_THE_ROTTING, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + } + + private: + InstanceScript* instance; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_idol_room_spawnerAI(creature); + } }; enum TombCreature { + EVENT_WEB = 7, + SPELL_POISON_PROC = 3616, + SPELL_VIRULENT_POISON_PROC = 12254, SPELL_WEB = 745 }; @@ -135,11 +380,6 @@ class npc_tomb_creature : public CreatureScript public: npc_tomb_creature() : CreatureScript("npc_tomb_creature") { } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_tomb_creatureAI(creature); - } - struct npc_tomb_creatureAI : public ScriptedAI { npc_tomb_creatureAI(Creature* creature) : ScriptedAI(creature) @@ -147,45 +387,86 @@ public: instance = creature->GetInstanceScript(); } - InstanceScript* instance; + void Reset() OVERRIDE + { + if (!me->HasAura(SPELL_POISON_PROC) && me->GetEntry() == NPC_TOMB_FIEND) + DoCast(me, SPELL_POISON_PROC); - uint32 uiWebTimer; + if (!me->HasAura(SPELL_VIRULENT_POISON_PROC) && me->GetEntry() == NPC_TOMB_REAVER) + DoCast(me, SPELL_VIRULENT_POISON_PROC); + } - void Reset() OVERRIDE + void JustDied(Unit* /*killer*/) OVERRIDE + { + if (instance) + instance->SetData(DATA_WAVE, me->GetEntry()); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE { - uiWebTimer = urand(5000, 8000); + events.ScheduleEvent(EVENT_WEB, urand(5000, 8000)); } - void UpdateAI(uint32 uiDiff) OVERRIDE + void UpdateAI(uint32 diff) OVERRIDE { if (!UpdateVictim()) return; - //from acid - if (me->GetEntry() == NPC_TOMB_REAVER) + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) { - if (uiWebTimer <= uiDiff) + switch (eventId) { - DoCastVictim(SPELL_WEB); - uiWebTimer = urand(7000, 16000); - } else uiWebTimer -= uiDiff; + case EVENT_WEB: + DoCastVictim(SPELL_WEB); + events.ScheduleEvent(EVENT_WEB, urand(7000, 16000)); + break; + } } - DoMeleeAttackIfReady(); } - void JustDied(Unit* /*killer*/) OVERRIDE + private: + InstanceScript* instance; + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_tomb_creatureAI(creature); + } +}; + +/*###### +## go_gong +######*/ + +class go_gong : public GameObjectScript +{ +public: + go_gong() : GameObjectScript("go_gong") { } + + bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE + { + InstanceScript* instance = go->GetInstanceScript(); + + if (instance) { - if (instance) - instance->SetData(DATA_GONG_WAVES, instance->GetData(DATA_GONG_WAVES)+1); + go->SendCustomAnim(0); + instance->SetData(DATA_WAVE, IN_PROGRESS); + return true; } - }; + return false; + } }; void AddSC_razorfen_downs() { new npc_henry_stern(); - new go_gong(); + new npc_belnistrasz(); + new npc_idol_room_spawner(); new npc_tomb_creature(); + new go_gong(); } diff --git a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h index c0f63474f23..9fe5314fda0 100644 --- a/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h +++ b/src/server/scripts/Kalimdor/RazorfenDowns/razorfen_downs.h @@ -18,27 +18,56 @@ #ifndef DEF_RAZORFEN_DOWNS_H #define DEF_RAZORFEN_DOWNS_H -enum Data +#define RFDScriptName "instance_razorfen_downs" + +uint32 const EncounterCount = 5; + +enum DataTypes { - BOSS_TUTEN_KASH, - DATA_GONG_WAVES + // Main Bosses + DATA_TUTEN_KASH = 0, + DATA_MORDRESH_FIRE_EYE = 1, + DATA_GLUTTON = 2, + DATA_AMNENNAR_THE_COLD_BRINGER = 3, + // Events + DATA_GONG = 4, + DATA_WAVE = 5, + DATA_EXTINGUISHING_THE_IDOL = 6 }; -enum Data64 +enum CreatureIds { - DATA_GONG + // Used in Tuten Kash summon event + NPC_TOMB_FIEND = 7349, + NPC_TOMB_REAVER = 7351, + NPC_TUTEN_KASH = 7355, + // Used for quest 3525 "Extinguishing the Idol" + NPC_IDOL_ROOM_SPAWNER = 8611, + NPC_WITHERED_BATTLE_BOAR = 7333, + NPC_DEATHS_HEAD_GEOMANCER = 7335, + NPC_WITHERED_QUILGUARD = 7329, + NPC_PLAGUEMAW_THE_ROTTING = 7356 }; enum GameObjectIds { - GO_GONG = 148917 + // Used for Tuten Kash summon event + GO_GONG = 148917, + // Used for quest 3525 "Extinguishing the Idol" + GO_IDOL_OVEN_FIRE = 151951, + GO_IDOL_CUP_FIRE = 151952, + GO_IDOL_MOUTH_FIRE = 151973, + GO_BELNISTRASZS_BRAZIER = 152097 }; -enum CreatureId +template +CreatureAI* GetRazorfenDownsAI(Creature* creature) { - NPC_TOMB_FIEND = 7349, - NPC_TOMB_REAVER = 7351, - NPC_TUTEN_KASH = 7355 -}; + if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) + if (instance->GetInstanceScript()) + if (instance->GetScriptId() == sObjectMgr->GetScriptId(RFDScriptName)) + return new AI(creature); + return NULL; +} #endif -- cgit v1.2.3