aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/ScriptLoader.cpp10
-rw-r--r--src/scripts/CMakeLists.txt4
-rw-r--r--src/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp209
-rw-r--r--src/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp482
-rw-r--r--src/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp273
-rw-r--r--src/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp159
-rw-r--r--src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp1101
-rw-r--r--src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h43
8 files changed, 2228 insertions, 53 deletions
diff --git a/src/game/ScriptLoader.cpp b/src/game/ScriptLoader.cpp
index 8e2eed1e2b5..43cb3fef3cf 100644
--- a/src/game/ScriptLoader.cpp
+++ b/src/game/ScriptLoader.cpp
@@ -388,6 +388,11 @@ void AddSC_boss_xevozz();
void AddSC_boss_zuramat();
void AddSC_instance_violet_hold();
void AddSC_violet_hold();
+void AddSC_instance_pit_of_saron(); //Pit of Saron
+void AddSC_pit_of_saron();
+void AddSC_boss_garfrost();
+void AddSC_boss_ick();
+void AddSC_boss_tyrannus();
void AddSC_dalaran();
void AddSC_borean_tundra();
@@ -868,6 +873,11 @@ void AddScripts()
AddSC_boss_zuramat();
AddSC_instance_violet_hold();
AddSC_violet_hold();
+ AddSC_instance_pit_of_saron(); //Pit of Saron
+ AddSC_pit_of_saron();
+ AddSC_boss_garfrost();
+ AddSC_boss_ick();
+ AddSC_boss_tyrannus();
AddSC_dalaran();
AddSC_borean_tundra();
diff --git a/src/scripts/CMakeLists.txt b/src/scripts/CMakeLists.txt
index c5e917923f3..5d8e71166a3 100644
--- a/src/scripts/CMakeLists.txt
+++ b/src/scripts/CMakeLists.txt
@@ -336,7 +336,11 @@ SET(scripts_STAT_SRCS
northrend/frozen_halls/forge_of_souls/forge_of_souls.h
northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h
+ northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp
+ northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp
+ northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp
northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp
+ northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp
northrend/frozen_halls/pit_of_saron/pit_of_saron.h
northrend/gundrak/instance_gundrak.cpp
northrend/gundrak/boss_slad_ran.cpp
diff --git a/src/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp b/src/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp
new file mode 100644
index 00000000000..2e30f4375d7
--- /dev/null
+++ b/src/scripts/northrend/frozen_halls/pit_of_saron/boss_forgemaster_garfrost.cpp
@@ -0,0 +1,209 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1658001,
+ SAY_SLAY_1 = -1658002,
+ SAY_SLAY_2 = -1658003,
+ SAY_DEATH = -1658004,
+ SAY_PHASE2 = -1658005,
+ SAY_PHASE3 = -1658006,
+
+ SAY_TYRANNUS_DEATH = -1659007,
+};
+
+enum eEvents
+{
+ EVENT_NONE,
+ EVENT_PERMAFROST,
+ EVENT_THROW_SARONITE,
+ EVENT_CHILLINGWAVE,
+ EVENT_DEEPFREEZE,
+};
+
+enum Spells
+{
+ SPELL_PERMAFROST = 70326,
+ SPELL_PERMAFROST_TRIGGER = 68786, // triggered by PERMAFROST. Used to check aura
+ SPELL_THROW_SARONITE = 68788,
+ SPELL_THUNDERING_STOMP = 68771,
+ SPELL_CHILLING_WAVE = 68778,
+ H_SPELL_CHILLING_WAVE = 70333,
+ SPELL_DEEP_FREEZE = 70381,
+ H_SPELL_DEEP_FREEZE = 72930,
+ SPELL_FORGE_MACE = 68785,
+ H_SPELL_FORGE_MACE = 70335,
+ SPELL_FORGE_BLADE = 68774,
+ H_SPELL_FORGE_BLADE = 70334,
+};
+
+enum eEnums
+{
+ EQUIP_ID_SWORD = 49345,
+ EQUIP_ID_MACE = 49344,
+ ACHIEV_DOESNT_GO_TO_ELEVEN = 4524,
+};
+
+struct boss_garfrostAI : public ScriptedAI
+{
+ boss_garfrostAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ bool phase2;
+ bool phase3;
+ bool bAchievement;
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ phase2 = false;
+ phase3 = false;
+ bAchievement = true;
+
+ if (pInstance)
+ pInstance->SetData(DATA_GARFROST_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ DoCast(m_creature, SPELL_PERMAFROST);
+
+ if (pInstance)
+ pInstance->SetData(DATA_GARFROST_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_THROW_SARONITE, 45000);
+ }
+
+ void DamageTaken(Unit* pDoneBy, uint32& uiDamage)
+ {
+ if (HealthBelowPct(66) && !phase2)
+ {
+ phase2 = true;
+ DoCast(m_creature, SPELL_THUNDERING_STOMP);
+ // TODO: should go to a forge
+ DoCast(m_creature, DUNGEON_MODE(SPELL_FORGE_BLADE, H_SPELL_FORGE_BLADE));
+ // TODO: should equip when spell completes
+ SetEquipmentSlots(false, EQUIP_ID_SWORD, -1, -1);
+ m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ events.ScheduleEvent(EVENT_CHILLINGWAVE, 10000);
+ }
+
+ if (HealthBelowPct(33) && !phase3)
+ {
+ phase3 = true;
+ DoCast(m_creature, SPELL_THUNDERING_STOMP);
+ // TODO: should go to a forge
+ DoCast(m_creature, DUNGEON_MODE(SPELL_FORGE_MACE, H_SPELL_FORGE_MACE));
+ // TODO: should equip when spell completes
+ SetEquipmentSlots(false, EQUIP_ID_MACE, -1, -1);
+ m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ events.CancelEvent(EVENT_CHILLINGWAVE); // cast only in phase 2.
+ events.ScheduleEvent(EVENT_DEEPFREEZE, 10000);
+ }
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+ if (pInstance)
+ {
+ if (Creature *pTyrannus = m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_TYRANNUS)))
+ DoScriptText(SAY_TYRANNUS_DEATH, pTyrannus);
+
+ pInstance->SetData(DATA_GARFROST_EVENT, DONE);
+ if (IsHeroic() && bAchievement)
+ pInstance->DoCompleteAchievement(ACHIEV_DOESNT_GO_TO_ELEVEN);
+ }
+ }
+
+ void SpellHitTarget(Unit* pTarget, const SpellEntry *spell)
+ {
+ if (spell->Id == SPELL_PERMAFROST_TRIGGER && bAchievement)
+ {
+ if (Aura *pAura = pTarget->GetAura(SPELL_PERMAFROST_TRIGGER))
+ if (pAura->GetStackAmount() > 10)
+ bAchievement = false;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_THROW_SARONITE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_THROW_SARONITE);
+ events.RescheduleEvent(EVENT_THROW_SARONITE, 35000);
+ return;
+ case EVENT_DEEPFREEZE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, DUNGEON_MODE(SPELL_DEEP_FREEZE, H_SPELL_DEEP_FREEZE));
+ events.RescheduleEvent(EVENT_DEEPFREEZE, 35000);
+ return;
+ case EVENT_CHILLINGWAVE:
+ DoCastAOE(DUNGEON_MODE(SPELL_CHILLING_WAVE, H_SPELL_CHILLING_WAVE));
+ events.RescheduleEvent(EVENT_CHILLINGWAVE, 40000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_garfrost(Creature* pCreature)
+{
+ return new boss_garfrostAI (pCreature);
+}
+
+void AddSC_boss_garfrost()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_garfrost";
+ newscript->GetAI = &GetAI_boss_garfrost;
+ newscript->RegisterSelf();
+}
diff --git a/src/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp b/src/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp
new file mode 100644
index 00000000000..d07930449a2
--- /dev/null
+++ b/src/scripts/northrend/frozen_halls/pit_of_saron/boss_krickandick.cpp
@@ -0,0 +1,482 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+/*
+ * SDComment: Spell Explosive barrage is not working.
+ */
+
+enum Spells
+{
+ SPELL_PURSUED = 68987,
+ SPELL_CONFUSION = 69029,
+ SPELL_EXPLOSIVE_BARRAGE = 69263,
+ SPELL_MIGHTY_KICK = 69021,
+ SPELL_POISON_NOVA = 68989,
+ H_SPELL_POISON_NOVA = 70434,
+ SPELL_SHADOW_BOLT = 69028,
+ SPELL_TOXIC_WASTE = 69024,
+ H_SPELL_TOXIC_WASTE = 70436,
+};
+
+enum Yells
+{
+ // Krick
+ SAY_KRICK_AGGRO = -1658010,
+ SAY_KRICK_SLAY_1 = -1658011,
+ SAY_KRICK_SLAY_2 = -1658012,
+ SAY_KRICK_BARRAGE_1 = -1658013,
+ SAY_KRICK_BARRAGE_2 = -1658014,
+ SAY_KRICK_POISON_NOVA = -1658015,
+ SAY_KRICK_CHASE_1 = -1658016,
+ SAY_KRICK_CHASE_2 = -1658017,
+ SAY_KRICK_CHASE_3 = -1658018,
+
+ // Ick
+ SAY_ICK_POISON_NOVA = -1658020,
+ SAY_ICK_CHASE_1 = -1658021,
+
+ // OUTRO
+ SAY_KRICK_OUTRO_1 = -1658030,
+ SAY_JAYNA_OUTRO_2 = -1658031,
+ SAY_SYLVANAS_OUTRO_2 = -1658032,
+ SAY_KRICK_OUTRO_3 = -1658033,
+ SAY_JAYNA_OUTRO_4 = -1658034,
+ SAY_SYLVANAS_OUTRO_4 = -1658035,
+ SAY_KRICK_OUTRO_5 = -1658036,
+ SAY_TYRANNUS_OUTRO_7 = -1658037,
+ SAY_KRICK_OUTRO_8 = -1658038,
+ SAY_TYRANNUS_OUTRO_9 = -1658039,
+ SAY_JAYNA_OUTRO_10 = -1658040,
+ SAY_SYLVANAS_OUTRO_10 = -1658041,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_PURSUE,
+ EVENT_MIGHTY_KICK,
+ EVENT_POISON_NOVA,
+ EVENT_EXPLOSIVE_BARRAGE,
+ EVENT_END_EXPLOSIVE_BARRAGE,
+
+ // Krick
+ EVENT_SHADOW_BOLT,
+ EVENT_TOXIC_WASTE,
+
+ // Krick OUTRO
+ EVENT_OUTRO_1,
+ EVENT_OUTRO_2,
+ EVENT_OUTRO_3,
+ EVENT_OUTRO_4,
+ EVENT_OUTRO_5,
+ EVENT_OUTRO_6,
+ EVENT_OUTRO_7,
+ EVENT_OUTRO_8,
+ EVENT_OUTRO_9,
+ EVENT_OUTRO_10,
+ EVENT_OUTRO_11,
+ EVENT_OUTRO_12,
+ EVENT_OUTRO_END,
+};
+
+enum KrickPhase
+{
+ PHASE_COMBAT,
+ PHASE_OUTRO,
+};
+
+enum Actions
+{
+ ACTION_OUTRO,
+};
+
+enum Misc
+{
+ SEAT_KRICK = 0,
+
+ // events GCD. Shall not be 0.
+ GCD_1 = 1,
+};
+
+// Krick is the Gnome.
+// Ick is the Mount
+// Common Events are handled/triggered by Ick that "drive" Krick through DoAction.
+
+struct boss_ickAI : public ScriptedAI
+{
+ boss_ickAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRICKANDICK_EVENT, NOT_STARTED);
+ }
+
+ Creature* GetKrick()
+ {
+ return m_creature->GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_KRICK) : 0);
+ }
+
+ void EnterCombat(Unit *pWho)
+ {
+ if (pInstance)
+ pInstance->SetData(DATA_KRICKANDICK_EVENT, IN_PROGRESS);
+
+ Creature* pKrick = GetKrick();
+ if (!pKrick)
+ pKrick = m_creature->SummonCreature(CREATURE_KRICK, *m_creature, TEMPSUMMON_MANUAL_DESPAWN);
+
+ if (pKrick)
+ DoScriptText(SAY_KRICK_AGGRO, pKrick);
+
+ events.ScheduleEvent(EVENT_MIGHTY_KICK, 20000, GCD_1);
+ events.ScheduleEvent(EVENT_PURSUE, 30000, GCD_1);
+ events.ScheduleEvent(EVENT_POISON_NOVA, 30000, GCD_1);
+ events.ScheduleEvent(EVENT_EXPLOSIVE_BARRAGE, 35000);
+ events.ScheduleEvent(EVENT_TOXIC_WASTE, 5000);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
+ }
+
+ void EnterEvadeMode()
+ {
+ m_creature->GetMotionMaster()->Clear();
+ ScriptedAI::EnterEvadeMode();
+ }
+
+ void JustDied(Unit* pKiller)
+ {
+ if (Creature* pKrick = GetKrick())
+ {
+ if (pKrick->AI())
+ pKrick->AI()->DoAction(ACTION_OUTRO);
+ }
+
+ if (pInstance)
+ pInstance->SetData(DATA_KRICKANDICK_EVENT, DONE);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->isInCombat())
+ return;
+
+ if (!m_creature->getVictim() && m_creature->getThreatManager().isThreatListEmpty())
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ switch(events.ExecuteEvent())
+ {
+ case EVENT_PURSUE:
+ if (Creature* pKrick = GetKrick())
+ DoScriptText(RAND(SAY_KRICK_CHASE_1,SAY_KRICK_CHASE_2,SAY_KRICK_CHASE_3), pKrick);
+
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ m_creature->Attack(pTarget,false);
+ DoScriptText(SAY_ICK_CHASE_1, m_creature, pTarget);
+ DoCast(pTarget, SPELL_PURSUED);
+ }
+
+ DoCast(SPELL_CONFUSION);
+ events.ScheduleEvent(EVENT_PURSUE, 30000, GCD_1);
+ return;
+
+ case EVENT_MIGHTY_KICK:
+ DoCast(m_creature->getVictim(), SPELL_MIGHTY_KICK);
+ events.ScheduleEvent(EVENT_MIGHTY_KICK, 25000, GCD_1);
+ return;
+
+ case EVENT_POISON_NOVA:
+ if (Creature* pKrick = GetKrick())
+ DoScriptText(SAY_KRICK_POISON_NOVA, pKrick);
+
+ DoScriptText(SAY_ICK_POISON_NOVA, m_creature);
+ DoCastAOE(DUNGEON_MODE(SPELL_POISON_NOVA,H_SPELL_POISON_NOVA));
+ events.ScheduleEvent(EVENT_POISON_NOVA, 30000, GCD_1);
+ return;
+
+ case EVENT_TOXIC_WASTE:
+ DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_TOXIC_WASTE,H_SPELL_TOXIC_WASTE));
+ events.ScheduleEvent(EVENT_TOXIC_WASTE, 5000);
+ return;
+
+ case EVENT_SHADOW_BOLT:
+ DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 15000);
+ return;
+
+ case EVENT_EXPLOSIVE_BARRAGE:
+ if (Creature *pKrick = GetKrick())
+ {
+ DoScriptText(SAY_KRICK_BARRAGE_1, pKrick);
+ DoScriptText(SAY_KRICK_BARRAGE_2, pKrick);
+ }
+
+ DoCastAOE(SPELL_EXPLOSIVE_BARRAGE);
+ m_creature->GetMotionMaster()->MoveIdle();
+ events.DelayEvents(20000, GCD_1); // 2 sec cast + 18 sec
+ events.ScheduleEvent(EVENT_END_EXPLOSIVE_BARRAGE, 20000);
+ return;
+
+ case EVENT_END_EXPLOSIVE_BARRAGE:
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
+ events.ScheduleEvent(EVENT_EXPLOSIVE_BARRAGE, 25000);
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct boss_krickAI : public ScriptedAI
+{
+ boss_krickAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ KrickPhase phase;
+ uint64 uiNpcOutroDialog;
+ uint64 uiTyrannus;
+
+ void Reset()
+ {
+ uiNpcOutroDialog = 0;
+ uiTyrannus = 0;
+ phase = PHASE_COMBAT;
+
+ m_creature->SetReactState(REACT_PASSIVE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ }
+
+ Creature* GetIck()
+ {
+ return m_creature->GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_ICK) : 0);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if (victim == m_creature)
+ return;
+
+ DoScriptText(RAND(SAY_KRICK_SLAY_1,SAY_KRICK_SLAY_2), m_creature);
+ }
+
+ void DamageTaken(Unit *pDoneBy, uint32 &uiDamage)
+ {
+ // if killed whatever the reason, it breaks the outro
+ uiDamage = 0;
+ }
+
+ void DoAction(const int32 actionId)
+ {
+ switch(actionId)
+ {
+ case ACTION_OUTRO:
+ {
+ Position pos;
+ if (Creature* pIck = GetIck())
+ {
+ // TODO: tele on Ick then run some distance.
+ pIck->GetNearPosition(pos, 5.0f, 3.14);
+ m_creature->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), 0.0f);
+ }
+ m_creature->SetVisibility(VISIBILITY_ON);
+
+ Creature* pJainaOrSylvanas = m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_JAINA_SYLVANAS_1));
+ if (pJainaOrSylvanas) {
+ Position pos;
+ m_creature->GetNearPosition(pos, 5.0f, 0);
+ pJainaOrSylvanas->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(),
+ pos.GetAngle(m_creature->GetPositionX(), m_creature->GetPositionY()));
+ }
+ else {
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ pJainaOrSylvanas = m_creature->SummonCreature(NPC_SYLVANAS_PART1, *m_creature, TEMPSUMMON_MANUAL_DESPAWN);
+ else
+ pJainaOrSylvanas = m_creature->SummonCreature(NPC_JAINA_PART1, *m_creature, TEMPSUMMON_MANUAL_DESPAWN);
+ }
+
+ if (pJainaOrSylvanas)
+ {
+ pJainaOrSylvanas->SetOrientation(pJainaOrSylvanas->GetAngle(m_creature->GetPositionX(), m_creature->GetPositionY()));
+ m_creature->SetOrientation(m_creature->GetAngle(pJainaOrSylvanas->GetPositionX(), pJainaOrSylvanas->GetPositionY()));
+ uiNpcOutroDialog = pJainaOrSylvanas->GetGUID();
+ }
+
+ phase = PHASE_OUTRO;
+ events.Reset();
+ events.ScheduleEvent(EVENT_OUTRO_1, 1000);
+ break;
+ }
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (phase == PHASE_OUTRO)
+ {
+ if (!pInstance)
+ return;
+
+ events.Update(diff);
+ switch(events.ExecuteEvent())
+ {
+ case EVENT_OUTRO_1:
+ {
+ DoScriptText(SAY_KRICK_OUTRO_1, m_creature);
+ events.ScheduleEvent(EVENT_OUTRO_2, 14000);
+ break;
+ }
+ case EVENT_OUTRO_2:
+ {
+ Creature* pNpcDialog = m_creature->GetCreature(*m_creature, uiNpcOutroDialog);
+ if (pNpcDialog)
+ {
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_2, pNpcDialog);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_2, pNpcDialog);
+ }
+ events.ScheduleEvent(EVENT_OUTRO_3, 8500);
+ break;
+ }
+ case EVENT_OUTRO_3:
+ DoScriptText(SAY_KRICK_OUTRO_3, m_creature);
+ events.ScheduleEvent(EVENT_OUTRO_4, 12000);
+ break;
+ case EVENT_OUTRO_4:
+ {
+ Creature* pNpcDialog = m_creature->GetCreature(*m_creature, uiNpcOutroDialog);
+ if (pNpcDialog)
+ {
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_4, pNpcDialog);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_4, pNpcDialog);
+ }
+ events.ScheduleEvent(EVENT_OUTRO_5, 8000);
+ break;
+ }
+ case EVENT_OUTRO_5:
+ DoScriptText(SAY_KRICK_OUTRO_5, m_creature);
+ events.ScheduleEvent(EVENT_OUTRO_6, 4000);
+ break;
+ case EVENT_OUTRO_6:
+ // TODO spawn Tyrannus at some distance and MovePoint near-by (flying on rimefang)
+ // store uiTyrannus
+ // Adjust timer so tyrannus has time to come
+ uiTyrannus = (pInstance ? pInstance->GetData64(DATA_TYRANNUS) : 0);
+ events.ScheduleEvent(EVENT_OUTRO_7, 1);
+ break;
+ case EVENT_OUTRO_7:
+ if (Creature *pTyrannus = m_creature->GetCreature(*m_creature, uiTyrannus))
+ DoScriptText(SAY_TYRANNUS_OUTRO_7, pTyrannus);
+ events.ScheduleEvent(EVENT_OUTRO_8, 7000);
+ break;
+ case EVENT_OUTRO_8:
+ DoScriptText(SAY_KRICK_OUTRO_8, m_creature);
+ // TODO: Tyrannus starts killing Krick.
+ // there shall be some visual spell effect
+ events.ScheduleEvent(EVENT_OUTRO_9, 6000);
+ break;
+ case EVENT_OUTRO_9:
+ // tyrannus kills krick
+ m_creature->SetStandState(UNIT_STAND_STATE_DEAD);
+ m_creature->SetHealth(0);
+
+ if (Creature *pTyrannus = m_creature->GetCreature(*m_creature, uiTyrannus))
+ DoScriptText(SAY_TYRANNUS_OUTRO_9, pTyrannus);
+
+ events.ScheduleEvent(EVENT_OUTRO_10, 12000);
+ break;
+ case EVENT_OUTRO_10:
+ {
+ Creature* pNpcDialog = m_creature->GetCreature(*m_creature, uiNpcOutroDialog);
+ if (pNpcDialog)
+ {
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == TEAM_ALLIANCE)
+ DoScriptText(SAY_JAYNA_OUTRO_10, pNpcDialog);
+ else
+ DoScriptText(SAY_SYLVANAS_OUTRO_10, pNpcDialog);
+ }
+
+ // End of OUTRO. for now...
+ events.ScheduleEvent(EVENT_OUTRO_END, 8000);
+ break;
+ }
+ case EVENT_OUTRO_END:
+ {
+ Creature* pNpcDialog = m_creature->GetCreature(*m_creature, uiNpcOutroDialog);
+ if (pNpcDialog)
+ pNpcDialog->DisappearAndDie();
+
+ m_creature->DisappearAndDie();
+ break;
+ }
+ }
+ return;
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_ick(Creature* pCreature)
+{
+ return new boss_ickAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_krick(Creature* pCreature)
+{
+ return new boss_krickAI(pCreature);
+}
+
+void AddSC_boss_ick()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name = "boss_ick";
+ newscript->GetAI = &GetAI_boss_ick;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "boss_krick";
+ newscript->GetAI = &GetAI_boss_krick;
+ newscript->RegisterSelf();
+}
diff --git a/src/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp b/src/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp
new file mode 100644
index 00000000000..86aceb57ea2
--- /dev/null
+++ b/src/scripts/northrend/frozen_halls/pit_of_saron/boss_scourgelord_tyrannus.cpp
@@ -0,0 +1,273 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+/*
+ * SDComment: TODO:
+ * - implement aura for spell Overlord Brand.
+ * - Intro/Outro
+ * - improve script of Rimefang
+ */
+
+enum Yells
+{
+ SAY_AMBUSH_1 = -1658050,
+ SAY_AMBUSH_2 = -1658051,
+ SAY_GAUNTLET_START = -1658052,
+ SAY_INTRO_1 = -1658053,
+ SAY_INTRO_2 = -1658054,
+
+ SAY_AGGRO = -1658055,
+ SAY_SLAY_1 = -1658056,
+ SAY_SLAY_2 = -1658057,
+ SAY_DEATH = -1658058,
+ SAY_MARK_RIMEFANG_1 = -1658059,
+ SAY_MARK_RIMEFANG_2 = -1658060,
+ SAY_DARK_MIGHT_1 = -1658061,
+ SAY_DARK_MIGHT_2 = -1658062,
+
+ SAY_GORKUN_OUTRO_1 = -1658063,
+ SAY_GORKUN_OUTRO_2 = -1658064,
+ SAY_JAYNA_OUTRO_3 = -1658065,
+ SAY_SYLVANAS_OUTRO_3 = -1658066,
+ SAY_JAYNA_OUTRO_4 = -1658067,
+ SAY_SYLVANAS_OUTRO_4 = -1658068,
+ SAY_JAYNA_OUTRO_5 = -1658069,
+};
+
+enum Spells
+{
+ SPELL_FORCEFUL_SMASH = 69155,
+ H_SPELL_FORCEFUL_SMASH = 69627,
+ SPELL_OVERLORDS_BRAND = 69172,
+ SPELL_DARK_MIGHT = 69167,
+ H_SPELL_DARK_MIGHT = 69629,
+ SPELL_HOARFROST = 69246,
+ SPELL_MARK_OF_RIMEFANG = 69275,
+ SPELL_ICY_BLAST = 69233,
+ H_SPELL_ICY_BLAST = 69646,
+ SPELL_ICY_BLAST_2 = 69238,
+ H_SPELL_ICY_BLAST_2 = 69628,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_FORCEFUL_SMASH,
+ EVENT_OVERLORDS_BRAND,
+ EVENT_DARK_MIGHT,
+
+ // Rimefang
+ EVENT_MARK_OF_RIMEFANG,
+ EVENT_HOARFROST,
+ EVENT_ICY_BLAST,
+ EVENT_ICY_BLAST_2,
+};
+
+enum Misc
+{
+ SEAT_TYRANNUS = 0
+};
+
+struct boss_tyrannusAI : public ScriptedAI
+{
+ boss_tyrannusAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_TYRANNUS_EVENT, NOT_STARTED);
+ }
+
+ Creature* GetRimefang()
+ {
+ return m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_RIMEFANG));
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, m_creature);
+ m_creature->ExitVehicle();
+
+ // restore health if any damage done during intro
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+
+ if (pInstance)
+ pInstance->SetData(DATA_TYRANNUS_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_FORCEFUL_SMASH, 10000);
+ events.ScheduleEvent(EVENT_OVERLORDS_BRAND, 35000);
+ events.ScheduleEvent(EVENT_DARK_MIGHT, 40000);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, m_creature);
+
+ if (pInstance)
+ {
+ pInstance->SetData(DATA_TYRANNUS_EVENT, DONE);
+ if (Creature* pRimefang = GetRimefang())
+ pRimefang->ForcedDespawn();
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FORCEFUL_SMASH:
+ DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_FORCEFUL_SMASH, H_SPELL_FORCEFUL_SMASH));
+ events.ScheduleEvent(EVENT_FORCEFUL_SMASH, 10000);
+ return;
+ case EVENT_OVERLORDS_BRAND:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_OVERLORDS_BRAND);
+ events.ScheduleEvent(EVENT_OVERLORDS_BRAND, 45000);
+ return;
+ case EVENT_DARK_MIGHT:
+ DoScriptText(SAY_DARK_MIGHT_1, m_creature);
+ DoScriptText(SAY_DARK_MIGHT_2, m_creature);
+ DoCast(m_creature, DUNGEON_MODE(SPELL_DARK_MIGHT, H_SPELL_DARK_MIGHT));
+ events.ScheduleEvent(EVENT_DARK_MIGHT, 60000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct boss_rimefangAI : public ScriptedAI
+{
+ boss_rimefangAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = c->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ EventMap events;
+
+ void Reset()
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ events.ScheduleEvent(EVENT_MARK_OF_RIMEFANG, 25000);
+ events.ScheduleEvent(EVENT_ICY_BLAST, 35000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_MARK_OF_RIMEFANG:
+ DoScriptText(SAY_MARK_RIMEFANG_1, m_creature);
+ DoScriptText(SAY_MARK_RIMEFANG_2, m_creature);
+
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_MARK_OF_RIMEFANG);
+ events.ScheduleEvent(EVENT_HOARFROST, 5000);
+ return;
+ case EVENT_HOARFROST:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_HOARFROST);
+ events.ScheduleEvent(EVENT_MARK_OF_RIMEFANG, 20000);
+ return;
+ case EVENT_ICY_BLAST:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, DUNGEON_MODE(SPELL_ICY_BLAST, H_SPELL_ICY_BLAST));
+ events.ScheduleEvent(EVENT_ICY_BLAST_2, 5000);
+ return;
+ case EVENT_ICY_BLAST_2:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget->getVictim(), DUNGEON_MODE(SPELL_ICY_BLAST_2, H_SPELL_ICY_BLAST_2));
+ events.ScheduleEvent(EVENT_ICY_BLAST, 30000);
+ return;
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_tyrannus(Creature* pCreature)
+{
+ return new boss_tyrannusAI(pCreature);
+}
+
+CreatureAI* GetAI_boss_rimefang(Creature* pCreature)
+{
+ return new boss_rimefangAI(pCreature);
+}
+
+void AddSC_boss_tyrannus()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_tyrannus";
+ newscript->GetAI = &GetAI_boss_tyrannus;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="boss_rimefang";
+ newscript->GetAI = &GetAI_boss_rimefang;
+ newscript->RegisterSelf();
+}
diff --git a/src/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp b/src/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp
index 908eaf8f669..8353af43608 100644
--- a/src/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp
+++ b/src/scripts/northrend/frozen_halls/pit_of_saron/instance_pit_of_saron.cpp
@@ -17,7 +17,7 @@
#include "ScriptedPch.h"
#include "pit_of_saron.h"
-#define MAX_ENCOUNTER 3
+#define MAX_ENCOUNTER 3
/* Pit of Saron encounters:
0- Forgemaster Garfrost
@@ -27,65 +27,135 @@
struct instance_pit_of_saron : public ScriptedInstance
{
- instance_pit_of_saron(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+ instance_pit_of_saron(Map* pMap) : ScriptedInstance(pMap) {};
- uint64 uiForgemaster;
uint64 uiKrick;
uint64 uiIck;
+ uint64 uiGarfrost;
uint64 uiTyrannus;
+ uint64 uiRimefang;
- uint32 m_auiEncounter[MAX_ENCOUNTER];
+ uint64 uiJainaOrSylvanas1;
+ uint64 uiJainaOrSylvanas2;
- void Initialize()
- {
- uiForgemaster = 0;
+ uint32 uiTeamInInstance;
+ uint32 uiEncounter[MAX_ENCOUNTER];
+
+ void Initialize()
+ {
+ for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ uiEncounter[i] = NOT_STARTED;
+
+ uiGarfrost = 0;
uiKrick = 0;
uiIck = 0;
uiTyrannus = 0;
-
+ }
+
+ bool IsEncounterInProgress() const
+ {
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- m_auiEncounter[i] = NOT_STARTED;
+ if (uiEncounter[i] == IN_PROGRESS)
+ return true;
+
+ return false;
}
void OnCreatureCreate(Creature* pCreature, bool add)
{
+ Map::PlayerList const &players = instance->GetPlayers();
+
+ if (!players.isEmpty())
+ {
+ if (Player* pPlayer = players.begin()->getSource())
+ uiTeamInInstance = pPlayer->GetTeam();
+ }
+
switch(pCreature->GetEntry())
{
- case CREATURE_FORGEMASTER:
- uiForgemaster = pCreature->GetGUID();
- break;
- case CREATURE_KRICK:
- uiKrick = pCreature->GetGUID();
+ case CREATURE_KRICK:
+ uiKrick = pCreature->GetGUID();
break;
+
case CREATURE_ICK:
uiIck = pCreature->GetGUID();
break;
- case CREATURE_TYRANNUS:
- uiTyrannus = pCreature->GetGUID();
- break;
+
+ case CREATURE_GARFROST:
+ uiGarfrost = pCreature->GetGUID();
+ break;
+
+ case CREATURE_TYRANNUS:
+ uiTyrannus = pCreature->GetGUID();
+ break;
+
+ case CREATURE_RIMEFANG:
+ uiRimefang = pCreature->GetGUID();
+ break;
+
+ case NPC_SYLVANAS_PART1:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_JAINA_PART1, ALLIANCE);
+ uiJainaOrSylvanas1 = pCreature->GetGUID();
+ break;
+ case NPC_SYLVANAS_PART2:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_JAINA_PART2, ALLIANCE);
+ uiJainaOrSylvanas2 = pCreature->GetGUID();
+ break;
+ case NPC_KILARA:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_ELANDRA, ALLIANCE);
+ break;
+ case NPC_KORALEN:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_KORLAEN, ALLIANCE);
+ break;
+ case NPC_CHAMPION_1_HORDE:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_CHAMPION_1_ALLIANCE, ALLIANCE);
+ break;
+ case NPC_CHAMPION_2_HORDE:
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_CHAMPION_2_ALLIANCE, ALLIANCE);
+ break;
+ case NPC_CHAMPION_3_HORDE: // No 3rd set for Alliance?
+ if (uiTeamInInstance == ALLIANCE)
+ pCreature->UpdateEntry(NPC_CHAMPION_2_ALLIANCE, ALLIANCE);
+ break;
}
}
-/*
- void OnGameObjectCreate(GameObject* pGo, bool add)
+
+ uint64 GetData64(uint32 identifier)
{
- switch(pGo->GetEntry())
+ switch(identifier)
{
+ case DATA_GARFROST: return uiGarfrost;
+ case DATA_KRICK: return uiKrick;
+ case DATA_ICK: return uiIck;
+ case DATA_TYRANNUS: return uiTyrannus;
+ case DATA_RIMEFANG: return uiRimefang;
+
+ case DATA_JAINA_SYLVANAS_1: return uiJainaOrSylvanas1;
+ case DATA_JAINA_SYLVANAS_2: return uiJainaOrSylvanas2;
}
+
+ return 0;
}
-*/
+
void SetData(uint32 type, uint32 data)
{
switch(type)
{
- case DATA_FORGEMASTER_EVENT:
- m_auiEncounter[0] = data;
+ case DATA_GARFROST_EVENT:
+ uiEncounter[0] = data;
+ break;
+ case DATA_TYRANNUS_EVENT:
+ uiEncounter[1] = data;
break;
case DATA_KRICKANDICK_EVENT:
- m_auiEncounter[1] = data;
+ uiEncounter[2] = data;
break;
- case DATA_TYRANNUS_EVENT:
- m_auiEncounter[2] = data;
- break;
}
if (data == DONE)
@@ -96,32 +166,27 @@ struct instance_pit_of_saron : public ScriptedInstance
{
switch(type)
{
- case DATA_FORGEMASTER_EVENT: return m_auiEncounter[0];
- case DATA_KRICKANDICK_EVENT: return m_auiEncounter[1];
- case DATA_TYRANNUS_EVENT: return m_auiEncounter[2];
+ case DATA_GARFROST_EVENT: return uiEncounter[0];
+ case DATA_TYRANNUS_EVENT: return uiEncounter[1];
+ case DATA_KRICKANDICK_EVENT: return uiEncounter[2];
}
return 0;
}
-/*
- uint64 GetData64(uint32 identifier)
- {
- switch(identifier)
- {
- }
- return 0;
- }
-*/
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
+ std::string str_data;
+
std::ostringstream saveStream;
- saveStream << "P S " << m_auiEncounter[0] << " " << m_auiEncounter[1] << m_auiEncounter[2];
+ saveStream << "P S " << uiEncounter[0] << " " << uiEncounter[1] << " " << uiEncounter[2];
+
+ str_data = saveStream.str();
OUT_SAVE_INST_DATA_COMPLETE;
- return saveStream.str();
+ return str_data;
}
void Load(const char* in)
@@ -142,13 +207,13 @@ struct instance_pit_of_saron : public ScriptedInstance
if (dataHead1 == 'P' && dataHead2 == 'S')
{
- m_auiEncounter[0] = data0;
- m_auiEncounter[1] = data1;
- m_auiEncounter[2] = data2;
+ uiEncounter[0] = data0;
+ uiEncounter[1] = data1;
+ uiEncounter[2] = data2;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS)
- m_auiEncounter[i] = NOT_STARTED;
+ if (uiEncounter[i] == IN_PROGRESS)
+ uiEncounter[i] = NOT_STARTED;
} else OUT_LOAD_INST_DATA_FAIL;
@@ -161,7 +226,7 @@ InstanceData* GetInstanceData_instance_pit_of_saron(Map* pMap)
return new instance_pit_of_saron(pMap);
}
-void AddSC_pit_of_saron()
+void AddSC_instance_pit_of_saron()
{
Script *newscript;
newscript = new Script;
diff --git a/src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp b/src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp
new file mode 100644
index 00000000000..63f1ff7e264
--- /dev/null
+++ b/src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.cpp
@@ -0,0 +1,1101 @@
+/* Copyright (C) 2006 - 2010 TrinityCore <https://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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "ScriptedPch.h"
+#include "pit_of_saron.h"
+
+/***************************************SPELLS*************************************/
+// Ymirjar Wrathbringer
+#define SPELL_BLIGHT DUNGEON_MODE(69603,70285)
+
+//Ymirjar Skycaller
+#define SPELL_FROSTBLADE 70291
+#define SPELL_GLACIAL_STRIKE 70292
+
+//Ymirjar Flamebearer
+#define SPELL_FIREBALL DUNGEON_MODE(69583,70282)
+#define SPELL_HELLFIRE DUNGEON_MODE(69586,70283)
+#define SPELL_TACTICAL_BLINK 69584
+
+//Ymirjar Deathbringer
+#define SPELL_EMPOWERED_SHADOW_BOLT DUNGEON_MODE(69528,70281)
+#define SPELL_SUMMON_UNDEAD 69516
+
+//Wrathbone Laborer
+#define SPELL_BLINDING_DIRT 70302
+#define SPELL_PUNCTURE_WOUND DUNGEON_MODE(70278,70279)
+#define SPELL_SHOVELLED DUNGEON_MODE(69572,70280)
+
+//Wrathbone Coldwraith
+#define SPELL_FREEZING_CIRCLE DUNGEON_MODE(69574,70276)
+#define SPELL_FROSTBOLT DUNGEON_MODE(69573,70277)
+
+//Stonespine Gargoyle
+#define SPELL_GARGOYLE_STRIKE DUNGEON_MODE(69520,70275)
+#define SPELL_STONEFORM 69575
+
+// Plagueborn Horror
+#define SPELL_BLIGHT_BOMB 69582
+#define SPELL_PUSTULANT_FLESH DUNGEON_MODE(69581,70273)
+#define SPELL_TOXIC_WASTE 70274
+
+//Iceborn Proto-Drake
+#define SPELL_FROST_BREATH DUNGEON_MODE(69527,70272)
+
+//Hungering Ghoul
+#define SPELL_DEVOUR_FLESH 70393
+
+//Fallen Warrior
+#define SPELL_ARCING_SLICE 69579
+#define SPELL_DEMORALIZING_SHOUT 61044
+#define SPELL_SHIELD_BLOCK 69580
+
+//Deathwhisper Torturer
+#define SPELL_BLACK_BRAND 70392
+#define SPELL_CURSE_OF_AGONY 70391
+
+//Deathwhisper Shadowcaster
+#define SPELL_SHADOW_BOLT DUNGEON_MODE(70386,70387)
+
+//Deathwhisper Necrolyte
+#define SPELL_CONVERSION_BEAM DUNGEON_MODE(69578,70269)
+#define SPELL_SHADOW_BOLT_2 DUNGEON_MODE(69577,70270)
+
+//Wrathbone Sorcerer
+#define SPELL_SHADOW_BOLT_3 DUNGEON_MODE(70386,70387)
+
+//Geist Ambusher
+#define SPELL_LEAPING_FACE_MAUL DUNGEON_MODE(69504,70271)
+
+/****************************************EVENTS************************************/
+enum eEvents
+{
+ EVENT_NONE,
+
+ // Ymirjar Wrathbringer
+ EVENT_BLIGHT,
+
+ // Ymirjar Skycaller
+ EVENT_FROSTBLADE,
+ EVENT_GLACIAL_STRIKE,
+
+ // Ymirjar Flamebearer
+ EVENT_FIREBALL,
+ EVENT_HELLFIRE,
+ EVENT_TACTICAL_BLINK,
+
+ //Ymirjar Deathbringer
+ EVENT_EMPOWERED_SHADOW_BOLT,
+ EVENT_SUMMON_UNDEAD,
+
+ //Wrathbone Laborer
+ EVENT_BLINDING_DIRT,
+ EVENT_PUNCTURE_WOUND,
+ EVENT_SHOVELLED,
+
+ //Wrathbone Coldwraith
+ EVENT_FREEZING_CIRCLE,
+ EVENT_FROSTBOLT,
+
+ //Stonespine Gargoyle
+ EVENT_GARGOYLE_STRIKE,
+ EVENT_STONEFORM,
+
+ //Plagueborn Horror
+ EVENT_BLIGHT_BOMB,
+ EVENT_PUSTULANT_FLESH,
+ EVENT_TOXIC_WASTE,
+
+ //Iceborn Proto-Drake
+ EVENT_FROST_BREATH,
+
+ //Hungering Ghoul
+ EVENT_DEVOUR_FLESH,
+
+ //Fallen Warrior
+ EVENT_ARCING_SLICE,
+ EVENT_DEMORALIZING_SHOUT,
+ EVENT_SHIELD_BLOCK,
+
+ //Deathwhisper Torturer
+ EVENT_BLACK_BRAND,
+ EVENT_CURSE_OF_AGONY,
+
+ //Deathwhisper Shadowcaster
+ EVENT_SHADOW_BOLT,
+
+ //Deathwhisper Necrolyte
+ EVENT_CONVERSION_BEAM,
+ EVENT_SHADOW_BOLT_2,
+
+ EVENT_SHADOW_BOLT_3,
+
+ //Geist Ambusher
+ EVENT_LEAPING_FACE_MAUL,
+};
+
+/****************************************AI****************************************/
+struct mob_ymirjar_wrathbringerAI : public ScriptedAI
+{
+ mob_ymirjar_wrathbringerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_BLIGHT, 7000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BLIGHT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_BLIGHT);
+ events.RescheduleEvent(EVENT_BLIGHT, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_ymirjar_skyCallerAI: public ScriptedAI
+{
+ mob_ymirjar_skyCallerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_FROSTBLADE, 1);
+ events.ScheduleEvent(EVENT_GLACIAL_STRIKE, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_GLACIAL_STRIKE:
+ DoCast(m_creature->getVictim(), SPELL_GLACIAL_STRIKE);
+ events.RescheduleEvent(EVENT_GLACIAL_STRIKE, 8000);
+ return;
+ case EVENT_FROSTBLADE:
+ DoCast(me, SPELL_FROSTBLADE);
+ events.CancelEvent(EVENT_FROSTBLADE);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_ymirjar_flamebearerAI: public ScriptedAI
+{
+ mob_ymirjar_flamebearerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_FIREBALL, 4000);
+ events.ScheduleEvent(EVENT_HELLFIRE, 8000);
+ events.ScheduleEvent(EVENT_TACTICAL_BLINK, 15000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FIREBALL:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_FIREBALL);
+ events.RescheduleEvent(EVENT_FIREBALL, 5000);
+ return;
+ case EVENT_HELLFIRE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_HELLFIRE);
+ events.RescheduleEvent(EVENT_HELLFIRE, 10000);
+ return;
+ case EVENT_TACTICAL_BLINK:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_TACTICAL_BLINK);
+ events.RescheduleEvent(EVENT_TACTICAL_BLINK, 12000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_ymirjar_deathbringerAI: public ScriptedAI
+{
+ mob_ymirjar_deathbringerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_EMPOWERED_SHADOW_BOLT, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_EMPOWERED_SHADOW_BOLT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_EMPOWERED_SHADOW_BOLT);
+ events.RescheduleEvent(EVENT_EMPOWERED_SHADOW_BOLT, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_wrathbone_laborerAI: public ScriptedAI
+{
+ mob_wrathbone_laborerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_BLINDING_DIRT, 8000);
+ events.ScheduleEvent(EVENT_PUNCTURE_WOUND, 9000);
+ events.ScheduleEvent(EVENT_SHOVELLED, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BLINDING_DIRT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_BLINDING_DIRT);
+ events.RescheduleEvent(EVENT_BLINDING_DIRT, 10000);
+ return;
+ case EVENT_PUNCTURE_WOUND:
+ DoCast(m_creature->getVictim(), SPELL_PUNCTURE_WOUND);
+ events.RescheduleEvent(EVENT_PUNCTURE_WOUND, 9000);
+ return;
+ case EVENT_SHOVELLED:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHOVELLED);
+ events.RescheduleEvent(EVENT_SHOVELLED, 7000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_wrathbone_coldwraithAI: public ScriptedAI
+{
+ mob_wrathbone_coldwraithAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_FREEZING_CIRCLE, 9000);
+ events.ScheduleEvent(EVENT_FROSTBOLT, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FREEZING_CIRCLE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_FREEZING_CIRCLE);
+ events.RescheduleEvent(EVENT_FREEZING_CIRCLE, 9000);
+ return;
+ case EVENT_FROSTBOLT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_FROSTBOLT);
+ events.RescheduleEvent(EVENT_FROSTBOLT, 5000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_stonespine_gargoyleAI: public ScriptedAI
+{
+ mob_stonespine_gargoyleAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_GARGOYLE_STRIKE, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_GARGOYLE_STRIKE:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_GARGOYLE_STRIKE);
+ events.RescheduleEvent(EVENT_GARGOYLE_STRIKE, 6000);
+ return;
+ case EVENT_STONEFORM:
+ if (HealthBelowPct(10))
+ DoCast(me, SPELL_STONEFORM);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_plagueborn_horrorAI: public ScriptedAI
+{
+ mob_plagueborn_horrorAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_BLIGHT_BOMB, 999999);
+ events.ScheduleEvent(EVENT_PUSTULANT_FLESH, 5000);
+ events.ScheduleEvent(EVENT_TOXIC_WASTE, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BLIGHT_BOMB:
+ if (HealthBelowPct(15))
+ DoCast(me, SPELL_BLIGHT_BOMB);
+ return;
+ case EVENT_PUSTULANT_FLESH:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_PUSTULANT_FLESH);
+ events.RescheduleEvent(EVENT_PUSTULANT_FLESH, 10000);
+ return;
+ case EVENT_TOXIC_WASTE:
+ DoCast(me, SPELL_TOXIC_WASTE);
+ events.RescheduleEvent(EVENT_TOXIC_WASTE, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_iceborn_protodrakeAI: public ScriptedAI
+{
+ mob_iceborn_protodrakeAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_FROST_BREATH, 5000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FROST_BREATH:
+ DoCast(m_creature->getVictim(), SPELL_FROST_BREATH);
+ events.RescheduleEvent(EVENT_FROST_BREATH, 10000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_hungering_ghoulAI: public ScriptedAI
+{
+ mob_hungering_ghoulAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_DEVOUR_FLESH, 4000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_DEVOUR_FLESH:
+ DoCast(m_creature->getVictim(), SPELL_DEVOUR_FLESH);
+ events.RescheduleEvent(EVENT_DEVOUR_FLESH, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_fallen_warriorAI: public ScriptedAI
+{
+ mob_fallen_warriorAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_ARCING_SLICE, 8000);
+ events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, 20000);
+ events.ScheduleEvent(EVENT_SHIELD_BLOCK, 8000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_ARCING_SLICE:
+ DoCast(m_creature->getVictim(), SPELL_ARCING_SLICE);
+ events.RescheduleEvent(EVENT_ARCING_SLICE, 10000);
+ return;
+ case EVENT_DEMORALIZING_SHOUT:
+ DoCast(me, SPELL_DEMORALIZING_SHOUT);
+ events.RescheduleEvent(EVENT_DEMORALIZING_SHOUT, 20000);
+ return;
+ case EVENT_SHIELD_BLOCK:
+ DoCast(m_creature->getVictim(), SPELL_SHIELD_BLOCK);
+ events.RescheduleEvent(EVENT_SHIELD_BLOCK, 8000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_deathwhisper_torturerAI: public ScriptedAI
+{
+ mob_deathwhisper_torturerAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_BLACK_BRAND, 10000);
+ events.ScheduleEvent(EVENT_CURSE_OF_AGONY, 6000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_BLACK_BRAND:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_BLACK_BRAND);
+ events.RescheduleEvent(EVENT_BLACK_BRAND, 10000);
+ return;
+ case EVENT_CURSE_OF_AGONY:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_CURSE_OF_AGONY);
+ events.RescheduleEvent(EVENT_CURSE_OF_AGONY, 13000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_deathwhisper_shadowcasterAI: public ScriptedAI
+{
+ mob_deathwhisper_shadowcasterAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_SHADOW_BOLT, 3000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHADOW_BOLT:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_BOLT);
+ events.RescheduleEvent(EVENT_SHADOW_BOLT, 5000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_deathwhisper_necrolyteAI: public ScriptedAI
+{
+ mob_deathwhisper_necrolyteAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_CONVERSION_BEAM, 12000);
+ events.ScheduleEvent(EVENT_SHADOW_BOLT_2, 4000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_CONVERSION_BEAM:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_CONVERSION_BEAM);
+ events.RescheduleEvent(EVENT_CONVERSION_BEAM, 12000);
+ return;
+ case EVENT_SHADOW_BOLT_2:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_BOLT_2);
+ events.RescheduleEvent(EVENT_SHADOW_BOLT_2, 5000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_wrathbone_sorcererAI: public ScriptedAI
+{
+ mob_wrathbone_sorcererAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ events.ScheduleEvent(EVENT_SHADOW_BOLT_3, 3000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHADOW_BOLT_3:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_SHADOW_BOLT_3);
+ events.RescheduleEvent(EVENT_SHADOW_BOLT_3, 5000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct mob_geist_ambusherAI: public ScriptedAI
+{
+ mob_geist_ambusherAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ //Only here so when I figure out how to make it cast on an NPC i can do that.
+ events.ScheduleEvent(EVENT_LEAPING_FACE_MAUL, 99999);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (m_creature->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ //Should only be used on NPCs
+ case EVENT_LEAPING_FACE_MAUL:
+ if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ DoCast(pTarget, SPELL_LEAPING_FACE_MAUL);
+ events.CancelEvent(EVENT_LEAPING_FACE_MAUL);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_ymirjar_wrathbringerAI(Creature* pCreature)
+{
+ return new mob_ymirjar_wrathbringerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_ymirjar_skyCallerAI(Creature* pCreature)
+{
+ return new mob_ymirjar_skyCallerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_ymirjar_flamebearerAI(Creature* pCreature)
+{
+ return new mob_ymirjar_flamebearerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_ymirjar_deathbringerAI(Creature* pCreature)
+{
+ return new mob_ymirjar_deathbringerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_wrathbone_laborerAI(Creature* pCreature)
+{
+ return new mob_wrathbone_laborerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_wrathbone_coldwraithAI(Creature* pCreature)
+{
+ return new mob_wrathbone_coldwraithAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_stonespine_gargoyleAI(Creature* pCreature)
+{
+ return new mob_stonespine_gargoyleAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_plagueborn_horrorAI(Creature* pCreature)
+{
+ return new mob_plagueborn_horrorAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_iceborn_protodrakeAI(Creature* pCreature)
+{
+ return new mob_iceborn_protodrakeAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_hungering_ghoulAI(Creature* pCreature)
+{
+ return new mob_hungering_ghoulAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_fallen_warriorAI(Creature* pCreature)
+{
+ return new mob_fallen_warriorAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_deathwhisper_torturerAI(Creature* pCreature)
+{
+ return new mob_deathwhisper_torturerAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_deathwhisper_shadowcasterAI(Creature* pCreature)
+{
+ return new mob_deathwhisper_shadowcasterAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_deathwhisper_necrolyteAI(Creature* pCreature)
+{
+ return new mob_deathwhisper_necrolyteAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_wrathbone_sorcererAI(Creature* pCreature)
+{
+ return new mob_wrathbone_sorcererAI(pCreature);
+}
+
+CreatureAI* GetAI_mob_geist_ambusherAI(Creature* pCreature)
+{
+ return new mob_geist_ambusherAI(pCreature);
+}
+
+void AddSC_pit_of_saron()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="mob_ymirjar_wrathbringer";
+ newscript->GetAI = &GetAI_mob_ymirjar_wrathbringerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ymirjar_skycaller";
+ newscript->GetAI = &GetAI_mob_ymirjar_skyCallerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ymirjar_flamebearer";
+ newscript->GetAI = &GetAI_mob_ymirjar_flamebearerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_ymirjar_deathbringer";
+ newscript->GetAI = &GetAI_mob_ymirjar_deathbringerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_wrathbone_laborer";
+ newscript->GetAI = &GetAI_mob_wrathbone_laborerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_wrathbone_coldwraith";
+ newscript->GetAI = &GetAI_mob_wrathbone_coldwraithAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_stonespine_gargoyle";
+ newscript->GetAI = &GetAI_mob_stonespine_gargoyleAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_plagueborn_horror";
+ newscript->GetAI = &GetAI_mob_plagueborn_horrorAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_iceborn_protodrake";
+ newscript->GetAI = &GetAI_mob_iceborn_protodrakeAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_hungering_ghoul";
+ newscript->GetAI = &GetAI_mob_hungering_ghoulAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_fallen_warrior";
+ newscript->GetAI = &GetAI_mob_fallen_warriorAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_deathwhisper_torturer";
+ newscript->GetAI = &GetAI_mob_deathwhisper_torturerAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_deathwhisper_shadowcaster";
+ newscript->GetAI = &GetAI_mob_deathwhisper_shadowcasterAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_deathwhisper_necrolyte";
+ newscript->GetAI = &GetAI_mob_deathwhisper_necrolyteAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_wrathbone_sorcerer";
+ newscript->GetAI = &GetAI_mob_wrathbone_sorcererAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name="mob_geist_ambusher";
+ newscript->GetAI = &GetAI_mob_geist_ambusherAI;
+ newscript->RegisterSelf();
+}
diff --git a/src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h b/src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h
index 97a9ff7d8f0..4a221d17518 100644
--- a/src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h
+++ b/src/scripts/northrend/frozen_halls/pit_of_saron/pit_of_saron.h
@@ -16,17 +16,48 @@
#ifndef DEF_PIT_OF_SARON_H
#define DEF_PIT_OF_SARON_H
+
enum Data
{
- DATA_FORGEMASTER_EVENT,
+ DATA_GARFROST_EVENT,
DATA_KRICKANDICK_EVENT,
- DATA_TYRANNUS_EVENT
+ DATA_TYRANNUS_EVENT,
+ DATA_TEAM_IN_INSTANCE,
+};
+
+enum Data64
+{
+ DATA_GARFROST,
+ DATA_KRICK,
+ DATA_ICK,
+ DATA_TYRANNUS,
+ DATA_RIMEFANG,
+
+ DATA_JAINA_SYLVANAS_1, // GUID of either Jaina or Sylvanas part 1, depending on team, as it's the same spawn.
+ DATA_JAINA_SYLVANAS_2, // GUID of either Jaina or Sylvanas part 2, depending on team, as it's the same spawn.
};
+
enum Creatures
{
- CREATURE_FORGEMASTER = 36494,
- CREATURE_KRICK = 36477,
- CREATURE_ICK = 36476,
- CREATURE_TYRANNUS = 36658
+ CREATURE_GARFROST = 36494,
+ CREATURE_KRICK = 36477,
+ CREATURE_ICK = 36476,
+ CREATURE_TYRANNUS = 36658,
+ CREATURE_RIMEFANG = 36661,
+
+ NPC_SYLVANAS_PART1 = 36990,
+ NPC_SYLVANAS_PART2 = 38189,
+ NPC_JAINA_PART1 = 36993,
+ NPC_JAINA_PART2 = 38188,
+ NPC_KILARA = 37583,
+ NPC_ELANDRA = 37774,
+ NPC_KORALEN = 37779,
+ NPC_KORLAEN = 37582,
+ NPC_CHAMPION_1_HORDE = 37584,
+ NPC_CHAMPION_2_HORDE = 37587,
+ NPC_CHAMPION_3_HORDE = 37588,
+ NPC_CHAMPION_1_ALLIANCE = 37496,
+ NPC_CHAMPION_2_ALLIANCE = 37497,
};
+
#endif