From 6623a9dc4253e7b55cea3ff2e7a9a8946b24a736 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Fri, 21 Jun 2013 23:14:59 -0230 Subject: Core/Scripting: Renamed Dark Portal scripts to The Black Morass --- src/server/game/Scripting/ScriptLoader.cpp | 12 +- src/server/scripts/Kalimdor/CMakeLists.txt | 12 +- .../CavernsOfTime/DarkPortal/boss_aeonus.cpp | 149 -------- .../DarkPortal/boss_chrono_lord_deja.cpp | 152 -------- .../CavernsOfTime/DarkPortal/boss_temporus.cpp | 153 -------- .../CavernsOfTime/DarkPortal/dark_portal.cpp | 422 --------------------- .../CavernsOfTime/DarkPortal/dark_portal.h | 67 ---- .../DarkPortal/instance_dark_portal.cpp | 358 ----------------- .../CavernsOfTime/TheBlackMorass/boss_aeonus.cpp | 149 ++++++++ .../TheBlackMorass/boss_chrono_lord_deja.cpp | 152 ++++++++ .../CavernsOfTime/TheBlackMorass/boss_temporus.cpp | 153 ++++++++ .../TheBlackMorass/instance_the_black_morass.cpp | 352 +++++++++++++++++ .../TheBlackMorass/the_black_morass.cpp | 422 +++++++++++++++++++++ .../TheBlackMorass/the_black_morass.h | 67 ++++ 14 files changed, 1307 insertions(+), 1313 deletions(-) delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h delete mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp create mode 100644 src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h (limited to 'src') diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index e65c5884319..b240100f642 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -294,11 +294,11 @@ void AddSC_boss_epoch_hunter(); void AddSC_boss_lieutenant_drake(); void AddSC_instance_old_hillsbrad(); void AddSC_old_hillsbrad(); -void AddSC_boss_aeonus(); //CoT The Dark Portal +void AddSC_boss_aeonus(); //CoT The Black Morass void AddSC_boss_chrono_lord_deja(); void AddSC_boss_temporus(); -void AddSC_dark_portal(); -void AddSC_instance_dark_portal(); +void AddSC_the_black_morass(); +void AddSC_instance_the_black_morass(); void AddSC_boss_epoch(); //CoT Culling Of Stratholme void AddSC_boss_infinite_corruptor(); void AddSC_boss_salramm(); @@ -940,11 +940,11 @@ void AddKalimdorScripts() AddSC_boss_lieutenant_drake(); AddSC_instance_old_hillsbrad(); AddSC_old_hillsbrad(); - AddSC_boss_aeonus(); //CoT The Dark Portal + AddSC_boss_aeonus(); //CoT The Black Morass AddSC_boss_chrono_lord_deja(); AddSC_boss_temporus(); - AddSC_dark_portal(); - AddSC_instance_dark_portal(); + AddSC_the_black_morass(); + AddSC_instance_the_black_morass(); AddSC_boss_epoch(); //CoT Culling Of Stratholme AddSC_boss_infinite_corruptor(); AddSC_boss_salramm(); diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt index 536824e7a63..6a54d777c1e 100644 --- a/src/server/scripts/Kalimdor/CMakeLists.txt +++ b/src/server/scripts/Kalimdor/CMakeLists.txt @@ -46,12 +46,12 @@ set(scripts_STAT_SRCS Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp Kalimdor/CavernsOfTime/CullingOfStratholme/instance_culling_of_stratholme.cpp Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h - Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h - Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp - Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp - Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp - Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp - Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp + Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h + Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp + Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp + Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp + Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp + Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp Kalimdor/BlackfathomDeeps/boss_kelris.cpp Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp Kalimdor/BlackfathomDeeps/boss_gelihast.cpp diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp deleted file mode 100644 index a5ec73cdb30..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_aeonus.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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 - * 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 . - */ - -/* -Name: Boss_Aeonus -%Complete: 80 -Comment: Some spells not implemented -Category: Caverns of Time, The Dark Portal -*/ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "dark_portal.h" - -enum Enums -{ - SAY_ENTER = 0, - SAY_AGGRO = 1, - SAY_BANISH = 2, - SAY_SLAY = 3, - SAY_DEATH = 4, - EMOTE_FRENZY = 5, - - SPELL_CLEAVE = 40504, - SPELL_TIME_STOP = 31422, - SPELL_ENRAGE = 37605, - SPELL_SAND_BREATH = 31473, - H_SPELL_SAND_BREATH = 39049 -}; - -enum Events -{ - EVENT_SANDBREATH = 1, - EVENT_TIMESTOP = 2, - EVENT_FRENZY = 3 -}; - -class boss_aeonus : public CreatureScript -{ -public: - boss_aeonus() : CreatureScript("boss_aeonus") { } - - struct boss_aeonusAI : public BossAI - { - boss_aeonusAI(Creature* creature) : BossAI(creature, TYPE_AEONUS) { } - - void Reset() { } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_SANDBREATH, urand(15000, 30000)); - events.ScheduleEvent(EVENT_TIMESTOP, urand(10000, 15000)); - events.ScheduleEvent(EVENT_FRENZY, urand(30000, 45000)); - - Talk(SAY_AGGRO); - } - - void MoveInLineOfSight(Unit* who) - { - //Despawn Time Keeper - if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER) - { - if (me->IsWithinDistInMap(who, 20.0f)) - { - Talk(SAY_BANISH); - me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void JustDied(Unit* /*killer*/) - { - Talk(SAY_DEATH); - - if (instance) - { - instance->SetData(TYPE_RIFT, DONE); - instance->SetData(TYPE_MEDIVH, DONE); // FIXME: later should be removed - } - } - - void KilledUnit(Unit* /*victim*/) - { - Talk(SAY_SLAY); - } - - void UpdateAI(uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_SANDBREATH: - DoCast(me->GetVictim(), SPELL_SAND_BREATH); - events.ScheduleEvent(EVENT_SANDBREATH, urand(15000, 25000)); - break; - case EVENT_TIMESTOP: - DoCast(me->GetVictim(), SPELL_TIME_STOP); - events.ScheduleEvent(EVENT_TIMESTOP, urand(20000, 35000)); - break; - case EVENT_FRENZY: - Talk(EMOTE_FRENZY); - DoCast(me, SPELL_ENRAGE); - events.ScheduleEvent(EVENT_FRENZY, urand(20000, 35000)); - break; - default: - break; - } - } - DoMeleeAttackIfReady(); - } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_aeonusAI (creature); - } - }; -}; - -void AddSC_boss_aeonus() -{ - new boss_aeonus(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp deleted file mode 100644 index e469ba81623..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_chrono_lord_deja.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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 - * 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_Chrono_Lord_Deja -SD%Complete: 65 -SDComment: All abilities not implemented -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "dark_portal.h" - -enum Enums -{ - SAY_ENTER = 0, - SAY_AGGRO = 1, - SAY_BANISH = 2, - SAY_SLAY = 3, - SAY_DEATH = 4, - - SPELL_ARCANE_BLAST = 31457, - H_SPELL_ARCANE_BLAST = 38538, - SPELL_ARCANE_DISCHARGE = 31472, - H_SPELL_ARCANE_DISCHARGE = 38539, - SPELL_TIME_LAPSE = 31467, - SPELL_ATTRACTION = 38540 //Not Implemented (Heroic mode) -}; - -enum Events -{ - EVENT_ARCANE_BLAST = 1, - EVENT_TIME_LAPSE = 2, - EVENT_ARCANE_DISCHARGE = 3, - EVENT_ATTRACTION = 4 -}; - -class boss_chrono_lord_deja : public CreatureScript -{ -public: - boss_chrono_lord_deja() : CreatureScript("boss_chrono_lord_deja") { } - - struct boss_chrono_lord_dejaAI : public BossAI - { - boss_chrono_lord_dejaAI(Creature* creature) : BossAI(creature, TYPE_CRONO_LORD_DEJA) { } - - void Reset() { } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_ARCANE_BLAST, urand(18000, 23000)); - events.ScheduleEvent(EVENT_TIME_LAPSE, urand(10000, 15000)); - events.ScheduleEvent(EVENT_ARCANE_DISCHARGE, urand(20000, 30000)); - if (IsHeroic()) - events.ScheduleEvent(EVENT_ATTRACTION, urand(25000, 35000)); - - Talk(SAY_AGGRO); - } - - void MoveInLineOfSight(Unit* who) - { - //Despawn Time Keeper - if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER) - { - if (me->IsWithinDistInMap(who, 20.0f)) - { - Talk(SAY_BANISH); - me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void KilledUnit(Unit* /*victim*/) - { - Talk(SAY_SLAY); - } - - void JustDied(Unit* /*killer*/) - { - Talk(SAY_DEATH); - - if (instance) - instance->SetData(TYPE_RIFT, SPECIAL); - } - - void UpdateAI(uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_ARCANE_BLAST: - DoCast(me->GetVictim(), SPELL_ARCANE_BLAST); - events.ScheduleEvent(EVENT_ARCANE_BLAST, urand(15000, 25000)); - break; - case EVENT_TIME_LAPSE: - Talk(SAY_BANISH); - DoCast(me, SPELL_TIME_LAPSE); - events.ScheduleEvent(EVENT_TIME_LAPSE, urand(15000, 25000)); - break; - case EVENT_ARCANE_DISCHARGE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_ARCANE_DISCHARGE); - events.ScheduleEvent(EVENT_ARCANE_DISCHARGE, urand(20000, 30000)); - break; - case EVENT_ATTRACTION: // Only in Heroic - DoCast(me, SPELL_ATTRACTION); - events.ScheduleEvent(EVENT_ATTRACTION, urand(25000, 35000)); - break; - default: - break; - } - } - DoMeleeAttackIfReady(); - } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_chrono_lord_dejaAI (creature); - } - }; -}; - -void AddSC_boss_chrono_lord_deja() -{ - new boss_chrono_lord_deja(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp deleted file mode 100644 index bf311fe29ca..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/boss_temporus.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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 - * 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_Temporus -SD%Complete: 75 -SDComment: More abilities need to be implemented -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "dark_portal.h" - -enum Enums -{ - SAY_ENTER = 0, - SAY_AGGRO = 1, - SAY_BANISH = 2, - SAY_SLAY = 3, - SAY_DEATH = 4, - - SPELL_HASTE = 31458, - SPELL_MORTAL_WOUND = 31464, - SPELL_WING_BUFFET = 31475, - H_SPELL_WING_BUFFET = 38593, - SPELL_REFLECT = 38592 //Not Implemented (Heroic mod) -}; - -enum Events -{ - EVENT_HASTE = 1, - EVENT_MORTAL_WOUND = 2, - EVENT_WING_BUFFET = 3, - EVENT_SPELL_REFLECTION = 4 -}; - -class boss_temporus : public CreatureScript -{ -public: - boss_temporus() : CreatureScript("boss_temporus") { } - - struct boss_temporusAI : public BossAI - { - boss_temporusAI(Creature* creature) : BossAI(creature, TYPE_TEMPORUS) { } - - void Reset() { } - - void EnterCombat(Unit* /*who*/) - { - events.ScheduleEvent(EVENT_HASTE, urand(15000, 23000)); - events.ScheduleEvent(EVENT_MORTAL_WOUND, 8000); - events.ScheduleEvent(EVENT_WING_BUFFET, urand(25000, 35000)); - if (IsHeroic()) - events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000); - - Talk(SAY_AGGRO); - } - - void KilledUnit(Unit* /*victim*/) - { - Talk(SAY_SLAY); - } - - void JustDied(Unit* /*killer*/) - { - Talk(SAY_DEATH); - - if (instance) - instance->SetData(TYPE_RIFT, SPECIAL); - } - - void MoveInLineOfSight(Unit* who) - { - //Despawn Time Keeper - if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER) - { - if (me->IsWithinDistInMap(who, 20.0f)) - { - Talk(SAY_BANISH); - - me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - } - - ScriptedAI::MoveInLineOfSight(who); - } - - void UpdateAI(uint32 diff) - { - //Return since we have no target - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_HASTE: - DoCast(me, SPELL_HASTE); - events.ScheduleEvent(EVENT_HASTE, urand(20000, 25000)); - break; - case EVENT_MORTAL_WOUND: - DoCast(me, SPELL_MORTAL_WOUND); - events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 20000)); - break; - case EVENT_WING_BUFFET: - DoCast(me, SPELL_WING_BUFFET); - events.ScheduleEvent(EVENT_WING_BUFFET, urand(20000, 30000)); - break; - case EVENT_SPELL_REFLECTION: // Only in Heroic - DoCast(me, SPELL_REFLECT); - events.ScheduleEvent(EVENT_SPELL_REFLECTION, urand(25000, 35000)); - break; - default: - break; - } - } - DoMeleeAttackIfReady(); - } - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_temporusAI (creature); - } - }; - -}; - -void AddSC_boss_temporus() -{ - new boss_temporus(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp deleted file mode 100644 index f49325041f7..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.cpp +++ /dev/null @@ -1,422 +0,0 @@ -/* - * 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 - * 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: Dark_Portal -SD%Complete: 30 -SDComment: Misc NPC's and mobs for instance. Most here far from complete. -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -/* ContentData -npc_medivh_bm -npc_time_rift -npc_saat -EndContentData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" -#include "dark_portal.h" -#include "Player.h" -#include "SpellInfo.h" - -enum MedivhBm -{ - SAY_ENTER = 0, //where does this belong? - SAY_INTRO = 1, - SAY_WEAK75 = 2, - SAY_WEAK50 = 3, - SAY_WEAK25 = 4, - SAY_DEATH = 5, - SAY_WIN = 6, - SAY_ORCS_ENTER = 7, - SAY_ORCS_ANSWER = 8, - - SPELL_CHANNEL = 31556, - SPELL_PORTAL_RUNE = 32570, //aura(portal on ground effect) - - SPELL_BLACK_CRYSTAL = 32563, //aura - SPELL_PORTAL_CRYSTAL = 32564, //summon - - SPELL_BANISH_PURPLE = 32566, //aura - SPELL_BANISH_GREEN = 32567, //aura - - SPELL_CORRUPT = 31326, - SPELL_CORRUPT_AEONUS = 37853, - - C_COUNCIL_ENFORCER = 17023 -}; - -class npc_medivh_bm : public CreatureScript -{ -public: - npc_medivh_bm() : CreatureScript("npc_medivh_bm") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_medivh_bmAI (creature); - } - - struct npc_medivh_bmAI : public ScriptedAI - { - npc_medivh_bmAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 SpellCorrupt_Timer; - uint32 Check_Timer; - - bool Life75; - bool Life50; - bool Life25; - - void Reset() - { - SpellCorrupt_Timer = 0; - - if (!instance) - return; - - if (instance->GetData(TYPE_MEDIVH) == IN_PROGRESS) - DoCast(me, SPELL_CHANNEL, true); - else if (me->HasAura(SPELL_CHANNEL)) - me->RemoveAura(SPELL_CHANNEL); - - DoCast(me, SPELL_PORTAL_RUNE, true); - } - - void MoveInLineOfSight(Unit* who) - { - if (!instance) - return; - - if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 10.0f)) - { - if (instance->GetData(TYPE_MEDIVH) == IN_PROGRESS || instance->GetData(TYPE_MEDIVH) == DONE) - return; - - Talk(SAY_INTRO); - instance->SetData(TYPE_MEDIVH, IN_PROGRESS); - DoCast(me, SPELL_CHANNEL, false); - Check_Timer = 5000; - } - else if (who->GetTypeId() == TYPEID_UNIT && me->IsWithinDistInMap(who, 15.0f)) - { - if (instance->GetData(TYPE_MEDIVH) != IN_PROGRESS) - return; - - uint32 entry = who->GetEntry(); - if (entry == NPC_INFINITE_ASSASIN || entry == NPC_INFINITE_WHELP || entry == NPC_INFINITE_CRONOMANCER || entry == NPC_INFINITE_EXECUTIONER || entry == NPC_INFINITE_VANQUISHER) - { - who->StopMoving(); - who->CastSpell(me, SPELL_CORRUPT, false); - } - else if (entry == NPC_AEONUS) - { - who->StopMoving(); - who->CastSpell(me, SPELL_CORRUPT_AEONUS, false); - } - } - } - - void AttackStart(Unit* /*who*/) - { - //if (instance && instance->GetData(TYPE_MEDIVH) == IN_PROGRESS) - //return; - - //ScriptedAI::AttackStart(who); - } - - void EnterCombat(Unit* /*who*/) {} - - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) - { - if (SpellCorrupt_Timer) - return; - - if (spell->Id == SPELL_CORRUPT_AEONUS) - SpellCorrupt_Timer = 1000; - - if (spell->Id == SPELL_CORRUPT) - SpellCorrupt_Timer = 3000; - } - - void JustDied(Unit* killer) - { - if (killer->GetEntry() == me->GetEntry()) - return; - - Talk(SAY_DEATH); - } - - void UpdateAI(uint32 diff) - { - if (!instance) - return; - - if (SpellCorrupt_Timer) - { - if (SpellCorrupt_Timer <= diff) - { - instance->SetData(TYPE_MEDIVH, SPECIAL); - - if (me->HasAura(SPELL_CORRUPT_AEONUS)) - SpellCorrupt_Timer = 1000; - else if (me->HasAura(SPELL_CORRUPT)) - SpellCorrupt_Timer = 3000; - else - SpellCorrupt_Timer = 0; - } else SpellCorrupt_Timer -= diff; - } - - if (Check_Timer) - { - if (Check_Timer <= diff) - { - uint32 pct = instance->GetData(DATA_SHIELD); - - Check_Timer = 5000; - - if (Life25 && pct <= 25) - { - Talk(SAY_WEAK25); - Life25 = false; - } - else if (Life50 && pct <= 50) - { - Talk(SAY_WEAK50); - Life50 = false; - } - else if (Life75 && pct <= 75) - { - Talk(SAY_WEAK75); - Life75 = false; - } - - //if we reach this it means event was running but at some point reset. - if (instance->GetData(TYPE_MEDIVH) == NOT_STARTED) - { - me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - me->RemoveCorpse(); - me->Respawn(); - return; - } - - if (instance->GetData(TYPE_RIFT) == DONE) - { - Talk(SAY_WIN); - Check_Timer = 0; - - if (me->HasAura(SPELL_CHANNEL)) - me->RemoveAura(SPELL_CHANNEL); - - /// @todo start the post-event here - instance->SetData(TYPE_MEDIVH, DONE); - } - } else Check_Timer -= diff; - } - - //if (!UpdateVictim()) - //return; - - //DoMeleeAttackIfReady(); - } - }; - -}; - -struct Wave -{ - uint32 PortalMob[4]; //spawns for portal waves (in order) -}; - -static Wave PortalWaves[]= -{ - { {NPC_INFINITE_ASSASIN, NPC_INFINITE_WHELP, NPC_INFINITE_CRONOMANCER, 0} }, - { {NPC_INFINITE_EXECUTIONER, NPC_INFINITE_CRONOMANCER, NPC_INFINITE_WHELP, NPC_INFINITE_ASSASIN} }, - { {NPC_INFINITE_EXECUTIONER, NPC_INFINITE_VANQUISHER, NPC_INFINITE_CRONOMANCER, NPC_INFINITE_ASSASIN} } -}; - -class npc_time_rift : public CreatureScript -{ -public: - npc_time_rift() : CreatureScript("npc_time_rift") { } - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_time_riftAI (creature); - } - - struct npc_time_riftAI : public ScriptedAI - { - npc_time_riftAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 TimeRiftWave_Timer; - uint8 mRiftWaveCount; - uint8 mPortalCount; - uint8 mWaveId; - - void Reset() - { - - TimeRiftWave_Timer = 15000; - mRiftWaveCount = 0; - - if (!instance) - return; - - mPortalCount = instance->GetData(DATA_PORTAL_COUNT); - - if (mPortalCount < 6) - mWaveId = 0; - else if (mPortalCount > 12) - mWaveId = 2; - else mWaveId = 1; - - } - void EnterCombat(Unit* /*who*/) {} - - void DoSummonAtRift(uint32 creature_entry) - { - if (!creature_entry) - return; - - if (instance && instance->GetData(TYPE_MEDIVH) != IN_PROGRESS) - { - me->InterruptNonMeleeSpells(true); - me->RemoveAllAuras(); - return; - } - - Position pos; - me->GetRandomNearPosition(pos, 10.0f); - - //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); - - if (Unit* Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) - if (Unit* temp = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_MEDIVH) : 0)) - Summon->AddThreat(temp, 0.0f); - } - - void DoSelectSummon() - { - if ((mRiftWaveCount > 2 && mWaveId < 1) || mRiftWaveCount > 3) - mRiftWaveCount = 0; - - uint32 entry = 0; - - entry = PortalWaves[mWaveId].PortalMob[mRiftWaveCount]; - TC_LOG_DEBUG(LOG_FILTER_TSCR, "npc_time_rift: summoning wave Creature (Wave %u, Entry %u).", mRiftWaveCount, entry); - - ++mRiftWaveCount; - - if (entry == NPC_INFINITE_WHELP) - { - for (uint8 i = 0; i < 3; ++i) - DoSummonAtRift(entry); - } else DoSummonAtRift(entry); - } - - void UpdateAI(uint32 diff) - { - if (!instance) - return; - - if (TimeRiftWave_Timer <= diff) - { - DoSelectSummon(); - TimeRiftWave_Timer = 15000; - } else TimeRiftWave_Timer -= diff; - - if (me->IsNonMeleeSpellCasted(false)) - return; - - TC_LOG_DEBUG(LOG_FILTER_TSCR, "npc_time_rift: not casting anylonger, i need to die."); - me->setDeathState(JUST_DIED); - - if (instance->GetData(TYPE_RIFT) == IN_PROGRESS) - instance->SetData(TYPE_RIFT, SPECIAL); - } - }; - -}; - -enum Saat -{ - SPELL_CHRONO_BEACON = 34975, - ITEM_CHRONO_BEACON = 24289 -}; - -#define GOSSIP_ITEM_OBTAIN "[PH] Obtain Chrono-Beacon" - -class npc_saat : public CreatureScript -{ -public: - npc_saat() : CreatureScript("npc_saat") { } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - if (action == GOSSIP_ACTION_INFO_DEF+1) - { - player->CLOSE_GOSSIP_MENU(); - creature->CastSpell(player, SPELL_CHRONO_BEACON, false); - } - return true; - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->IsQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); - - if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(ITEM_CHRONO_BEACON)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_OBTAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(10000, creature->GetGUID()); - return true; - } - else if (player->GetQuestRewardStatus(QUEST_OPENING_PORTAL) && !player->HasItemCount(ITEM_CHRONO_BEACON)) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_OBTAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - player->SEND_GOSSIP_MENU(10001, creature->GetGUID()); - return true; - } - - player->SEND_GOSSIP_MENU(10002, creature->GetGUID()); - return true; - } - -}; - -void AddSC_dark_portal() -{ - new npc_medivh_bm(); - new npc_time_rift(); - new npc_saat(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h deleted file mode 100644 index 09f693d73f4..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/dark_portal.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 - * 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 DEF_DARKPORTAL_H -#define DEF_DARKPORTAL_H - -uint32 const EncounterCount = 2; - -enum DataTypes -{ - TYPE_MEDIVH = 1, - TYPE_RIFT = 2, - TYPE_AEONUS = 3, - TYPE_TEMPORUS = 4, - TYPE_CRONO_LORD_DEJA = 5, - DATA_MEDIVH = 10, - DATA_PORTAL_COUNT = 11, - DATA_SHIELD = 12 -}; - -enum WorldStateIds -{ - WORLD_STATE_BM = 2541, - WORLD_STATE_BM_SHIELD = 2540, - WORLD_STATE_BM_RIFT = 2784 -}; - -enum QuestIds -{ - QUEST_OPENING_PORTAL = 10297, - QUEST_MASTER_TOUCH = 9836 -}; - -enum CreatureIds -{ - NPC_MEDIVH = 15608, - NPC_TIME_RIFT = 17838, - NPC_TIME_KEEPER = 17918, - NPC_RIFT_KEEPER = 21104, - NPC_RIFT_LORD = 17839, - NPC_CRONO_LORD_DEJA = 17879, - NPC_TEMPORUS = 17880, - NPC_AEONUS = 17881, - NPC_INFINITE_ASSASIN = 17835, - NPC_INFINITE_WHELP = 21818, - NPC_INFINITE_CRONOMANCER = 17892, - NPC_INFINITE_EXECUTIONER = 18994, - NPC_INFINITE_VANQUISHER = 18995 -}; - -#endif - diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp deleted file mode 100644 index 28f16a10ed3..00000000000 --- a/src/server/scripts/Kalimdor/CavernsOfTime/DarkPortal/instance_dark_portal.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* - * 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 - * 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: Instance_Dark_Portal -SD%Complete: 50 -SDComment: Quest support: 9836, 10297. Currently in progress. -SDCategory: Caverns of Time, The Dark Portal -EndScriptData */ - -#include "ScriptMgr.h" -#include "InstanceScript.h" -#include "dark_portal.h" -#include "Player.h" -#include "TemporarySummon.h" -#include "SpellInfo.h" - -enum Misc -{ - SPELL_RIFT_CHANNEL = 31387, - RIFT_BOSS = 1 -}; - -inline uint32 RandRiftBoss() { return ((rand()%2) ? NPC_RIFT_KEEPER : NPC_RIFT_LORD); } - -float PortalLocation[4][4]= -{ - {-2041.06f, 7042.08f, 29.99f, 1.30f}, - {-1968.18f, 7042.11f, 21.93f, 2.12f}, - {-1885.82f, 7107.36f, 22.32f, 3.07f}, - {-1928.11f, 7175.95f, 22.11f, 3.44f} -}; - -struct Wave -{ - uint32 PortalBoss; //protector of current portal - uint32 NextPortalTime; //time to next portal, or 0 if portal boss need to be killed -}; - -static Wave RiftWaves[]= -{ - { RIFT_BOSS, 0 }, - { NPC_CRONO_LORD_DEJA, 0 }, - { RIFT_BOSS, 120000 }, - { NPC_TEMPORUS, 140000 }, - { RIFT_BOSS, 120000 }, - { NPC_AEONUS, 0 } -}; - -enum EventIds -{ - EVENT_NEXT_PORTAL = 1 -}; - -class instance_dark_portal : public InstanceMapScript -{ -public: - instance_dark_portal() : InstanceMapScript("instance_dark_portal", 269) { } - - InstanceScript* GetInstanceScript(InstanceMap* map) const - { - return new instance_dark_portal_InstanceMapScript(map); - } - - struct instance_dark_portal_InstanceMapScript : public InstanceScript - { - instance_dark_portal_InstanceMapScript(Map* map) : InstanceScript(map) { } - - uint32 m_auiEncounter[EncounterCount]; - - uint32 mRiftPortalCount; - uint32 mShieldPercent; - uint8 mRiftWaveCount; - uint8 mRiftWaveId; - - uint64 _medivhGUID; - uint8 _currentRiftId; - - void Initialize() - { - _medivhGUID = 0; - Clear(); - } - - void Clear() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - mRiftPortalCount = 0; - mShieldPercent = 100; - mRiftWaveCount = 0; - mRiftWaveId = 0; - - _currentRiftId = 0; - } - - void InitWorldState(bool Enable = true) - { - DoUpdateWorldState(WORLD_STATE_BM, Enable ? 1 : 0); - DoUpdateWorldState(WORLD_STATE_BM_SHIELD, 100); - DoUpdateWorldState(WORLD_STATE_BM_RIFT, 0); - } - - bool IsEncounterInProgress() const - { - if (GetData(TYPE_MEDIVH) == IN_PROGRESS) - return true; - - return false; - } - - void OnPlayerEnter(Player* player) - { - if (GetData(TYPE_MEDIVH) == IN_PROGRESS) - return; - - player->SendUpdateWorldState(WORLD_STATE_BM, 0); - } - - void OnCreatureCreate(Creature* creature) - { - if (creature->GetEntry() == NPC_MEDIVH) - _medivhGUID = creature->GetGUID(); - } - - //what other conditions to check? - bool CanProgressEvent() - { - if (instance->GetPlayers().isEmpty()) - return false; - - return true; - } - - uint8 GetRiftWaveId() - { - switch (mRiftPortalCount) - { - case 6: - mRiftWaveId = 2; - return 1; - case 12: - mRiftWaveId = 4; - return 3; - case 18: - return 5; - default: - return mRiftWaveId; - } - } - - void SetData(uint32 type, uint32 data) - { - switch (type) - { - case TYPE_MEDIVH: - if (data == SPECIAL && m_auiEncounter[0] == IN_PROGRESS) - { - --mShieldPercent; - - DoUpdateWorldState(WORLD_STATE_BM_SHIELD, mShieldPercent); - - if (!mShieldPercent) - { - if (Creature* medivh = instance->GetCreature(_medivhGUID)) - { - if (medivh->IsAlive()) - { - medivh->DealDamage(medivh, medivh->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - m_auiEncounter[0] = FAIL; - m_auiEncounter[1] = NOT_STARTED; - } - } - } - } - else - { - if (data == IN_PROGRESS) - { - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance Dark Portal: Starting event."); - InitWorldState(); - m_auiEncounter[1] = IN_PROGRESS; - _events.ScheduleEvent(EVENT_NEXT_PORTAL, 15000); - } - - if (data == DONE) - { - //this may be completed further out in the post-event - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance Dark Portal: Event completed."); - Map::PlayerList const& players = instance->GetPlayers(); - - if (!players.isEmpty()) - { - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - { - if (Player* player = itr->GetSource()) - { - if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE) - player->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL); - - if (player->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE) - player->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH); - } - } - } - } - - m_auiEncounter[0] = data; - } - break; - case TYPE_RIFT: - if (data == SPECIAL) - { - if (mRiftPortalCount < 7) - _events.ScheduleEvent(EVENT_NEXT_PORTAL, 5000); - } - else - m_auiEncounter[1] = data; - break; - } - } - - uint32 GetData(uint32 type) const - { - switch (type) - { - case TYPE_MEDIVH: - return m_auiEncounter[0]; - case TYPE_RIFT: - return m_auiEncounter[1]; - case DATA_PORTAL_COUNT: - return mRiftPortalCount; - case DATA_SHIELD: - return mShieldPercent; - } - return 0; - } - - uint64 GetData64(uint32 data) const - { - if (data == DATA_MEDIVH) - return _medivhGUID; - - return 0; - } - - Creature* SummonedPortalBoss(Creature* me) - { - uint32 entry = RiftWaves[GetRiftWaveId()].PortalBoss; - - if (entry == RIFT_BOSS) - entry = RandRiftBoss(); - - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance Dark Portal: Summoning rift boss entry %u.", entry); - - Position pos; - me->GetRandomNearPosition(pos, 10.0f); - - //normalize Z-level if we can, if rift is not at ground level. - pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); - - if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000)) - return summon; - - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance Dark Portal: What just happened there? No boss, no loot, no fun..."); - return NULL; - } - - void DoSpawnPortal() - { - if (Creature* medivh = instance->GetCreature(_medivhGUID)) - { - uint8 tmp = urand(0, 2); - - if (tmp >= _currentRiftId) - ++tmp; - - TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance Dark Portal: Creating Time Rift at locationId %i (old locationId was %u).", tmp, _currentRiftId); - - _currentRiftId = tmp; - - Creature* temp = medivh->SummonCreature(NPC_TIME_RIFT, - PortalLocation[tmp][0], PortalLocation[tmp][1], PortalLocation[tmp][2], PortalLocation[tmp][3], - TEMPSUMMON_CORPSE_DESPAWN, 0); - if (temp) - { - temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - if (Creature* boss = SummonedPortalBoss(temp)) - { - if (boss->GetEntry() == NPC_AEONUS) - boss->AddThreat(medivh, 0.0f); - else - { - boss->AddThreat(temp, 0.0f); - temp->CastSpell(boss, SPELL_RIFT_CHANNEL, false); - } - } - } - } - } - - void Update(uint32 diff) - { - if (m_auiEncounter[1] != IN_PROGRESS) - return; - - //add delay timer? - if (!CanProgressEvent()) - { - Clear(); - return; - } - - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_NEXT_PORTAL: - ++mRiftPortalCount; - DoUpdateWorldState(WORLD_STATE_BM_RIFT, mRiftPortalCount); - DoSpawnPortal(); - _events.ScheduleEvent(EVENT_NEXT_PORTAL, RiftWaves[GetRiftWaveId()].NextPortalTime); - break; - default: - break; - } - } - } - - private: - EventMap _events; - }; - -}; - -void AddSC_instance_dark_portal() -{ - new instance_dark_portal(); -} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp new file mode 100644 index 00000000000..3b1987e04f5 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_aeonus.cpp @@ -0,0 +1,149 @@ +/* + * 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 + * 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 . + */ + +/* +Name: Boss_Aeonus +%Complete: 80 +Comment: Some spells not implemented +Category: Caverns of Time, The Dark Portal +*/ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "the_black_morass.h" + +enum Enums +{ + SAY_ENTER = 0, + SAY_AGGRO = 1, + SAY_BANISH = 2, + SAY_SLAY = 3, + SAY_DEATH = 4, + EMOTE_FRENZY = 5, + + SPELL_CLEAVE = 40504, + SPELL_TIME_STOP = 31422, + SPELL_ENRAGE = 37605, + SPELL_SAND_BREATH = 31473, + H_SPELL_SAND_BREATH = 39049 +}; + +enum Events +{ + EVENT_SANDBREATH = 1, + EVENT_TIMESTOP = 2, + EVENT_FRENZY = 3 +}; + +class boss_aeonus : public CreatureScript +{ +public: + boss_aeonus() : CreatureScript("boss_aeonus") { } + + struct boss_aeonusAI : public BossAI + { + boss_aeonusAI(Creature* creature) : BossAI(creature, TYPE_AEONUS) { } + + void Reset() { } + + void EnterCombat(Unit* /*who*/) + { + events.ScheduleEvent(EVENT_SANDBREATH, urand(15000, 30000)); + events.ScheduleEvent(EVENT_TIMESTOP, urand(10000, 15000)); + events.ScheduleEvent(EVENT_FRENZY, urand(30000, 45000)); + + Talk(SAY_AGGRO); + } + + void MoveInLineOfSight(Unit* who) + { + //Despawn Time Keeper + if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER) + { + if (me->IsWithinDistInMap(who, 20.0f)) + { + Talk(SAY_BANISH); + me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } + + void JustDied(Unit* /*killer*/) + { + Talk(SAY_DEATH); + + if (instance) + { + instance->SetData(TYPE_RIFT, DONE); + instance->SetData(TYPE_MEDIVH, DONE); // FIXME: later should be removed + } + } + + void KilledUnit(Unit* /*victim*/) + { + Talk(SAY_SLAY); + } + + void UpdateAI(uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SANDBREATH: + DoCast(me->GetVictim(), SPELL_SAND_BREATH); + events.ScheduleEvent(EVENT_SANDBREATH, urand(15000, 25000)); + break; + case EVENT_TIMESTOP: + DoCast(me->GetVictim(), SPELL_TIME_STOP); + events.ScheduleEvent(EVENT_TIMESTOP, urand(20000, 35000)); + break; + case EVENT_FRENZY: + Talk(EMOTE_FRENZY); + DoCast(me, SPELL_ENRAGE); + events.ScheduleEvent(EVENT_FRENZY, urand(20000, 35000)); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); + } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_aeonusAI (creature); + } + }; +}; + +void AddSC_boss_aeonus() +{ + new boss_aeonus(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp new file mode 100644 index 00000000000..9fd7b22a1da --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_chrono_lord_deja.cpp @@ -0,0 +1,152 @@ +/* + * 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 + * 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 . + */ + +/* +Name: Boss_Chrono_Lord_Deja +%Complete: 65 +Comment: All abilities not implemented +Category: Caverns of Time, The Black Morass +*/ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "the_black_morass.h" + +enum Enums +{ + SAY_ENTER = 0, + SAY_AGGRO = 1, + SAY_BANISH = 2, + SAY_SLAY = 3, + SAY_DEATH = 4, + + SPELL_ARCANE_BLAST = 31457, + H_SPELL_ARCANE_BLAST = 38538, + SPELL_ARCANE_DISCHARGE = 31472, + H_SPELL_ARCANE_DISCHARGE = 38539, + SPELL_TIME_LAPSE = 31467, + SPELL_ATTRACTION = 38540 //Not Implemented (Heroic mode) +}; + +enum Events +{ + EVENT_ARCANE_BLAST = 1, + EVENT_TIME_LAPSE = 2, + EVENT_ARCANE_DISCHARGE = 3, + EVENT_ATTRACTION = 4 +}; + +class boss_chrono_lord_deja : public CreatureScript +{ +public: + boss_chrono_lord_deja() : CreatureScript("boss_chrono_lord_deja") { } + + struct boss_chrono_lord_dejaAI : public BossAI + { + boss_chrono_lord_dejaAI(Creature* creature) : BossAI(creature, TYPE_CRONO_LORD_DEJA) { } + + void Reset() { } + + void EnterCombat(Unit* /*who*/) + { + events.ScheduleEvent(EVENT_ARCANE_BLAST, urand(18000, 23000)); + events.ScheduleEvent(EVENT_TIME_LAPSE, urand(10000, 15000)); + events.ScheduleEvent(EVENT_ARCANE_DISCHARGE, urand(20000, 30000)); + if (IsHeroic()) + events.ScheduleEvent(EVENT_ATTRACTION, urand(25000, 35000)); + + Talk(SAY_AGGRO); + } + + void MoveInLineOfSight(Unit* who) + { + //Despawn Time Keeper + if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER) + { + if (me->IsWithinDistInMap(who, 20.0f)) + { + Talk(SAY_BANISH); + me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } + + void KilledUnit(Unit* /*victim*/) + { + Talk(SAY_SLAY); + } + + void JustDied(Unit* /*killer*/) + { + Talk(SAY_DEATH); + + if (instance) + instance->SetData(TYPE_RIFT, SPECIAL); + } + + void UpdateAI(uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ARCANE_BLAST: + DoCast(me->GetVictim(), SPELL_ARCANE_BLAST); + events.ScheduleEvent(EVENT_ARCANE_BLAST, urand(15000, 25000)); + break; + case EVENT_TIME_LAPSE: + Talk(SAY_BANISH); + DoCast(me, SPELL_TIME_LAPSE); + events.ScheduleEvent(EVENT_TIME_LAPSE, urand(15000, 25000)); + break; + case EVENT_ARCANE_DISCHARGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_ARCANE_DISCHARGE); + events.ScheduleEvent(EVENT_ARCANE_DISCHARGE, urand(20000, 30000)); + break; + case EVENT_ATTRACTION: // Only in Heroic + DoCast(me, SPELL_ATTRACTION); + events.ScheduleEvent(EVENT_ATTRACTION, urand(25000, 35000)); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); + } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_chrono_lord_dejaAI (creature); + } + }; +}; + +void AddSC_boss_chrono_lord_deja() +{ + new boss_chrono_lord_deja(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp new file mode 100644 index 00000000000..8ded2388083 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/boss_temporus.cpp @@ -0,0 +1,153 @@ +/* + * 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 + * 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 . + */ + +/* +Name: Boss_Temporus +%Complete: 75 +Comment: More abilities need to be implemented +Category: Caverns of Time, The Black Morass +*/ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "the_black_morass.h" + +enum Enums +{ + SAY_ENTER = 0, + SAY_AGGRO = 1, + SAY_BANISH = 2, + SAY_SLAY = 3, + SAY_DEATH = 4, + + SPELL_HASTE = 31458, + SPELL_MORTAL_WOUND = 31464, + SPELL_WING_BUFFET = 31475, + H_SPELL_WING_BUFFET = 38593, + SPELL_REFLECT = 38592 //Not Implemented (Heroic mod) +}; + +enum Events +{ + EVENT_HASTE = 1, + EVENT_MORTAL_WOUND = 2, + EVENT_WING_BUFFET = 3, + EVENT_SPELL_REFLECTION = 4 +}; + +class boss_temporus : public CreatureScript +{ +public: + boss_temporus() : CreatureScript("boss_temporus") { } + + struct boss_temporusAI : public BossAI + { + boss_temporusAI(Creature* creature) : BossAI(creature, TYPE_TEMPORUS) { } + + void Reset() { } + + void EnterCombat(Unit* /*who*/) + { + events.ScheduleEvent(EVENT_HASTE, urand(15000, 23000)); + events.ScheduleEvent(EVENT_MORTAL_WOUND, 8000); + events.ScheduleEvent(EVENT_WING_BUFFET, urand(25000, 35000)); + if (IsHeroic()) + events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000); + + Talk(SAY_AGGRO); + } + + void KilledUnit(Unit* /*victim*/) + { + Talk(SAY_SLAY); + } + + void JustDied(Unit* /*killer*/) + { + Talk(SAY_DEATH); + + if (instance) + instance->SetData(TYPE_RIFT, SPECIAL); + } + + void MoveInLineOfSight(Unit* who) + { + //Despawn Time Keeper + if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER) + { + if (me->IsWithinDistInMap(who, 20.0f)) + { + Talk(SAY_BANISH); + + me->DealDamage(who, who->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + } + + ScriptedAI::MoveInLineOfSight(who); + } + + void UpdateAI(uint32 diff) + { + //Return since we have no target + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_HASTE: + DoCast(me, SPELL_HASTE); + events.ScheduleEvent(EVENT_HASTE, urand(20000, 25000)); + break; + case EVENT_MORTAL_WOUND: + DoCast(me, SPELL_MORTAL_WOUND); + events.ScheduleEvent(EVENT_MORTAL_WOUND, urand(10000, 20000)); + break; + case EVENT_WING_BUFFET: + DoCast(me, SPELL_WING_BUFFET); + events.ScheduleEvent(EVENT_WING_BUFFET, urand(20000, 30000)); + break; + case EVENT_SPELL_REFLECTION: // Only in Heroic + DoCast(me, SPELL_REFLECT); + events.ScheduleEvent(EVENT_SPELL_REFLECTION, urand(25000, 35000)); + break; + default: + break; + } + } + DoMeleeAttackIfReady(); + } + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_temporusAI (creature); + } + }; + +}; + +void AddSC_boss_temporus() +{ + new boss_temporus(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp new file mode 100644 index 00000000000..7d76cce6ddb --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/instance_the_black_morass.cpp @@ -0,0 +1,352 @@ +/* + * 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 + * 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 . + */ + +/* +Name: Instance_The_Black_Morass +%Complete: 50 +Comment: Quest support: 9836, 10297. Currently in progress. +Category: Caverns of Time, The Black Morass +*/ + +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "the_black_morass.h" +#include "Player.h" +#include "TemporarySummon.h" +#include "SpellInfo.h" +#include "ScriptedCreature.h" + +enum Misc +{ + SPELL_RIFT_CHANNEL = 31387, + RIFT_BOSS = 1 +}; + +inline uint32 RandRiftBoss() { return ((rand()%2) ? NPC_RIFT_KEEPER : NPC_RIFT_LORD); } + +float PortalLocation[4][4]= +{ + {-2041.06f, 7042.08f, 29.99f, 1.30f}, + {-1968.18f, 7042.11f, 21.93f, 2.12f}, + {-1885.82f, 7107.36f, 22.32f, 3.07f}, + {-1928.11f, 7175.95f, 22.11f, 3.44f} +}; + +struct Wave +{ + uint32 PortalBoss; //protector of current portal + uint32 NextPortalTime; //time to next portal, or 0 if portal boss need to be killed +}; + +static Wave RiftWaves[]= +{ + { RIFT_BOSS, 0 }, + { NPC_CRONO_LORD_DEJA, 0 }, + { RIFT_BOSS, 120000 }, + { NPC_TEMPORUS, 140000 }, + { RIFT_BOSS, 120000 }, + { NPC_AEONUS, 0 } +}; + +enum EventIds +{ + EVENT_NEXT_PORTAL = 1 +}; + +class instance_the_black_morass : public InstanceMapScript +{ +public: + instance_the_black_morass() : InstanceMapScript("instance_the_black_morass", 269) { } + + InstanceScript* GetInstanceScript(InstanceMap* map) const + { + return new instance_the_black_morass_InstanceMapScript(map); + } + + struct instance_the_black_morass_InstanceMapScript : public InstanceScript + { + instance_the_black_morass_InstanceMapScript(Map* map) : InstanceScript(map) { } + + uint32 m_auiEncounter[EncounterCount]; + + uint32 mRiftPortalCount; + uint32 mShieldPercent; + uint8 mRiftWaveCount; + uint8 mRiftWaveId; + + uint64 _medivhGUID; + uint8 _currentRiftId; + + void Initialize() + { + _medivhGUID = 0; + Clear(); + } + + void Clear() + { + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + + mRiftPortalCount = 0; + mShieldPercent = 100; + mRiftWaveCount = 0; + mRiftWaveId = 0; + + _currentRiftId = 0; + } + + void InitWorldState(bool Enable = true) + { + DoUpdateWorldState(WORLD_STATE_BM, Enable ? 1 : 0); + DoUpdateWorldState(WORLD_STATE_BM_SHIELD, 100); + DoUpdateWorldState(WORLD_STATE_BM_RIFT, 0); + } + + bool IsEncounterInProgress() const + { + if (GetData(TYPE_MEDIVH) == IN_PROGRESS) + return true; + + return false; + } + + void OnPlayerEnter(Player* player) + { + if (GetData(TYPE_MEDIVH) == IN_PROGRESS) + return; + + player->SendUpdateWorldState(WORLD_STATE_BM, 0); + } + + void OnCreatureCreate(Creature* creature) + { + if (creature->GetEntry() == NPC_MEDIVH) + _medivhGUID = creature->GetGUID(); + } + + //what other conditions to check? + bool CanProgressEvent() + { + if (instance->GetPlayers().isEmpty()) + return false; + + return true; + } + + uint8 GetRiftWaveId() + { + switch (mRiftPortalCount) + { + case 6: + mRiftWaveId = 2; + return 1; + case 12: + mRiftWaveId = 4; + return 3; + case 18: + return 5; + default: + return mRiftWaveId; + } + } + + void SetData(uint32 type, uint32 data) + { + switch (type) + { + case TYPE_MEDIVH: + if (data == SPECIAL && m_auiEncounter[0] == IN_PROGRESS) + { + --mShieldPercent; + + DoUpdateWorldState(WORLD_STATE_BM_SHIELD, mShieldPercent); + + if (!mShieldPercent) + { + if (Creature* medivh = instance->GetCreature(_medivhGUID)) + { + if (medivh->IsAlive()) + { + medivh->DealDamage(medivh, medivh->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_auiEncounter[0] = FAIL; + m_auiEncounter[1] = NOT_STARTED; + } + } + } + } + else + { + if (data == IN_PROGRESS) + { + TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance The Black Morass: Starting event."); + InitWorldState(); + m_auiEncounter[1] = IN_PROGRESS; + Events.ScheduleEvent(EVENT_NEXT_PORTAL, 15000); + } + + if (data == DONE) + { + //this may be completed further out in the post-event + TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance The Black Morass: Event completed."); + Map::PlayerList const& players = instance->GetPlayers(); + + if (!players.isEmpty()) + { + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + if (Player* player = itr->GetSource()) + { + if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE) + player->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL); + + if (player->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE) + player->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH); + } + } + } + } + + m_auiEncounter[0] = data; + } + break; + case TYPE_RIFT: + if (data == SPECIAL) + { + if (mRiftPortalCount < 7) + Events.ScheduleEvent(EVENT_NEXT_PORTAL, 5000); + } + else + m_auiEncounter[1] = data; + break; + } + } + + uint32 GetData(uint32 type) const + { + switch (type) + { + case TYPE_MEDIVH: + return m_auiEncounter[0]; + case TYPE_RIFT: + return m_auiEncounter[1]; + case DATA_PORTAL_COUNT: + return mRiftPortalCount; + case DATA_SHIELD: + return mShieldPercent; + } + return 0; + } + + uint64 GetData64(uint32 data) const + { + if (data == DATA_MEDIVH) + return _medivhGUID; + + return 0; + } + + Creature* SummonedPortalBoss(Creature* me) + { + uint32 entry = RiftWaves[GetRiftWaveId()].PortalBoss; + + if (entry == RIFT_BOSS) + entry = RandRiftBoss(); + + TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance The Black Morass: Summoning rift boss entry %u.", entry); + + Position pos; + me->GetRandomNearPosition(pos, 10.0f); + + //normalize Z-level if we can, if rift is not at ground level. + pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + + if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000)) + return summon; + + TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance The Black Morass: What just happened there? No boss, no loot, no fun..."); + return NULL; + } + + void DoSpawnPortal() + { + if (Creature* medivh = instance->GetCreature(_medivhGUID)) + { + uint8 tmp = urand(0, 2); + + if (tmp >= _currentRiftId) + ++tmp; + + TC_LOG_DEBUG(LOG_FILTER_TSCR, "Instance The Black Morass: Creating Time Rift at locationId %i (old locationId was %u).", tmp, _currentRiftId); + + _currentRiftId = tmp; + + Creature* temp = medivh->SummonCreature(NPC_TIME_RIFT, + PortalLocation[tmp][0], PortalLocation[tmp][1], PortalLocation[tmp][2], PortalLocation[tmp][3], + TEMPSUMMON_CORPSE_DESPAWN, 0); + if (temp) + { + temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + temp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + if (Creature* boss = SummonedPortalBoss(temp)) + { + if (boss->GetEntry() == NPC_AEONUS) + boss->AddThreat(medivh, 0.0f); + else + { + boss->AddThreat(temp, 0.0f); + temp->CastSpell(boss, SPELL_RIFT_CHANNEL, false); + } + } + } + } + } + + void Update(uint32 diff) + { + if (m_auiEncounter[1] != IN_PROGRESS) + return; + + //add delay timer? + if (!CanProgressEvent()) + { + Clear(); + return; + } + + Events.Update(diff); + + if (Events.ExecuteEvent() == EVENT_NEXT_PORTAL) + { + ++mRiftPortalCount; + DoUpdateWorldState(WORLD_STATE_BM_RIFT, mRiftPortalCount); + DoSpawnPortal(); + Events.ScheduleEvent(EVENT_NEXT_PORTAL, RiftWaves[GetRiftWaveId()].NextPortalTime); + } + } + + protected: + EventMap Events; + }; + +}; + +void AddSC_instance_the_black_morass() +{ + new instance_the_black_morass(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp new file mode 100644 index 00000000000..d27b4b330b4 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.cpp @@ -0,0 +1,422 @@ +/* + * 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 + * 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 . + */ + +/* +Name: The_Black_Morass +%Complete: 30 +Comment: Misc NPC's and mobs for instance. Most here far from complete. +Category: Caverns of Time, The Black Morass +*/ + +/* ContentData +npc_medivh_bm +npc_time_rift +npc_saat +EndContentData */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "the_black_morass.h" +#include "Player.h" +#include "SpellInfo.h" + +enum MedivhBm +{ + SAY_ENTER = 0, //where does this belong? + SAY_INTRO = 1, + SAY_WEAK75 = 2, + SAY_WEAK50 = 3, + SAY_WEAK25 = 4, + SAY_DEATH = 5, + SAY_WIN = 6, + SAY_ORCS_ENTER = 7, + SAY_ORCS_ANSWER = 8, + + SPELL_CHANNEL = 31556, + SPELL_PORTAL_RUNE = 32570, //aura(portal on ground effect) + + SPELL_BLACK_CRYSTAL = 32563, //aura + SPELL_PORTAL_CRYSTAL = 32564, //summon + + SPELL_BANISH_PURPLE = 32566, //aura + SPELL_BANISH_GREEN = 32567, //aura + + SPELL_CORRUPT = 31326, + SPELL_CORRUPT_AEONUS = 37853, + + C_COUNCIL_ENFORCER = 17023 +}; + +class npc_medivh_bm : public CreatureScript +{ +public: + npc_medivh_bm() : CreatureScript("npc_medivh_bm") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_medivh_bmAI (creature); + } + + struct npc_medivh_bmAI : public ScriptedAI + { + npc_medivh_bmAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } + + InstanceScript* instance; + + uint32 SpellCorrupt_Timer; + uint32 Check_Timer; + + bool Life75; + bool Life50; + bool Life25; + + void Reset() + { + SpellCorrupt_Timer = 0; + + if (!instance) + return; + + if (instance->GetData(TYPE_MEDIVH) == IN_PROGRESS) + DoCast(me, SPELL_CHANNEL, true); + else if (me->HasAura(SPELL_CHANNEL)) + me->RemoveAura(SPELL_CHANNEL); + + DoCast(me, SPELL_PORTAL_RUNE, true); + } + + void MoveInLineOfSight(Unit* who) + { + if (!instance) + return; + + if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 10.0f)) + { + if (instance->GetData(TYPE_MEDIVH) == IN_PROGRESS || instance->GetData(TYPE_MEDIVH) == DONE) + return; + + Talk(SAY_INTRO); + instance->SetData(TYPE_MEDIVH, IN_PROGRESS); + DoCast(me, SPELL_CHANNEL, false); + Check_Timer = 5000; + } + else if (who->GetTypeId() == TYPEID_UNIT && me->IsWithinDistInMap(who, 15.0f)) + { + if (instance->GetData(TYPE_MEDIVH) != IN_PROGRESS) + return; + + uint32 entry = who->GetEntry(); + if (entry == NPC_INFINITE_ASSASIN || entry == NPC_INFINITE_WHELP || entry == NPC_INFINITE_CRONOMANCER || entry == NPC_INFINITE_EXECUTIONER || entry == NPC_INFINITE_VANQUISHER) + { + who->StopMoving(); + who->CastSpell(me, SPELL_CORRUPT, false); + } + else if (entry == NPC_AEONUS) + { + who->StopMoving(); + who->CastSpell(me, SPELL_CORRUPT_AEONUS, false); + } + } + } + + void AttackStart(Unit* /*who*/) + { + //if (instance && instance->GetData(TYPE_MEDIVH) == IN_PROGRESS) + //return; + + //ScriptedAI::AttackStart(who); + } + + void EnterCombat(Unit* /*who*/) {} + + void SpellHit(Unit* /*caster*/, const SpellInfo* spell) + { + if (SpellCorrupt_Timer) + return; + + if (spell->Id == SPELL_CORRUPT_AEONUS) + SpellCorrupt_Timer = 1000; + + if (spell->Id == SPELL_CORRUPT) + SpellCorrupt_Timer = 3000; + } + + void JustDied(Unit* killer) + { + if (killer->GetEntry() == me->GetEntry()) + return; + + Talk(SAY_DEATH); + } + + void UpdateAI(uint32 diff) + { + if (!instance) + return; + + if (SpellCorrupt_Timer) + { + if (SpellCorrupt_Timer <= diff) + { + instance->SetData(TYPE_MEDIVH, SPECIAL); + + if (me->HasAura(SPELL_CORRUPT_AEONUS)) + SpellCorrupt_Timer = 1000; + else if (me->HasAura(SPELL_CORRUPT)) + SpellCorrupt_Timer = 3000; + else + SpellCorrupt_Timer = 0; + } else SpellCorrupt_Timer -= diff; + } + + if (Check_Timer) + { + if (Check_Timer <= diff) + { + uint32 pct = instance->GetData(DATA_SHIELD); + + Check_Timer = 5000; + + if (Life25 && pct <= 25) + { + Talk(SAY_WEAK25); + Life25 = false; + } + else if (Life50 && pct <= 50) + { + Talk(SAY_WEAK50); + Life50 = false; + } + else if (Life75 && pct <= 75) + { + Talk(SAY_WEAK75); + Life75 = false; + } + + //if we reach this it means event was running but at some point reset. + if (instance->GetData(TYPE_MEDIVH) == NOT_STARTED) + { + me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + me->RemoveCorpse(); + me->Respawn(); + return; + } + + if (instance->GetData(TYPE_RIFT) == DONE) + { + Talk(SAY_WIN); + Check_Timer = 0; + + if (me->HasAura(SPELL_CHANNEL)) + me->RemoveAura(SPELL_CHANNEL); + + /// @todo start the post-event here + instance->SetData(TYPE_MEDIVH, DONE); + } + } else Check_Timer -= diff; + } + + //if (!UpdateVictim()) + //return; + + //DoMeleeAttackIfReady(); + } + }; + +}; + +struct Wave +{ + uint32 PortalMob[4]; //spawns for portal waves (in order) +}; + +static Wave PortalWaves[]= +{ + { {NPC_INFINITE_ASSASIN, NPC_INFINITE_WHELP, NPC_INFINITE_CRONOMANCER, 0} }, + { {NPC_INFINITE_EXECUTIONER, NPC_INFINITE_CRONOMANCER, NPC_INFINITE_WHELP, NPC_INFINITE_ASSASIN} }, + { {NPC_INFINITE_EXECUTIONER, NPC_INFINITE_VANQUISHER, NPC_INFINITE_CRONOMANCER, NPC_INFINITE_ASSASIN} } +}; + +class npc_time_rift : public CreatureScript +{ +public: + npc_time_rift() : CreatureScript("npc_time_rift") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_time_riftAI (creature); + } + + struct npc_time_riftAI : public ScriptedAI + { + npc_time_riftAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } + + InstanceScript* instance; + + uint32 TimeRiftWave_Timer; + uint8 mRiftWaveCount; + uint8 mPortalCount; + uint8 mWaveId; + + void Reset() + { + + TimeRiftWave_Timer = 15000; + mRiftWaveCount = 0; + + if (!instance) + return; + + mPortalCount = instance->GetData(DATA_PORTAL_COUNT); + + if (mPortalCount < 6) + mWaveId = 0; + else if (mPortalCount > 12) + mWaveId = 2; + else mWaveId = 1; + + } + void EnterCombat(Unit* /*who*/) {} + + void DoSummonAtRift(uint32 creature_entry) + { + if (!creature_entry) + return; + + if (instance && instance->GetData(TYPE_MEDIVH) != IN_PROGRESS) + { + me->InterruptNonMeleeSpells(true); + me->RemoveAllAuras(); + return; + } + + Position pos; + me->GetRandomNearPosition(pos, 10.0f); + + //normalize Z-level if we can, if rift is not at ground level. + pos.m_positionZ = std::max(me->GetMap()->GetHeight(pos.m_positionX, pos.m_positionY, MAX_HEIGHT), me->GetMap()->GetWaterLevel(pos.m_positionX, pos.m_positionY)); + + if (Unit* Summon = DoSummon(creature_entry, pos, 30000, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT)) + if (Unit* temp = Unit::GetUnit(*me, instance ? instance->GetData64(DATA_MEDIVH) : 0)) + Summon->AddThreat(temp, 0.0f); + } + + void DoSelectSummon() + { + if ((mRiftWaveCount > 2 && mWaveId < 1) || mRiftWaveCount > 3) + mRiftWaveCount = 0; + + uint32 entry = 0; + + entry = PortalWaves[mWaveId].PortalMob[mRiftWaveCount]; + TC_LOG_DEBUG(LOG_FILTER_TSCR, "npc_time_rift: summoning wave Creature (Wave %u, Entry %u).", mRiftWaveCount, entry); + + ++mRiftWaveCount; + + if (entry == NPC_INFINITE_WHELP) + { + for (uint8 i = 0; i < 3; ++i) + DoSummonAtRift(entry); + } else DoSummonAtRift(entry); + } + + void UpdateAI(uint32 diff) + { + if (!instance) + return; + + if (TimeRiftWave_Timer <= diff) + { + DoSelectSummon(); + TimeRiftWave_Timer = 15000; + } else TimeRiftWave_Timer -= diff; + + if (me->IsNonMeleeSpellCasted(false)) + return; + + TC_LOG_DEBUG(LOG_FILTER_TSCR, "npc_time_rift: not casting anylonger, i need to die."); + me->setDeathState(JUST_DIED); + + if (instance->GetData(TYPE_RIFT) == IN_PROGRESS) + instance->SetData(TYPE_RIFT, SPECIAL); + } + }; + +}; + +enum Saat +{ + SPELL_CHRONO_BEACON = 34975, + ITEM_CHRONO_BEACON = 24289 +}; + +#define GOSSIP_ITEM_OBTAIN "[PH] Obtain Chrono-Beacon" + +class npc_saat : public CreatureScript +{ +public: + npc_saat() : CreatureScript("npc_saat") { } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) + { + player->PlayerTalkClass->ClearMenus(); + if (action == GOSSIP_ACTION_INFO_DEF+1) + { + player->CLOSE_GOSSIP_MENU(); + creature->CastSpell(player, SPELL_CHRONO_BEACON, false); + } + return true; + } + + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->IsQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(ITEM_CHRONO_BEACON)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_OBTAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(10000, creature->GetGUID()); + return true; + } + else if (player->GetQuestRewardStatus(QUEST_OPENING_PORTAL) && !player->HasItemCount(ITEM_CHRONO_BEACON)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_OBTAIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(10001, creature->GetGUID()); + return true; + } + + player->SEND_GOSSIP_MENU(10002, creature->GetGUID()); + return true; + } + +}; + +void AddSC_the_black_morass() +{ + new npc_medivh_bm(); + new npc_time_rift(); + new npc_saat(); +} diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h new file mode 100644 index 00000000000..729eb42e9c5 --- /dev/null +++ b/src/server/scripts/Kalimdor/CavernsOfTime/TheBlackMorass/the_black_morass.h @@ -0,0 +1,67 @@ +/* + * 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 + * 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 DEF_THEBLACKMORASS_H +#define DEF_THEBLACKMORASS_H + +uint32 const EncounterCount = 2; + +enum DataTypes +{ + TYPE_MEDIVH = 1, + TYPE_RIFT = 2, + TYPE_AEONUS = 3, + TYPE_TEMPORUS = 4, + TYPE_CRONO_LORD_DEJA = 5, + DATA_MEDIVH = 10, + DATA_PORTAL_COUNT = 11, + DATA_SHIELD = 12 +}; + +enum WorldStateIds +{ + WORLD_STATE_BM = 2541, + WORLD_STATE_BM_SHIELD = 2540, + WORLD_STATE_BM_RIFT = 2784 +}; + +enum QuestIds +{ + QUEST_OPENING_PORTAL = 10297, + QUEST_MASTER_TOUCH = 9836 +}; + +enum CreatureIds +{ + NPC_MEDIVH = 15608, + NPC_TIME_RIFT = 17838, + NPC_TIME_KEEPER = 17918, + NPC_RIFT_KEEPER = 21104, + NPC_RIFT_LORD = 17839, + NPC_CRONO_LORD_DEJA = 17879, + NPC_TEMPORUS = 17880, + NPC_AEONUS = 17881, + NPC_INFINITE_ASSASIN = 17835, + NPC_INFINITE_WHELP = 21818, + NPC_INFINITE_CRONOMANCER = 17892, + NPC_INFINITE_EXECUTIONER = 18994, + NPC_INFINITE_VANQUISHER = 18995 +}; + +#endif + -- cgit v1.2.3