diff options
18 files changed, 1024 insertions, 828 deletions
diff --git a/sql/updates/world/2013_08_26_03_world_auchindoun.sql b/sql/updates/world/2013_08_26_03_world_auchindoun.sql new file mode 100644 index 00000000000..cf726fa41c5 --- /dev/null +++ b/sql/updates/world/2013_08_26_03_world_auchindoun.sql @@ -0,0 +1,12 @@ +UPDATE `instance_template` SET `script`='instance_auchenai_crypts' WHERE `map`=558; +UPDATE `instance_template` SET `script`='instance_mana_tombs' WHERE `map`=557; + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (33923, 38796, 33666, 38795, 39365); +INSERT INTO `spell_script_names`(`spell_id`, `ScriptName`) VALUES +(33923, 'spell_murmur_sonic_boom'), +(38796, 'spell_murmur_sonic_boom'), +(33666, 'spell_murmur_sonic_boom_effect'), +(38795, 'spell_murmur_sonic_boom_effect'), +(39365, 'spell_murmur_thundering_storm'); + +DELETE FROM `creature_ai_scripts` WHERE `id`=1879605; diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index ed0972c3301..513cfe74b6a 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -533,20 +533,31 @@ void AddSC_zuldrak(); void AddSC_crystalsong_forest(); void AddSC_isle_of_conquest(); -//outland -void AddSC_boss_exarch_maladaar(); //Auchindoun Auchenai Crypts +// Outland + +// Auchindoun - Auchenai Crypts void AddSC_boss_shirrak_the_dead_watcher(); -void AddSC_boss_nexusprince_shaffar(); //Auchindoun Mana Tombs +void AddSC_boss_exarch_maladaar(); +void AddSC_instance_auchenai_crypts(); + +// Auchindoun - Mana Tombs void AddSC_boss_pandemonius(); -void AddSC_boss_darkweaver_syth(); //Auchindoun Sekketh Halls +void AddSC_boss_nexusprince_shaffar(); +void AddSC_instance_mana_tombs(); + +// Auchindoun - Sekketh Halls +void AddSC_boss_darkweaver_syth(); void AddSC_boss_talon_king_ikiss(); void AddSC_boss_anzu(); void AddSC_instance_sethekk_halls(); -void AddSC_instance_shadow_labyrinth(); //Auchindoun Shadow Labyrinth + +// Auchindoun - Shadow Labyrinth void AddSC_boss_ambassador_hellmaw(); void AddSC_boss_blackheart_the_inciter(); void AddSC_boss_grandmaster_vorpil(); void AddSC_boss_murmur(); +void AddSC_instance_shadow_labyrinth(); + void AddSC_black_temple(); //Black Temple void AddSC_boss_illidan(); void AddSC_boss_shade_of_akama(); @@ -1042,19 +1053,29 @@ void AddKalimdorScripts() void AddOutlandScripts() { #ifdef SCRIPTS - AddSC_boss_exarch_maladaar(); //Auchindoun Auchenai Crypts + // Auchindoun - Auchenai Crypts AddSC_boss_shirrak_the_dead_watcher(); - AddSC_boss_nexusprince_shaffar(); //Auchindoun Mana Tombs + AddSC_boss_exarch_maladaar(); + AddSC_instance_auchenai_crypts(); + + // Auchindoun - Mana Tombs AddSC_boss_pandemonius(); - AddSC_boss_darkweaver_syth(); //Auchindoun Sekketh Halls + AddSC_boss_nexusprince_shaffar(); + AddSC_instance_mana_tombs(); + + // Auchindoun - Sekketh Halls + AddSC_boss_darkweaver_syth(); AddSC_boss_talon_king_ikiss(); AddSC_boss_anzu(); AddSC_instance_sethekk_halls(); - AddSC_instance_shadow_labyrinth(); //Auchindoun Shadow Labyrinth + + // Auchindoun - Shadow Labyrinth AddSC_boss_ambassador_hellmaw(); AddSC_boss_blackheart_the_inciter(); AddSC_boss_grandmaster_vorpil(); AddSC_boss_murmur(); + AddSC_instance_shadow_labyrinth(); + AddSC_black_temple(); //Black Temple AddSC_boss_illidan(); AddSC_boss_shade_of_akama(); diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h new file mode 100644 index 00000000000..21e82a1702d --- /dev/null +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef AUCHENAI_CRYPTS_H_ +#define AUCHENAI_CRYPTS_H_ + +#define ACScriptName "instance_auchenai_crypts" + +uint32 const EncounterCount = 2; + +enum DataTypes +{ + // Encounter States/Boss GUIDs + DATA_SHIRRAK_THE_DEAD_WATCHER = 0, + DATA_EXARCH_MALADAAR = 1 +}; + +enum CreatureIds +{ +}; + +enum GameObjectIds +{ +}; + +template<class AI> +AI* GetAuchenaiCryptsAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, ACScriptName); +} + +#endif // AUCHENAI_CRYPTS_H_ diff --git a/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp new file mode 100644 index 00000000000..56279f20e4c --- /dev/null +++ b/src/server/scripts/Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "auchenai_crypts.h" + +class instance_auchenai_crypts : public InstanceMapScript +{ + public: + instance_auchenai_crypts() : InstanceMapScript(ACScriptName, 558) { } + + struct instance_auchenai_crypts_InstanceMapScript : public InstanceScript + { + instance_auchenai_crypts_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + } + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_auchenai_crypts_InstanceMapScript(map); + } +}; + +void AddSC_instance_auchenai_crypts() +{ + new instance_auchenai_crypts(); +} diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp b/src/server/scripts/Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp new file mode 100644 index 00000000000..77a5841cb39 --- /dev/null +++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "mana_tombs.h" + +class instance_mana_tombs : public InstanceMapScript +{ + public: + instance_mana_tombs() : InstanceMapScript(MTScriptName, 557) { } + + struct instance_mana_tombs_InstanceMapScript : public InstanceScript + { + instance_mana_tombs_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + } + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_mana_tombs_InstanceMapScript(map); + } +}; + +void AddSC_instance_mana_tombs() +{ + new instance_mana_tombs(); +} diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/mana_tombs.h b/src/server/scripts/Outland/Auchindoun/ManaTombs/mana_tombs.h new file mode 100644 index 00000000000..9199ef1945b --- /dev/null +++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/mana_tombs.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef MANA_TOMBS_H_ +#define MANA_TOMBS_H_ + +#define MTScriptName "instance_mana_tombs" + +uint32 const EncounterCount = 4; + +enum DataTypes +{ + // Encounter States/Boss GUIDs + DATA_PANDEMONIUS = 0, + DATA_TAVAROK = 1, + DATA_NEXUSPRINCE_SHAFFAR = 2, + DATA_YOR = 3 +}; + +enum CreatureIds +{ +}; + +enum GameObjectIds +{ +}; + +template<class AI> +AI* GetManaTombsAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, MTScriptName); +} + +#endif // MANA_TOMBS_H_ diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp index ade6c13aafe..af8a4390d96 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_anzu.cpp @@ -71,20 +71,22 @@ class boss_anzu : public CreatureScript void Reset() OVERRIDE { + //_Reset(); + events.Reset(); _under33Percent = false; _under66Percent = false; } void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); events.ScheduleEvent(EVENT_PARALYZING_SCREECH, 14000); events.ScheduleEvent(EVENT_CYCLONE_OF_FEATHERS, 5000); } void JustDied(Unit* /*killer*/) OVERRIDE { - if (instance) - instance->SetData(DATA_ANZU, DONE); + _JustDied(); } void DamageTaken(Unit* /*killer*/, uint32 &damage) OVERRIDE @@ -153,12 +155,11 @@ class boss_anzu : public CreatureScript private: bool _under33Percent; bool _under66Percent; - }; CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new boss_anzuAI(creature); + return GetSethekkHallsAI<boss_anzuAI>(creature); } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp index 782db325496..be3a109b9f0 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp @@ -75,6 +75,7 @@ public: void Reset() OVERRIDE { + _Reset(); summon90 = false; summon50 = false; summon10 = false; @@ -82,6 +83,7 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); events.ScheduleEvent(EVENT_FLAME_SHOCK, 2000); events.ScheduleEvent(EVENT_ARCANE_SHOCK, 4000); events.ScheduleEvent(EVENT_FROST_SHOCK, 6000); @@ -93,18 +95,14 @@ public: void JustDied(Unit* /*killer*/) OVERRIDE { + _JustDied(); Talk(SAY_DEATH); - - if (instance) - instance->SetData(DATA_DARKWEAVER_SYTH, DONE); } - void KilledUnit(Unit* /*victim*/) OVERRIDE + void KilledUnit(Unit* who) OVERRIDE { - if (rand()%2) - return; - - Talk(SAY_SLAY); + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } void JustSummoned(Creature* summoned) OVERRIDE @@ -196,7 +194,7 @@ public: CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new boss_darkweaver_sythAI(creature); + return GetSethekkHallsAI<boss_darkweaver_sythAI>(creature); } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp index 9d3aa623011..022ac3e9e4d 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp @@ -62,6 +62,7 @@ public: void Reset() OVERRIDE { + _Reset(); ArcaneVolley_Timer = 5000; Sheep_Timer = 8000; Blink_Timer = 35000; @@ -72,7 +73,6 @@ public: } void MoveInLineOfSight(Unit* who) OVERRIDE - { if (!me->GetVictim() && me->CanCreatureAttack(who)) { @@ -96,20 +96,20 @@ public: void EnterCombat(Unit* /*who*/) OVERRIDE { + _EnterCombat(); Talk(SAY_AGGRO); } void JustDied(Unit* /*killer*/) OVERRIDE { + _JustDied(); Talk(SAY_DEATH); - - if (instance) - instance->SetData(DATA_TALON_KING_IKISS, DONE); } - void KilledUnit(Unit* /*victim*/) OVERRIDE + void KilledUnit(Unit* who) OVERRIDE { - Talk(SAY_SLAY); + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } void UpdateAI(uint32 diff) OVERRIDE @@ -202,7 +202,7 @@ public: CreatureAI* GetAI(Creature* creature) const OVERRIDE { - return new boss_talon_king_ikissAI(creature); + return GetSethekkHallsAI<boss_talon_king_ikissAI>(creature); } }; diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp index f380914506e..08cefb83c96 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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,125 +15,100 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Instance - Sethekk Halls -SD%Complete: 50 -SDComment: Instance Data for Sethekk Halls instance -SDCategory: Auchindoun, Sethekk Halls -EndScriptData */ - #include "ScriptMgr.h" #include "InstanceScript.h" #include "sethekk_halls.h" -class instance_sethekk_halls : public InstanceMapScript +DoorData const doorData[] = { -public: - instance_sethekk_halls() : InstanceMapScript("instance_sethekk_halls", 556) { } - - InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE - { - return new instance_sethekk_halls_InstanceMapScript(map); - } - - struct instance_sethekk_halls_InstanceMapScript : public InstanceScript - { - instance_sethekk_halls_InstanceMapScript(Map* map) : InstanceScript(map) - { - SetBossNumber(EncounterCount); - } + { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; - void Initialize() OVERRIDE - { - SetBossState(DATA_ANZU, NOT_STARTED); - iIkissDoorGUID = 0; - } +class instance_sethekk_halls : public InstanceMapScript +{ + public: + instance_sethekk_halls() : InstanceMapScript(SHScriptName, 556) { } - void OnCreatureCreate(Creature* creature) OVERRIDE + struct instance_sethekk_halls_InstanceMapScript : public InstanceScript { - if (creature->GetEntry() == NPC_ANZU) + instance_sethekk_halls_InstanceMapScript(Map* map) : InstanceScript(map) { - if (GetBossState(DATA_ANZU) == DONE) - creature->DisappearAndDie(); - else - SetBossState(DATA_ANZU, IN_PROGRESS); + SetBossNumber(EncounterCount); + LoadDoorData(doorData); } - } - void OnGameObjectCreate(GameObject* go) OVERRIDE - { - if (go->GetEntry() == GO_IKISS_DOOR) - iIkissDoorGUID = go->GetGUID(); - } - - bool SetBossState(uint32 type, EncounterState state) OVERRIDE - { - if (!InstanceScript::SetBossState(type, state)) - return false; + void OnCreatureCreate(Creature* creature) OVERRIDE + { + if (creature->GetEntry() == NPC_ANZU) + { + if (GetBossState(DATA_ANZU) == DONE) + creature->DisappearAndDie(); + else + SetBossState(DATA_ANZU, IN_PROGRESS); + } + } - switch (type) + void OnGameObjectCreate(GameObject* go) OVERRIDE { - case DATA_DARKWEAVER_SYTH: - break; - case DATA_TALON_KING_IKISS: - if (state == DONE) - DoUseDoorOrButton(iIkissDoorGUID, DAY*IN_MILLISECONDS); - break; - case DATA_ANZU: - break; - default: - break; + if (go->GetEntry() == GO_IKISS_DOOR) + AddDoor(go, true); } - return true; - } + void OnGameObjectRemove(GameObject* go) OVERRIDE + { + if (go->GetEntry() == GO_IKISS_DOOR) + AddDoor(go, false); + } - std::string GetSaveData() OVERRIDE - { - OUT_SAVE_INST_DATA; + std::string GetSaveData() OVERRIDE + { + OUT_SAVE_INST_DATA; - std::ostringstream saveStream; - saveStream << "S H " << GetBossSaveData(); + std::ostringstream saveStream; + saveStream << "S H " << GetBossSaveData(); - OUT_SAVE_INST_DATA_COMPLETE; - return saveStream.str(); - } + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } - void Load(const char* str) OVERRIDE - { - if (!str) + void Load(char const* str) OVERRIDE { - OUT_LOAD_INST_DATA_FAIL; - return; - } + if (!str) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - OUT_LOAD_INST_DATA(str); + OUT_LOAD_INST_DATA(str); - char dataHead1, dataHead2; + char dataHead1, dataHead2; - std::istringstream loadStream(str); - loadStream >> dataHead1 >> dataHead2; + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; - if (dataHead1 == 'S' && dataHead2 == 'H') - { - for (uint32 i = 0; i < EncounterCount; ++i) + if (dataHead1 == 'S' && dataHead2 == 'H') { - uint32 tmpState; - loadStream >> tmpState; - if (tmpState == IN_PROGRESS || tmpState > SPECIAL) - tmpState = NOT_STARTED; - SetBossState(i, EncounterState(tmpState)); + 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; + + OUT_LOAD_INST_DATA_COMPLETE; } - else - OUT_LOAD_INST_DATA_FAIL; + }; - OUT_LOAD_INST_DATA_COMPLETE; + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_sethekk_halls_InstanceMapScript(map); } - - protected: - uint64 iIkissDoorGUID; - }; }; void AddSC_instance_sethekk_halls() diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h index 86789e9982f..58b8d4d157c 100644 --- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h +++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h @@ -15,13 +15,16 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DEF_SETHEKK_HALLS_H -#define DEF_SETHEKK_HALLS_H +#ifndef SETHEKK_HALLS_H_ +#define SETHEKK_HALLS_H_ + +#define SHScriptName "instance_sethekk_halls" uint32 const EncounterCount = 3; enum DataTypes { + // Encounter States/Boss GUIDs DATA_DARKWEAVER_SYTH = 0, DATA_TALON_KING_IKISS = 1, DATA_ANZU = 2 @@ -38,4 +41,10 @@ enum GameObjectIds GO_IKISS_DOOR = 177203 }; -#endif +template<class AI> +AI* GetSethekkHallsAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, SHScriptName); +} + +#endif // SETHEKK_HALLS_H_ diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp index ffadfccecfe..1fa589af3a1 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp @@ -45,165 +45,146 @@ enum Spells SPELL_ENRAGE = 34970 }; -class boss_ambassador_hellmaw : public CreatureScript +enum Events { -public: - boss_ambassador_hellmaw() : CreatureScript("boss_ambassador_hellmaw") { } - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_ambassador_hellmawAI(creature); - } - - struct boss_ambassador_hellmawAI : public npc_escortAI - { - boss_ambassador_hellmawAI(Creature* creature) : npc_escortAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; + EVENT_CORROSIVE_ACID = 1, + EVENT_FEAR, + EVENT_BERSERK +}; - uint32 EventCheck_Timer; - uint32 CorrosiveAcid_Timer; - uint32 Fear_Timer; - uint32 Enrage_Timer; - bool Intro; - bool IsBanished; - bool Enraged; +class boss_ambassador_hellmaw : public CreatureScript +{ + public: + boss_ambassador_hellmaw() : CreatureScript("boss_ambassador_hellmaw") { } - void Reset() OVERRIDE + struct boss_ambassador_hellmawAI : public npc_escortAI { - EventCheck_Timer = 5000; - CorrosiveAcid_Timer = urand(5000, 10000); - Fear_Timer = urand(25000, 30000); - Enrage_Timer = 180000; - Intro = false; - IsBanished = true; - Enraged = false; - - if (instance && me->IsAlive()) + boss_ambassador_hellmawAI(Creature* creature) : npc_escortAI(creature) { - if (instance->GetData(TYPE_OVERSEER) != DONE) - DoCast(me, SPELL_BANISH, true); + _instance = creature->GetInstanceScript(); + _intro = false; } - } - void JustReachedHome() OVERRIDE - { - if (instance) - instance->SetData(TYPE_HELLMAW, FAIL); - } + void Reset() OVERRIDE + { + if (!me->IsAlive()) + return; - void MoveInLineOfSight(Unit* who) OVERRIDE + _events.Reset(); + _instance->SetBossState(DATA_AMBASSADOR_HELLMAW, NOT_STARTED); - { - if (me->HasAura(SPELL_BANISH)) - return; + _events.ScheduleEvent(EVENT_CORROSIVE_ACID, urand(5000, 10000)); + _events.ScheduleEvent(EVENT_FEAR, urand(25000, 30000)); + if (IsHeroic()) + _events.ScheduleEvent(EVENT_BERSERK, 180000); - npc_escortAI::MoveInLineOfSight(who); - } + DoAction(ACTION_AMBASSADOR_HELLMAW_BANISH); + } - void WaypointReached(uint32 /*waypointId*/) OVERRIDE - { - } + void MoveInLineOfSight(Unit* who) OVERRIDE + { + if (me->HasAura(SPELL_BANISH)) + return; - void DoIntro() - { - if (me->HasAura(SPELL_BANISH)) - me->RemoveAurasDueToSpell(SPELL_BANISH); + npc_escortAI::MoveInLineOfSight(who); + } - IsBanished = false; - Intro = true; + void WaypointReached(uint32 /*waypointId*/) OVERRIDE + { + } - if (instance) + void DoAction(int32 actionId) { - if (instance->GetData(TYPE_HELLMAW) != FAIL) + if (actionId == ACTION_AMBASSADOR_HELLMAW_INTRO) + DoIntro(); + else if (actionId == ACTION_AMBASSADOR_HELLMAW_BANISH) { - Talk(SAY_INTRO); - Start(true, false, 0, NULL, false, true); + if (_instance->GetData(DATA_FEL_OVERSEER) && me->HasAura(SPELL_BANISH)) + DoCast(me, SPELL_BANISH, true); // this will not work, because he is immune to banish } - - instance->SetData(TYPE_HELLMAW, IN_PROGRESS); } - } - void EnterCombat(Unit* /*who*/) OVERRIDE - { - Talk(SAY_AGGRO); - } + void DoIntro() + { + if (_intro) + return; - void KilledUnit(Unit* /*victim*/) OVERRIDE - { - Talk(SAY_SLAY); - } + _intro = true; - void JustDied(Unit* /*killer*/) OVERRIDE - { - Talk(SAY_DEATH); + if (me->HasAura(SPELL_BANISH)) + me->RemoveAurasDueToSpell(SPELL_BANISH); - if (instance) - instance->SetData(TYPE_HELLMAW, DONE); - } + Talk(SAY_INTRO); + Start(true, false, 0, NULL, false, true); + } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!Intro && !HasEscortState(STATE_ESCORT_ESCORTING)) + void EnterCombat(Unit* /*who*/) OVERRIDE { - if (EventCheck_Timer <= diff) - { - if (instance) - { - if (instance->GetData(TYPE_OVERSEER) == DONE) - { - DoIntro(); - return; - } - } - EventCheck_Timer = 5000; - return; - } - else - { - EventCheck_Timer -= diff; - return; - } + _instance->SetBossState(DATA_AMBASSADOR_HELLMAW, IN_PROGRESS); + Talk(SAY_AGGRO); } - npc_escortAI::UpdateAI(diff); - - if (!UpdateVictim()) - return; - - if (me->HasAura(SPELL_BANISH, 0)) + void KilledUnit(Unit* who) OVERRIDE { - EnterEvadeMode(); - return; + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } - if (CorrosiveAcid_Timer <= diff) + void JustDied(Unit* /*killer*/) OVERRIDE { - DoCastVictim(SPELL_CORROSIVE_ACID); - CorrosiveAcid_Timer = urand(15000, 25000); - } else CorrosiveAcid_Timer -= diff; + _instance->SetBossState(DATA_AMBASSADOR_HELLMAW, DONE); + Talk(SAY_DEATH); + } - if (Fear_Timer <= diff) + void UpdateEscortAI(uint32 const diff) OVERRIDE { - DoCast(me, SPELL_FEAR); - Fear_Timer = urand(20000, 35000); - } else Fear_Timer -= diff; + if (!UpdateVictim()) + return; - if (IsHeroic()) - { - if (!Enraged && Enrage_Timer <= diff) + if (me->HasAura(SPELL_BANISH)) + { + EnterEvadeMode(); + return; + } + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) { - DoCast(me, SPELL_ENRAGE); - Enraged = true; - } else Enrage_Timer -= diff; + switch (eventId) + { + case EVENT_CORROSIVE_ACID: + DoCastVictim(SPELL_CORROSIVE_ACID); + _events.ScheduleEvent(EVENT_CORROSIVE_ACID, urand(15000, 25000)); + break; + case EVENT_FEAR: + DoCastAOE(SPELL_FEAR); + _events.ScheduleEvent(EVENT_FEAR, urand(20000, 35000)); + break; + case EVENT_BERSERK: + DoCast(me, SPELL_ENRAGE, true); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); } - } - }; + private: + InstanceScript* _instance; + EventMap _events; + bool _intro; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetShadowLabyrinthAI<boss_ambassador_hellmawAI>(creature); + } }; void AddSC_boss_ambassador_hellmaw() diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp index 573acfce5c2..ec3465a0bfc 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp @@ -50,112 +50,97 @@ enum BlackheartTheInciter enum Events { - EVENT_INCITE_CHAOS_WAIT = 1, - EVENT_INCITE_CHAOS = 2, - EVENT_CHARGE_ATTACK = 3, - EVENT_WAR_STOMP = 4 + EVENT_INCITE_CHAOS = 1, + EVENT_CHARGE_ATTACK = 2, + EVENT_WAR_STOMP = 3 }; class boss_blackheart_the_inciter : public CreatureScript { -public: - boss_blackheart_the_inciter() : CreatureScript("boss_blackheart_the_inciter") { } + public: + boss_blackheart_the_inciter() : CreatureScript("boss_blackheart_the_inciter") { } - struct boss_blackheart_the_inciterAI : public BossAI - { - boss_blackheart_the_inciterAI(Creature* creature) : BossAI(creature, DATA_BLACKHEARTTHEINCITEREVENT) { } - - void Reset() OVERRIDE + struct boss_blackheart_the_inciterAI : public BossAI { - InciteChaos = false; - - if (instance) - instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, NOT_STARTED); - } + boss_blackheart_the_inciterAI(Creature* creature) : BossAI(creature, DATA_BLACKHEART_THE_INCITER) { } - void KilledUnit(Unit* /*victim*/) OVERRIDE - { - Talk(SAY_SLAY); - } - - void JustDied(Unit* /*killer*/) OVERRIDE - { - Talk(SAY_DEATH); + void Reset() OVERRIDE + { + _Reset(); + } - if (instance) - instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, DONE); - } + void EnterCombat(Unit* /*who*/) OVERRIDE + { + _EnterCombat(); + events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000); + events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000); + events.ScheduleEvent(EVENT_WAR_STOMP, 15000); - void EnterCombat(Unit* /*who*/) OVERRIDE - { - events.ScheduleEvent(EVENT_INCITE_CHAOS_WAIT, 15000); - events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000); - events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000); - events.ScheduleEvent(EVENT_WAR_STOMP, 15000); + Talk(SAY_AGGRO); + } - Talk(SAY_AGGRO); + void KilledUnit(Unit* who) OVERRIDE + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - if (instance) - instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, IN_PROGRESS); - } + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + Talk(SAY_DEATH); + } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + while (uint32 eventId = events.ExecuteEvent()) { - case EVENT_INCITE_CHAOS_WAIT: - InciteChaos = false; - events.ScheduleEvent(EVENT_INCITE_CHAOS_WAIT, 15000); - break; - case EVENT_INCITE_CHAOS: + switch (eventId) { - DoCast(me, SPELL_INCITE_CHAOS); - - std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); - for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + case EVENT_INCITE_CHAOS: { - Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); - if (target && target->GetTypeId() == TYPEID_PLAYER) - me->CastSpell(target, SPELL_INCITE_CHAOS_B, true); + DoCast(me, SPELL_INCITE_CHAOS); + + std::list<HostileReference*> t_list = me->getThreatManager().getThreatList(); + for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + { + if (Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) + if (target->GetTypeId() == TYPEID_PLAYER) + me->CastSpell(target, SPELL_INCITE_CHAOS_B, true); + } + + DoResetThreat(); + events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000); + break; } - - DoResetThreat(); - InciteChaos = true; - events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000); - break; + case EVENT_CHARGE_ATTACK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_CHARGE); + events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000)); + break; + case EVENT_WAR_STOMP: + DoCast(me, SPELL_WAR_STOMP); + events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000)); + break; } - case EVENT_CHARGE_ATTACK: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_CHARGE); - events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000)); - break; - case EVENT_WAR_STOMP: - DoCast(me, SPELL_WAR_STOMP); - events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000)); - break; } - } - DoMeleeAttackIfReady(); - } - private: - bool InciteChaos; - }; + DoMeleeAttackIfReady(); + } + }; - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_blackheart_the_inciterAI(creature); - } + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetShadowLabyrinthAI<boss_blackheart_the_inciterAI>(creature); + } }; void AddSC_boss_blackheart_the_inciter() diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp index 088913b13d2..44ef5e8e42c 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp @@ -43,16 +43,23 @@ enum GrandmasterVorpil SPELL_BANISH = 38791, NPC_VOID_TRAVELER = 19226, + SPELL_SUMMON_VOID_TRAVELER_A = 33582, + SPELL_SUMMON_VOID_TRAVELER_B = 33583, + SPELL_SUMMON_VOID_TRAVELER_C = 33584, + SPELL_SUMMON_VOID_TRAVELER_D = 33585, + SPELL_SUMMON_VOID_TRAVELER_E = 33586, + SPELL_SACRIFICE = 33587, SPELL_SHADOW_NOVA = 33846, SPELL_EMPOWERING_SHADOWS = 33783, H_SPELL_EMPOWERING_SHADOWS = 39364, NPC_VOID_PORTAL = 19224, + SPELL_SUMMON_PORTAL = 33566, SPELL_VOID_PORTAL_VISUAL = 33569 }; -float VorpilPosition[3] = {-252.8820f, -264.3030f, 17.1f}; +Position const VorpilPosition = { -252.8820f, -264.3030f, 17.1f, 0.0f }; float VoidPortalCoords[5][3] = { @@ -71,254 +78,202 @@ enum Events EVENT_SUMMON_TRAVELER = 4 }; -class npc_voidtraveler : public CreatureScript +class boss_grandmaster_vorpil : public CreatureScript { -public: - npc_voidtraveler() : CreatureScript("npc_voidtraveler") { } + public: + boss_grandmaster_vorpil() : CreatureScript("boss_grandmaster_vorpil") { } - struct npc_voidtravelerAI : public ScriptedAI - { - npc_voidtravelerAI(Creature* creature) : ScriptedAI(creature) {} - - uint64 VorpilGUID; - uint32 move; - bool sacrificed; - - void Reset() OVERRIDE + struct boss_grandmaster_vorpilAI : public BossAI { - VorpilGUID = 0; - move = 0; - sacrificed = false; - } - - void EnterCombat(Unit* /*who*/)OVERRIDE {} + boss_grandmaster_vorpilAI(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL) + { + _intro = false; + } - void UpdateAI(uint32 diff) OVERRIDE - { - if (!VorpilGUID) + void Reset() OVERRIDE { - me->Kill(me); - return; + _Reset(); + _helpYell = false; } - if (move <= diff) + + void SummonPortals() { - Creature* Vorpil = Unit::GetCreature(*me, VorpilGUID); - if (!Vorpil) - { - VorpilGUID = 0; - return; - } + for (uint8 i = 0; i < 5; ++i) + if (Creature* portal = me->SummonCreature(NPC_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 3000000)) + portal->CastSpell(portal, SPELL_VOID_PORTAL_VISUAL, true); - if (sacrificed) - { - me->AddAura(DUNGEON_MODE(SPELL_EMPOWERING_SHADOWS, H_SPELL_EMPOWERING_SHADOWS), Vorpil); - Vorpil->ModifyHealth(int32(Vorpil->CountPctFromMaxHealth(4))); - DoCast(me, SPELL_SHADOW_NOVA, true); - me->Kill(me); - return; - } - me->GetMotionMaster()->MoveFollow(Vorpil, 0, 0); - if (me->IsWithinDist(Vorpil, 3)) - { - DoCast(me, SPELL_SACRIFICE, false); - sacrificed = true; - move = 500; - return; - } - if (!Vorpil->IsInCombat() || Vorpil->isDead()) + events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); + } + + void spawnVoidTraveler() + { + uint8 pos = urand(0, 4); + me->SummonCreature(NPC_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); + if (!_helpYell) { - me->Kill(me); - return; + Talk(SAY_HELP); + _helpYell = true; } - move = 1000; - } else move -= diff; - } - }; - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new npc_voidtravelerAI(creature); - } -}; - -class boss_grandmaster_vorpil : public CreatureScript -{ -public: - boss_grandmaster_vorpil() : CreatureScript("boss_grandmaster_vorpil") { } - - struct boss_grandmaster_vorpilAI : public BossAI - { - boss_grandmaster_vorpilAI(Creature* creature) : BossAI(creature, DATA_GRANDMASTERVORPIL) - { - Intro = false; - } + } - void Reset() OVERRIDE - { - HelpYell = false; - sumportals = false; - destroyPortals(); + void KilledUnit(Unit* who) OVERRIDE + { + if (who->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } - if (instance) - instance->SetData(DATA_GRANDMASTERVORPILEVENT, NOT_STARTED); - } + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + Talk(SAY_DEATH); + } - void summonPortals() - { - if (!sumportals) + void EnterCombat(Unit* /*who*/) OVERRIDE { - for (uint8 i = 0; i < 5; ++i) - { - Creature* Portal = NULL; - Portal = me->SummonCreature(NPC_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 3000000); - if (Portal) - { - PortalsGuid[i] = Portal->GetGUID(); - Portal->CastSpell(Portal, SPELL_VOID_PORTAL_VISUAL, false); - } - } - sumportals = true; - events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); + _EnterCombat(); + events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(7000, 14000)); + if (IsHeroic()) + events.ScheduleEvent(EVENT_BANISH, 17000); + events.ScheduleEvent(EVENT_DRAW_SHADOWS, 45000); + events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 90000); + + Talk(SAY_AGGRO); + SummonPortals(); } - } - void destroyPortals() - { - if (sumportals) + void MoveInLineOfSight(Unit* who) OVERRIDE { - for (uint8 i = 0; i < 5; ++i) + BossAI::MoveInLineOfSight(who); + + if (!_intro && me->IsWithinLOSInMap(who) && me->IsWithinDistInMap(who, 100) && me->IsValidAttackTarget(who)) { - Unit* Portal = Unit::GetUnit(*me, PortalsGuid[i]); - if (Portal && Portal->IsAlive()) - Portal->DealDamage(Portal, Portal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - PortalsGuid[i] = 0; + Talk(SAY_INTRO); + _intro = true; } - sumportals = false; } - } - void spawnVoidTraveler() - { - int pos = urand(0, 4); - me->SummonCreature(NPC_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); - if (!HelpYell) + void UpdateAI(uint32 diff) OVERRIDE { - Talk(SAY_HELP); - HelpYell = true; - } - } + if (!UpdateVictim()) + return; - void JustSummoned(Creature* summoned) OVERRIDE - { - if (summoned && summoned->GetEntry() == NPC_VOID_TRAVELER) - CAST_AI(npc_voidtraveler::npc_voidtravelerAI, summoned->AI())->VorpilGUID = me->GetGUID(); - } + events.Update(diff); - void KilledUnit(Unit* /*victim*/) OVERRIDE - { - Talk(SAY_SLAY); - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void JustDied(Unit* /*killer*/) OVERRIDE - { - Talk(SAY_DEATH); - destroyPortals(); + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SHADOWBOLT_VOLLEY: + DoCast(me, SPELL_SHADOWBOLT_VOLLEY); + events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(15000, 30000)); + break; + case EVENT_BANISH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f, false)) + DoCast(target, SPELL_BANISH); + events.ScheduleEvent(EVENT_BANISH, 16000); + break; + case EVENT_DRAW_SHADOWS: + { + Map* map = me->GetMap(); + Map::PlayerList const &PlayerList = map->GetPlayers(); + for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) + if (Player* i_pl = i->GetSource()) + if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH)) + i_pl->TeleportTo(me->GetMapId(), VorpilPosition.GetPositionX(), VorpilPosition.GetPositionY(), VorpilPosition.GetPositionZ(), VorpilPosition.GetOrientation(), TELE_TO_NOT_LEAVE_COMBAT); + + me->SetPosition(VorpilPosition); + DoCast(me, SPELL_DRAW_SHADOWS, true); + DoCast(me, SPELL_RAIN_OF_FIRE); + events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6000); + events.ScheduleEvent(EVENT_DRAW_SHADOWS, 30000); + break; + } + case EVENT_SUMMON_TRAVELER: + spawnVoidTraveler(); + events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10000); + // enrage at 20% + if (HealthBelowPct(20)) + events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); + break; + } + } - if (instance) - instance->SetData(DATA_GRANDMASTERVORPILEVENT, DONE); - } + DoMeleeAttackIfReady(); + } + + private: + bool _intro; + bool _helpYell; + }; - void EnterCombat(Unit* /*who*/) OVERRIDE + CreatureAI* GetAI(Creature* creature) const OVERRIDE { - events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(7000, 14000)); - if (IsHeroic()) - events.ScheduleEvent(EVENT_BANISH, 17000); - events.ScheduleEvent(EVENT_DRAW_SHADOWS, 45000); - events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 90000); - - Talk(SAY_AGGRO); - summonPortals(); - - if (instance) - instance->SetData(DATA_GRANDMASTERVORPILEVENT, IN_PROGRESS); - _EnterCombat(); + return GetShadowLabyrinthAI<boss_grandmaster_vorpilAI>(creature); } +}; - void MoveInLineOfSight(Unit* who) OVERRIDE +class npc_voidtraveler : public CreatureScript +{ + public: + npc_voidtraveler() : CreatureScript("npc_voidtraveler") { } + struct npc_voidtravelerAI : public ScriptedAI { - ScriptedAI::MoveInLineOfSight(who); - - if (!Intro && me->IsWithinLOSInMap(who)&& me->IsWithinDistInMap(who, 100) && me->IsValidAttackTarget(who)) + npc_voidtravelerAI(Creature* creature) : ScriptedAI(creature) { - Talk(SAY_INTRO); - Intro = true; + _instance = creature->GetInstanceScript(); } - } - - void UpdateAI(uint32 diff) OVERRIDE - { - if (!UpdateVictim()) - return; - events.Update(diff); + void Reset() OVERRIDE + { + _moveTimer = 0; + _sacrificed = false; + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + void EnterCombat(Unit* /*who*/) OVERRIDE { } - while (uint32 eventId = events.ExecuteEvent()) + void UpdateAI(uint32 diff) OVERRIDE { - switch (eventId) + if (_moveTimer <= diff) { - case EVENT_SHADOWBOLT_VOLLEY: - DoCast(me, SPELL_SHADOWBOLT_VOLLEY); - events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(15000, 30000)); - break; - case EVENT_BANISH: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30, false)) - DoCast(target, SPELL_BANISH); - events.ScheduleEvent(EVENT_BANISH, 16000); - break; - case EVENT_DRAW_SHADOWS: - { - Map* map = me->GetMap(); - Map::PlayerList const &PlayerList = map->GetPlayers(); - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player* i_pl = i->GetSource()) - if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH)) - i_pl->TeleportTo(me->GetMapId(), VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT); - - me->SetPosition(VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0.0f); - DoCast(me, SPELL_DRAW_SHADOWS, true); - DoCast(me, SPELL_RAIN_OF_FIRE); - events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6000); - events.ScheduleEvent(EVENT_DRAW_SHADOWS, 30000); - break; - } - case EVENT_SUMMON_TRAVELER: - spawnVoidTraveler(); - events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10000); - //enrage at 20% - if (HealthBelowPct(20)) - events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000); - break; + Creature* Vorpil = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_GRANDMASTER_VORPIL)); + if (!Vorpil) + return; + + if (_sacrificed) + { + DoCastAOE(DUNGEON_MODE(SPELL_EMPOWERING_SHADOWS, H_SPELL_EMPOWERING_SHADOWS), true); + DoCast(me, SPELL_SHADOW_NOVA, true); + me->Kill(me); + return; + } + me->GetMotionMaster()->MoveFollow(Vorpil, 0, 0); + if (me->IsWithinDist(Vorpil, 3)) + { + DoCast(me, SPELL_SACRIFICE, false); + _sacrificed = true; + _moveTimer = 500; + return; + } + _moveTimer = 1000; } + else + _moveTimer -= diff; } - DoMeleeAttackIfReady(); - } private: - bool Intro, HelpYell; - bool sumportals; - uint64 PortalsGuid[5]; - + InstanceScript* _instance; + uint32 _moveTimer; + bool _sacrificed; + }; - }; - - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_grandmaster_vorpilAI(creature); - } + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetShadowLabyrinthAI<npc_voidtravelerAI>(creature); + } }; void AddSC_boss_grandmaster_vorpil() diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp index 99078b3b15d..5e2e26b578a 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp @@ -25,8 +25,8 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "SpellScript.h" #include "shadow_labyrinth.h" -#include "SpellInfo.h" enum Murmur { @@ -54,149 +54,234 @@ enum Events class boss_murmur : public CreatureScript { -public: - boss_murmur() : CreatureScript("boss_murmur") { } + public: + boss_murmur() : CreatureScript("boss_murmur") { } - struct boss_murmurAI : public BossAI - { - boss_murmurAI(Creature* creature) : BossAI(creature, DATA_MURMUREVENT) + struct boss_murmurAI : public BossAI { - SetCombatMovement(false); - } - - void Reset() OVERRIDE - { - events.ScheduleEvent(EVENT_SONIC_BOOM, 30000); - events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(8000, 20000)); - events.ScheduleEvent(EVENT_RESONANCE, 5000); - events.ScheduleEvent(EVENT_MAGNETIC_PULL, urand(15000, 30000)); - if (IsHeroic()) + boss_murmurAI(Creature* creature) : BossAI(creature, DATA_MURMUR) { - events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000); - events.ScheduleEvent(EVENT_SONIC_SHOCK, 10000); + SetCombatMovement(false); } - //database should have `RegenHealth`=0 to prevent regen - uint32 hp = me->CountPctFromMaxHealth(40); - if (hp) me->SetHealth(hp); - me->ResetPlayerDamageReq(); - } + void Reset() OVERRIDE + { + _Reset(); + events.ScheduleEvent(EVENT_SONIC_BOOM, 30000); + events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(8000, 20000)); + events.ScheduleEvent(EVENT_RESONANCE, 5000); + events.ScheduleEvent(EVENT_MAGNETIC_PULL, urand(15000, 30000)); + if (IsHeroic()) + { + events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000); + events.ScheduleEvent(EVENT_SONIC_SHOCK, 10000); + } - void SonicBoomEffect() - { - ThreatContainer::StorageType const &t_list = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + // database should have `RegenHealth`=0 to prevent regen + uint32 hp = me->CountPctFromMaxHealth(40); + if (hp) + me->SetHealth(hp); + me->ResetPlayerDamageReq(); + } + + void EnterCombat(Unit* /*who*/) OVERRIDE { - Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid()); - if (target && target->GetTypeId() == TYPEID_PLAYER) - { - //Not do anything without aura, spell can be resisted! - if (target->HasAura(SPELL_SONIC_BOOM_CAST) && me->IsWithinDistInMap(target, 34.0f)) - { - //This will be wrong calculation. Also, comments suggest it must deal damage - target->SetHealth(target->CountPctFromMaxHealth(20)); - } - } + _EnterCombat(); } - } - void EnterCombat(Unit* /*who*/) OVERRIDE {} + void JustDied(Unit* /*killer*/) OVERRIDE + { + _JustDied(); + } - // Sonic Boom instant damage (needs core fix instead of this) - void SpellHitTarget(Unit* target, const SpellInfo* spell) OVERRIDE - { - if (target && target->IsAlive() && spell && spell->Id == uint32(SPELL_SONIC_BOOM_EFFECT)) - me->DealDamage(target, (target->GetHealth()*90)/100, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NATURE, spell); - } + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) OVERRIDE - { - //Return since we have no target or casting - if (!UpdateVictim() || me->IsNonMeleeSpellCasted(false)) - return; + events.Update(diff); - events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) + while (uint32 eventId = events.ExecuteEvent()) { - case EVENT_SONIC_BOOM: - Talk(EMOTE_SONIC_BOOM); - DoCast(me, SPELL_SONIC_BOOM_CAST); - DoCast(me, SPELL_SONIC_BOOM_EFFECT, true); - SonicBoomEffect(); - events.ScheduleEvent(EVENT_SONIC_BOOM, 30000); - events.ScheduleEvent(EVENT_RESONANCE, 1500); - break; - case EVENT_MURMURS_TOUCH: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80, true)) - DoCast(target, SPELL_MURMURS_TOUCH); - events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(25000, 35000)); - break; - case EVENT_RESONANCE: - if (!(me->IsWithinMeleeRange(me->GetVictim()))) - { - DoCast(me, SPELL_RESONANCE); - events.ScheduleEvent(EVENT_RESONANCE, 5000); - } - break; - case EVENT_MAGNETIC_PULL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive()) + switch (eventId) + { + case EVENT_SONIC_BOOM: + Talk(EMOTE_SONIC_BOOM); + DoCast(me, SPELL_SONIC_BOOM_CAST); + events.ScheduleEvent(EVENT_SONIC_BOOM, 30000); + events.ScheduleEvent(EVENT_RESONANCE, 1500); + break; + case EVENT_MURMURS_TOUCH: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80.0f, true)) + DoCast(target, SPELL_MURMURS_TOUCH); + events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(25000, 35000)); + break; + case EVENT_RESONANCE: + if (!(me->IsWithinMeleeRange(me->GetVictim()))) + { + DoCast(me, SPELL_RESONANCE); + events.ScheduleEvent(EVENT_RESONANCE, 5000); + } + break; + case EVENT_MAGNETIC_PULL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) { DoCast(target, SPELL_MAGNETIC_PULL); - events.ScheduleEvent(EVENT_MAGNETIC_PULL, 15000+rand()%15000); + events.ScheduleEvent(EVENT_MAGNETIC_PULL, urand(15000, 30000)); break; } - events.ScheduleEvent(EVENT_MAGNETIC_PULL, 500); - break; - case EVENT_THUNDERING_STORM: - { - ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) - if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid())) - if (target->IsAlive() && !me->IsWithinDist(target, 35, false)) - DoCast(target, SPELL_THUNDERING_STORM, true); - events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000); - break; - } - case EVENT_SONIC_SHOCK: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20, false)) - if (target->IsAlive()) + events.ScheduleEvent(EVENT_MAGNETIC_PULL, 500); + break; + case EVENT_THUNDERING_STORM: + DoCastAOE(SPELL_THUNDERING_STORM, true); + events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000); + break; + case EVENT_SONIC_SHOCK: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, false)) DoCast(target, SPELL_SONIC_SHOCK); - events.ScheduleEvent(EVENT_SONIC_SHOCK, 10000+rand()%10000); - break; + events.ScheduleEvent(EVENT_SONIC_SHOCK, urand(10000, 20000)); + break; + } + } + + // Select nearest most aggro target if top aggro too far + if (!me->isAttackReady()) + return; + + if (!me->IsWithinMeleeRange(me->GetVictim())) + { + ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); + for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) + if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid())) + if (me->IsWithinMeleeRange(target)) + { + me->TauntApply(target); + break; + } } + + DoMeleeAttackIfReady(); } + }; - // Select nearest most aggro target if top aggro too far - if (!me->isAttackReady()) - return; + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetShadowLabyrinthAI<boss_murmurAI>(creature); + } +}; - if (!me->IsWithinMeleeRange(me->GetVictim())) +// 33923, 38796 - Sonic Boom +class spell_murmur_sonic_boom : public SpellScriptLoader +{ + public: + spell_murmur_sonic_boom() : SpellScriptLoader("spell_murmur_sonic_boom") { } + + class spell_murmur_sonic_boom_SpellScript : public SpellScript + { + PrepareSpellScript(spell_murmur_sonic_boom_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE { - ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i) - if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid())) - if (target->IsAlive() && me->IsWithinMeleeRange(target)) - { - me->TauntApply(target); - break; - } + if (!sSpellMgr->GetSpellInfo(SPELL_SONIC_BOOM_EFFECT)) + return false; + return true; + } + + void HandleEffect(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell((Unit*)NULL, SPELL_SONIC_BOOM_EFFECT, true); } - DoMeleeAttackIfReady(); + void Register() OVERRIDE + { + OnEffectHit += SpellEffectFn(spell_murmur_sonic_boom_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_murmur_sonic_boom_SpellScript(); } - }; +}; + +// 33666, 38795 - Sonic Boom Effect +class spell_murmur_sonic_boom_effect : public SpellScriptLoader +{ + public: + spell_murmur_sonic_boom_effect() : SpellScriptLoader("spell_murmur_sonic_boom_effect") { } + + class spell_murmur_sonic_boom_effect_SpellScript : public SpellScript + { + PrepareSpellScript(spell_murmur_sonic_boom_effect_SpellScript); + + void CalcDamage() + { + if (Unit* target = GetHitUnit()) + SetHitDamage(target->CountPctFromMaxHealth(80)); /// @todo: find correct value + } - CreatureAI* GetAI(Creature* creature) const OVERRIDE - { - return new boss_murmurAI(creature); - } + void Register() OVERRIDE + { + OnHit += SpellHitFn(spell_murmur_sonic_boom_effect_SpellScript::CalcDamage); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_murmur_sonic_boom_effect_SpellScript(); + } +}; + +class ThunderingStormCheck +{ + public: + ThunderingStormCheck(WorldObject* source) : _source(source) { } + + bool operator()(WorldObject* obj) + { + float distSq = _source->GetExactDist2dSq(obj); + return distSq < (25.0f * 25.0f) || distSq > (100.0f * 100.0f); + } + + private: + WorldObject const* _source; + float _dist; +}; + +// 39365 - Thundering Storm +class spell_murmur_thundering_storm : public SpellScriptLoader +{ + public: + spell_murmur_thundering_storm() : SpellScriptLoader("spell_murmur_thundering_storm") { } + + class spell_murmur_thundering_storm_SpellScript : public SpellScript + { + PrepareSpellScript(spell_murmur_thundering_storm_SpellScript); + + void FilterTarget(std::list<WorldObject*>& targets) + { + targets.remove_if(ThunderingStormCheck(GetCaster())); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_murmur_thundering_storm_SpellScript::FilterTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_murmur_thundering_storm_SpellScript(); + } }; void AddSC_boss_murmur() { new boss_murmur(); + new spell_murmur_sonic_boom(); + new spell_murmur_sonic_boom_effect(); + new spell_murmur_thundering_storm(); } diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp index 9a507979d8d..a401a74273f 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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,210 +15,178 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Instance_Shadow_Labyrinth -SD%Complete: 85 -SDComment: Some cleanup left along with save -SDCategory: Auchindoun, Shadow Labyrinth -EndScriptData */ - #include "ScriptMgr.h" #include "InstanceScript.h" +#include "ScriptedCreature.h" #include "shadow_labyrinth.h" -/* Shadow Labyrinth encounters: -1 - Ambassador Hellmaw event -2 - Blackheart the Inciter event -3 - Grandmaster Vorpil event -4 - Murmur event -*/ +DoorData const doorData[] = +{ + { GO_REFECTORY_DOOR, DATA_BLACKHEART_THE_INCITER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { GO_SCREAMING_HALL_DOOR, DATA_GRANDMASTER_VORPIL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END +}; class instance_shadow_labyrinth : public InstanceMapScript { -public: - instance_shadow_labyrinth() : InstanceMapScript("instance_shadow_labyrinth", 555) { } - - InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE - { - return new instance_shadow_labyrinth_InstanceMapScript(map); - } - - struct instance_shadow_labyrinth_InstanceMapScript : public InstanceScript - { - instance_shadow_labyrinth_InstanceMapScript(Map* map) : InstanceScript(map) {} - - uint32 m_auiEncounter[EncounterCount]; - std::string str_data; - - uint64 m_uiRefectoryDoorGUID; - uint64 m_uiScreamingHallDoorGUID; - - uint64 m_uiGrandmasterVorpil; - uint32 m_uiFelOverseerCount; + public: + instance_shadow_labyrinth() : InstanceMapScript(SLScriptName, 555) { } - void Initialize() OVERRIDE + struct instance_shadow_labyrinth_InstanceMapScript : public InstanceScript { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - m_uiRefectoryDoorGUID = 0; - m_uiScreamingHallDoorGUID = 0; - - m_uiGrandmasterVorpil = 0; - m_uiFelOverseerCount = 0; - } + instance_shadow_labyrinth_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(EncounterCount); + LoadDoorData(doorData); - bool IsEncounterInProgress() const OVERRIDE - { - for (uint8 i = 0; i < EncounterCount; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; + AmbassadorHellmawGUID = 0; + GrandmasterVorpilGUID = 0; + FelOverseerCount = 0; + } - return false; - } + void OnCreatureCreate(Creature* creature) OVERRIDE + { + switch (creature->GetEntry()) + { + case NPC_AMBASSADOR_HELLMAW: + AmbassadorHellmawGUID = creature->GetGUID(); + break; + case NPC_GRANDMASTER_VORPIL: + GrandmasterVorpilGUID = creature->GetGUID(); + break; + case NPC_FEL_OVERSEER: + if (creature->IsAlive()) + { + ++FelOverseerCount; + if (Creature* hellmaw = instance->GetCreature(AmbassadorHellmawGUID)) + hellmaw->AI()->DoAction(ACTION_AMBASSADOR_HELLMAW_BANISH); + } + break; + default: + break; + } + } - void OnGameObjectCreate(GameObject* go) OVERRIDE - { - switch (go->GetEntry()) + void OnGameObjectCreate(GameObject* go) OVERRIDE { - case REFECTORY_DOOR: - m_uiRefectoryDoorGUID = go->GetGUID(); - if (m_auiEncounter[2] == DONE) - go->SetGoState(GO_STATE_ACTIVE); - break; - case SCREAMING_HALL_DOOR: - m_uiScreamingHallDoorGUID = go->GetGUID(); - if (m_auiEncounter[3] == DONE) - go->SetGoState(GO_STATE_ACTIVE); - break; + switch (go->GetEntry()) + { + case GO_REFECTORY_DOOR: + case GO_SCREAMING_HALL_DOOR: + AddDoor(go, true); + break; + default: + break; + } } - } - void OnCreatureCreate(Creature* creature) OVERRIDE - { - switch (creature->GetEntry()) + void OnGameObjectRemove(GameObject* go) OVERRIDE { - case 18732: - m_uiGrandmasterVorpil = creature->GetGUID(); - break; - case 18796: - if (creature->IsAlive()) - { - ++m_uiFelOverseerCount; - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Shadow Labyrinth: counting %u Fel Overseers.", m_uiFelOverseerCount); - } - break; + switch (go->GetEntry()) + { + case GO_REFECTORY_DOOR: + case GO_SCREAMING_HALL_DOOR: + AddDoor(go, false); + break; + default: + break; + } } - } - void SetData(uint32 type, uint32 uiData) OVERRIDE - { - switch (type) + void OnUnitDeath(Unit* unit) { - case TYPE_HELLMAW: - m_auiEncounter[0] = uiData; - break; + Creature* creature = unit->ToCreature(); + if (!creature) + return; - case TYPE_OVERSEER: - if (uiData != DONE) - { - TC_LOG_ERROR(LOG_FILTER_TSCR, "Shadow Labyrinth: TYPE_OVERSEER did not expect other data than DONE"); - return; - } - if (m_uiFelOverseerCount) - { - --m_uiFelOverseerCount; + if (creature->GetEntry() == NPC_FEL_OVERSEER) + { + if (FelOverseerCount) + --FelOverseerCount; - if (m_uiFelOverseerCount) - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Shadow Labyrinth: %u Fel Overseers left to kill.", m_uiFelOverseerCount); - else - { - m_auiEncounter[1] = DONE; - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Shadow Labyrinth: TYPE_OVERSEER == DONE"); - } - } - break; - - case DATA_BLACKHEARTTHEINCITEREVENT: - if (uiData == DONE) - DoUseDoorOrButton(m_uiRefectoryDoorGUID); - m_auiEncounter[2] = uiData; - break; - - case DATA_GRANDMASTERVORPILEVENT: - if (uiData == DONE) - DoUseDoorOrButton(m_uiScreamingHallDoorGUID); - m_auiEncounter[3] = uiData; - break; - - case DATA_MURMUREVENT: - m_auiEncounter[4] = uiData; - break; + if (!FelOverseerCount) + if (Creature* hellmaw = instance->GetCreature(AmbassadorHellmawGUID)) + hellmaw->AI()->DoAction(ACTION_AMBASSADOR_HELLMAW_INTRO); + } } - if (uiData == DONE) + uint32 GetData(uint32 type) const OVERRIDE { - if (type == TYPE_OVERSEER && m_uiFelOverseerCount != 0) - return; + switch (type) + { + case DATA_FEL_OVERSEER: + return !FelOverseerCount ? 1 : 0; + default: + break; + } + return 0; + } + uint64 GetData64(uint32 type) const OVERRIDE + { + switch (type) + { + case DATA_GRANDMASTER_VORPIL: + return GrandmasterVorpilGUID; + default: + break; + } + return 0; + } + + std::string GetSaveData() OVERRIDE + { OUT_SAVE_INST_DATA; std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' - << m_auiEncounter[2] << ' ' << m_auiEncounter[3] << ' ' << m_auiEncounter[4]; + saveStream << "S L " << GetBossSaveData(); - str_data = saveStream.str(); - - SaveToDB(); OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); } - } - uint32 GetData(uint32 type) const OVERRIDE - { - switch (type) + void Load(char const* str) OVERRIDE { - case TYPE_HELLMAW: return m_auiEncounter[0]; - case TYPE_OVERSEER: return m_auiEncounter[1]; - case DATA_GRANDMASTERVORPILEVENT: return m_auiEncounter[3]; - case DATA_MURMUREVENT: return m_auiEncounter[4]; - } - return false; - } + if (!str) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - uint64 GetData64(uint32 identifier) const OVERRIDE - { - if (identifier == DATA_GRANDMASTERVORPIL) - return m_uiGrandmasterVorpil; + OUT_LOAD_INST_DATA(str); - return 0; - } + char dataHead1, dataHead2; - std::string GetSaveData() OVERRIDE - { - return str_data; - } - - void Load(const char* in) OVERRIDE - { - if (!in) - { - OUT_LOAD_INST_DATA_FAIL; - return; - } + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; - OUT_LOAD_INST_DATA(in); + if (dataHead1 == 'S' && dataHead2 == 'L') + { + 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; - std::istringstream loadStream(in); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4]; + OUT_LOAD_INST_DATA_COMPLETE; + } - for (uint8 i = 0; i < EncounterCount; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - m_auiEncounter[i] = NOT_STARTED; + protected: + uint64 AmbassadorHellmawGUID; + uint64 GrandmasterVorpilGUID; + uint32 FelOverseerCount; + }; - OUT_LOAD_INST_DATA_COMPLETE; + InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE + { + return new instance_shadow_labyrinth_InstanceMapScript(map); } - }; - }; void AddSC_instance_shadow_labyrinth() diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h index 8fdb60b32a6..fd073903748 100644 --- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h +++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> * * 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,26 +15,49 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DEF_SHADOW_LABYRINTH_H -#define DEF_SHADOW_LABYRINTH_H +#ifndef SHADOW_LABYRINTH_H_ +#define SHADOW_LABYRINTH_H_ -uint32 const EncounterCount = 5; +#define SLScriptName "instance_shadow_labyrinth" + +uint32 const EncounterCount = 4; enum DataTypes { - TYPE_HELLMAW = 1, - TYPE_OVERSEER = 2, - DATA_BLACKHEARTTHEINCITEREVENT = 3, - DATA_GRANDMASTERVORPILEVENT = 4, - DATA_MURMUREVENT = 5, - DATA_GRANDMASTERVORPIL = 6 + // Encounter States/Boss GUIDs + DATA_AMBASSADOR_HELLMAW = 0, + DATA_BLACKHEART_THE_INCITER = 1, + DATA_GRANDMASTER_VORPIL = 2, + DATA_MURMUR = 3, + + // Additional Data + DATA_FEL_OVERSEER = 4 +}; + +enum CreatureIds +{ + NPC_AMBASSADOR_HELLMAW = 18731, + NPC_GRANDMASTER_VORPIL = 18732, + NPC_FEL_OVERSEER = 18796 }; -enum Objects +enum GameObjectIds { - REFECTORY_DOOR = 183296, // door opened when blackheart the inciter dies - SCREAMING_HALL_DOOR = 183295 // door opened when grandmaster vorpil dies + GO_REFECTORY_DOOR = 183296, // door opened when blackheart the inciter dies + GO_SCREAMING_HALL_DOOR = 183295 // door opened when grandmaster vorpil dies }; -#endif +enum Misc +{ + ACTION_AMBASSADOR_HELLMAW_INTRO = 1, + ACTION_AMBASSADOR_HELLMAW_BANISH = 2, +}; + +template<class AI> +AI* GetShadowLabyrinthAI(Creature* creature) +{ + return GetInstanceAI<AI>(creature, SLScriptName); +} + +#endif // SHADOW_LABYRINTH_H_ diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt index c828c6dfbcf..84cbbc3c30c 100644 --- a/src/server/scripts/Outland/CMakeLists.txt +++ b/src/server/scripts/Outland/CMakeLists.txt @@ -74,19 +74,23 @@ set(scripts_STAT_SRCS Outland/TempestKeep/arcatraz/arcatraz.cpp Outland/Auchindoun/AuchenaiCrypts/boss_shirrak_the_dead_watcher.cpp Outland/Auchindoun/AuchenaiCrypts/boss_exarch_maladaar.cpp + Outland/Auchindoun/AuchenaiCrypts/instance_auchenai_crypts.cpp + Outland/Auchindoun/AuchenaiCrypts/auchenai_crypts.h Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp - Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp + Outland/Auchindoun/ManaTombs/instance_mana_tombs.cpp + Outland/Auchindoun/ManaTombs/mana_tombs.h Outland/Auchindoun/SethekkHalls/boss_darkweaver_syth.cpp + Outland/Auchindoun/SethekkHalls/boss_tailonking_ikiss.cpp Outland/Auchindoun/SethekkHalls/boss_anzu.cpp Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp Outland/Auchindoun/SethekkHalls/sethekk_halls.h - Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp + Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp + Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h - Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp Outland/boss_doomwalker.cpp Outland/zone_terokkar_forest.cpp Outland/zone_hellfire_peninsula.cpp |