aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrazom62 <none@none>2010-05-20 20:09:18 +0200
committerTrazom62 <none@none>2010-05-20 20:09:18 +0200
commitd2cad4b14e27c8c7b7ba5be7449dbb908f34497d (patch)
tree722ed1fb40c1b90ff5668cbe8be6063d2233026b
parentce7886aeb0df0257aa953bdf83ef51c4251a6ebf (diff)
Script HoR instance. 1st part.
Fixes issue #1311. - Intro event. - 10 waves including Falric and Marwyn. - Script based on proposal of Synric on trinitycore forum (submitted by Skarabex on GC). --HG-- branch : trunk
-rw-r--r--sql/FULL/world_script_texts.sql60
-rw-r--r--sql/FULL/world_scripts_full.sql13
-rw-r--r--sql/updates/8246_world_script_name.sql11
-rw-r--r--sql/updates/8246_world_script_texts.sql60
-rw-r--r--src/game/ScriptLoader.cpp8
-rw-r--r--src/game/SpellAuras.cpp23
-rw-r--r--src/game/SpellMgr.cpp1
-rw-r--r--src/scripts/CMakeLists.txt3
-rw-r--r--src/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp142
-rw-r--r--src/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp133
-rw-r--r--src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp1022
-rw-r--r--src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h133
-rw-r--r--src/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp321
-rw-r--r--win/VC90/game.vcproj12
14 files changed, 1907 insertions, 35 deletions
diff --git a/sql/FULL/world_script_texts.sql b/sql/FULL/world_script_texts.sql
index 670c34dfa23..581d129a5a2 100644
--- a/sql/FULL/world_script_texts.sql
+++ b/sql/FULL/world_script_texts.sql
@@ -2712,6 +2712,66 @@ INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1`
(36990,-1658068,'I thought he''d never shut up. At last, Sindragosa silenced that long-winded fool. To the Halls of Reflection, champions! Our objective is near... I can sense it.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17036,0,0,0,'Sylvanas SAY_SYLVANAS_OUTRO_4'),
(36993,-1658069,'I... I could not save them... Damn you, Arthas! DAMN YOU!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16616,0,0,0,'Jaina SAY_JAYNA_OUTRO_5'),
+-- -1 658 000 ICECROWN CITADEL: FROZEN HALLS: HALLS OF REFLECTION
+-- INTRO
+ (37221,-1668001,'The chill of this place... Brr... I can feel my blood freezing.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16631,1,0,0,'Jaina SAY_JAINA_INTRO_1'),
+ (37221,-1668002,'What is that? Up ahead! Could it be... ? Heroes at my side!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16632,1,0,0,'Jaina SAY_JAINA_INTRO_2'),
+ (37221,-1668003,'Frostmourne! The blade that destroyed our kingdom...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16633,1,0,0,'Jaina SAY_JAINA_INTRO_3'),
+ (37221,-1668004,'Stand back! Touch that blade and your soul will be scarred for all eternity! I must attempt to commune with the spirits locked away within Frostmourne. Give me space, back up please!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16634,1,0,0,'Jaina SAY_JAINA_INTRO_4'),
+ (37225,-1668005,'Jaina! Could it truly be you?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16666,1,0,0,'Uther SAY_UTHER_INTRO_A2_1'),
+ (37221,-1668006,'Uther! Dear Uther! ... I... I''m so sorry.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16635,0,0,0,'Jaina SAY_JAINA_INTRO_5'),
+ (37225,-1668007,'Jaina you haven''t much time. The Lich King sees what the sword sees. He will be here shortly!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16667,0,0,0,'Uther SAY_UTHER_INTRO_A2_2'),
+ (37221,-1668008,'Arthas is here? Maybe I...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16636,0,0,0,'Jaina SAY_JAINA_INTRO_6'),
+ (37225,-1668009,'No, girl. Arthas is not here. Arthas is merely a presence within the Lich King''s mind. A dwindling presence...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16668,0,0,0,'Uther SAY_UTHER_INTRO_A2_3'),
+ (37221,-1668010,'But Uther, if there''s any hope of reaching Arthas. I... I must try.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16637,0,0,0,'Jaina SAY_JAINA_INTRO_7'),
+ (37225,-1668011,'Jaina, listen to me. You must destroy the Lich King. You cannot reason with him. He will kill you and your allies and raise you all as powerful soldiers of the Scourge.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16669,0,0,0,'Uther SAY_UTHER_INTRO_A2_4'),
+ (37221,-1668012,'Tell me how, Uther? How do I destroy my prince? My...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16638,0,0,0,'Jaina SAY_JAINA_INTRO_8'),
+ (37225,-1668013,'Snap out of it, girl. You must destroy the Lich King at the place where he merged with Ner''zhul - atop the spire, at the Frozen Throne. It is the only way.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16670,0,0,0,'Uther SAY_UTHER_INTRO_A2_5'),
+ (37221,-1668014,'You''re right, Uther. Forgive me. I... I don''t know what got a hold of me. We will deliver this information to the King and the knights that battle the Scourge within Icecrown Citadel.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16639,0,0,0,'Jaina SAY_JAINA_INTRO_9'),
+ (37225,-1668015,'There is... something else that you should know about the Lich King. Control over the Scourge must never be lost. Even if you were to strike down the Lich King, another would have to take his place. For without the control of its master, the Scourge would run rampant across the world - destroying all living things.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16671,0,0,0,'Uther SAY_UTHER_INTRO_A2_6'),
+ (37225,-1668016,'A grand sacrifice by a noble soul...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16672,0,0,0,'Uther SAY_UTHER_INTRO_A2_7'),
+ (37221,-1668017,'Who could bear such a burden?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16640,0,0,0,'Jaina SAY_JAINA_INTRO_10'),
+ (37225,-1668018,'I do not know, Jaina. I suspect that the piece of Arthas that might be left inside the Lich King is all that holds the Scourge from annihilating Azeroth.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16673,0,0,0,'Uther SAY_UTHER_INTRO_A2_8'),
+ (37221,-1668019,'Then maybe there is still hope...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16641,0,0,0,'Jaina SAY_JAINA_INTRO_11'),
+ (37225,-1668020,'No, Jaina! Aargh! He... He is coming! You... You must...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16674,0,0,0,'Uther SAY_UTHER_INTRO_A2_9'),
+ (37223,-1668021,'I... I don''t believe it! Frostmourne stands before us, unguarded! Just as the Gnome claimed. Come, heroes!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17049,1,0,0,'Sylvanas SAY_SYLVANAS_INTRO_1'),
+ (37223,-1668022,'Standing this close to the blade that ended my life... The pain... It is renewed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17050,1,0,0,'Sylvanas SAY_SYLVANAS_INTRO_2'),
+ (37223,-1668023,'I dare not touch it. Stand back! Stand back as I attempt to commune with the blade! Perhaps our salvation lies within...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17051,1,0,0,'Sylvanas SAY_SYLVANAS_INTRO_3'),
+ (37225,-1668024,'Careful, girl. I''ve heard talk of that cursed blade saving us before. Look around you and see what has been born of Frostmourne.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16659,0,0,0,'Uther SAY_UTHER_INTRO_H2_1'),
+ (37223,-1668025,'Uther...Uther the Lightbringer. How...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17052,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_4'),
+ (37225,-1668026,'You haven''t much time. The Lich King sees what the sword sees. He will be here shortly.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16660,0,0,0,'Uther SAY_UTHER_INTRO_H2_2'),
+ (37223,-1668027,'The Lich King is here? Then my destiny shall be fulfilled today!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17053,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_5'),
+ (37225,-1668028,'You cannot defeat the Lich King. Not here. You would be a fool to try. He will kill those who follow you and raise them as powerful servants of the Scourge. But for you, Sylvanas, his reward for you would be worse than the last.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16661,0,0,0,'Uther SAY_UTHER_INTRO_H2_3'),
+ (37223,-1668029,'There must be a way... ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17054,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_6'),
+ (37225,-1668030,'Perhaps, but know this: there must always be a Lich King. Even if you were to strike down Arthas, another would have to take his place, for without the control of the Lich King, the Scourge would wash over this world like locusts, destroying all that they touched.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16662,0,0,0,'Uther SAY_UTHER_INTRO_H2_4'),
+ (37223,-1668031,'Who could bear such a burden?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17055,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_7'),
+ (37225,-1668032,'I do not know, Banshee Queen. I suspect that the piece of Arthas that might be left inside the Lich King is all that holds the Scourge from annihilating Azeroth.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16663,0,0,0,'Uther SAY_UTHER_INTRO_H2_5'),
+ (37225,-1668033,'Alas, the only way to defeat the Lich King is to destroy him at the place he was created.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16664,0,0,0,'Uther SAY_UTHER_INTRO_H2_6'),
+ (37223,-1668034,'The Frozen Throne...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17056,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_8'),
+ (37225,-1668035,'I... Aargh... He... He is coming... You... You must...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16665,0,0,0,'Uther SAY_UTHER_INTRO_H2_7'),
+ (37226,-1668036,'SILENCE, PALADIN!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17225,1,0,0,'Lich King SAY_LK_INTRO_1'),
+ (37226,-1668037,'So you wish to commune with the dead? You shall have your wish.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17226,1,0,0,'Lich King SAY_LK_INTRO_2'),
+ (37226,-1668038,'Falric. Marwyn. Bring their corpses to my chamber when you are through.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17227,1,0,0,'Lich King SAY_LK_INTRO_3'),
+ (38112,-1668039,'As you wish, my lord.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16717,1,0,0,'Falric SAY_FALRIC_INTRO_1'),
+ (38113,-1668040,'As you wish, my lord.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16741,1,0,0,'Marwyn SAY_MARWYN_INTRO_1'),
+ (38112,-1668041,'Soldiers of Lordaeron, rise to meet your master''s call!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16714,1,0,0,'Falric SAY_FALRIC_INTRO_2'),
+ (37221,-1668042,'You won''t deny me this Arthas! I must know! I must find out!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16642,1,0,0,'Jaina SAY_JAINA_INTRO_END'),
+ (37223,-1668043,'You will not escape me that easily, Arthas! I will have my vengeance!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17057,1,0,0,'Sylvanas SAY_SYLVANAS_INTRO_END'),
+-- Falric
+ (38112,-1668050,'Men, women and children... None were spared the master''s wrath. Your death will be no different.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16710,1,0,0,'Falric SAY_AGGRO'),
+ (38112,-1668051,'Sniveling maggot!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16711,1,0,0,'Falric SAY_SLAY_1'),
+ (38112,-1668052,'The children of Stratholme fought with more ferocity!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16712,1,0,0,'Falric SAY_SLAY_2'),
+ (38112,-1668053,'Marwyn, finish them...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16713,1,0,0,'Falric SAY_DEATH'),
+ (38112,-1668054,'Despair... so delicious...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16715,1,0,0,'Falric SAY_IMPENDING_DESPAIR'),
+ (38112,-1668055,'Fear... so exhilarating...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16716,1,0,0,'Falric SAY_DEFILING_HORROR'),
+-- Marwyn
+ (38113,-1668060,'Death is all that you will find here!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16734,1,0,0,'Marwyn SAY_AGGRO'),
+ (38113,-1668061,'I saw the same look in his eyes when he died. Terenas could hardly believe it. Hahahaha!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16735,1,0,0,'Marwyn SAY_SLAY_1'),
+ (38113,-1668062,'Choke on your suffering!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16736,1,0,0,'Marwyn SAY_SLAY_2'),
+ (38113,-1668063,'Yes... Run... Run to meet your destiny... Its bitter, cold embrace, awaits you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16737,1,0,0,'Marwyn SAY_DEATH'),
+ (38113,-1668064,'Your flesh has decayed before your very eyes!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16739,1,0,0,'Marwyn SAY_CORRUPTED_FLESH_1'),
+ (38113,-1668065,'Waste away into nothingness!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16740,1,0,0,'Marwyn SAY_CORRUPTED_FLESH_2'),
+
-- -1 999 900+ - RANDOM
(0,-1999900,'Let the games begin.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,8280,1,0,0,'example_creature SAY_AGGRO'),
(0,-1999901,'I see endless suffering. I see torment. I see rage. I see everything.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,8831,1,0,0,'example_creature SAY_RANDOM_0'),
diff --git a/sql/FULL/world_scripts_full.sql b/sql/FULL/world_scripts_full.sql
index 39d7b999c42..227c8e881a7 100644
--- a/sql/FULL/world_scripts_full.sql
+++ b/sql/FULL/world_scripts_full.sql
@@ -793,6 +793,19 @@ UPDATE `creature_template` SET `ScriptName`='boss_magtheridon' WHERE `entry`=172
UPDATE `creature_template` SET `ScriptName`='mob_hellfire_channeler' WHERE `entry`=17256;
UPDATE `creature_template` SET `ScriptName`='mob_abyssal' WHERE `entry`=17454;
+/* HALLS OF REFLECTION */
+UPDATE `instance_template` SET `script`='instance_halls_of_reflection' WHERE `map`=668;
+UPDATE `creature_template` SET `Scriptname`='boss_falric' WHERE `entry`=38112;
+UPDATE `creature_template` SET `Scriptname`='boss_marwyn' WHERE `entry`=38113;
+UPDATE `creature_template` SET `Scriptname`='npc_jaina_hor_part1' WHERE `entry`=37221;
+UPDATE `creature_template` SET `Scriptname`='npc_sylvanas_hor_part1' WHERE `entry`=37223;
+UPDATE `creature_template` SET `Scriptname`='npc_ghostly_priest' WHERE `entry`=38175;
+UPDATE `creature_template` SET `Scriptname`='npc_phantom_mage' WHERE `entry`=38172;
+UPDATE `creature_template` SET `Scriptname`='npc_phantom_hallucination' WHERE `entry`=38567;
+UPDATE `creature_template` SET `Scriptname`='npc_shadowy_mercenary' WHERE `entry`=38177;
+UPDATE `creature_template` SET `Scriptname`='npc_spectral_footman' WHERE `entry`=38173;
+UPDATE `creature_template` SET `Scriptname`='npc_tortured_rifleman' WHERE `entry`=38176;
+
/* HELLFIRE PENINSULA */
UPDATE `creature_template` SET `ScriptName`='boss_doomlord_kazzak' WHERE `entry`=18728;
UPDATE `creature_template` SET `ScriptName`='npc_wounded_blood_elf' WHERE `entry`=16993;
diff --git a/sql/updates/8246_world_script_name.sql b/sql/updates/8246_world_script_name.sql
new file mode 100644
index 00000000000..fc1f1825c83
--- /dev/null
+++ b/sql/updates/8246_world_script_name.sql
@@ -0,0 +1,11 @@
+UPDATE `instance_template` SET `script`='instance_halls_of_reflection' WHERE `map`=668;
+UPDATE `creature_template` SET `Scriptname`='boss_falric' WHERE `entry`=38112;
+UPDATE `creature_template` SET `Scriptname`='boss_marwyn' WHERE `entry`=38113;
+UPDATE `creature_template` SET `Scriptname`='npc_jaina_hor_part1' WHERE `entry`=37221;
+UPDATE `creature_template` SET `Scriptname`='npc_sylvanas_hor_part1' WHERE `entry`=37223;
+UPDATE `creature_template` SET `Scriptname`='npc_ghostly_priest' WHERE `entry`=38175;
+UPDATE `creature_template` SET `Scriptname`='npc_phantom_mage' WHERE `entry`=38172;
+UPDATE `creature_template` SET `Scriptname`='npc_phantom_hallucination' WHERE `entry`=38567;
+UPDATE `creature_template` SET `Scriptname`='npc_shadowy_mercenary' WHERE `entry`=38177;
+UPDATE `creature_template` SET `Scriptname`='npc_spectral_footman' WHERE `entry`=38173;
+UPDATE `creature_template` SET `Scriptname`='npc_tortured_rifleman' WHERE `entry`=38176;
diff --git a/sql/updates/8246_world_script_texts.sql b/sql/updates/8246_world_script_texts.sql
new file mode 100644
index 00000000000..051a7613fc2
--- /dev/null
+++ b/sql/updates/8246_world_script_texts.sql
@@ -0,0 +1,60 @@
+DELETE FROM `script_texts` WHERE `entry` <= -1668000 and `entry` >= -1668999;
+INSERT INTO `script_texts` (`npc_entry`,`entry`,`content_default`,`content_loc1`,`content_loc2`,`content_loc3`,`content_loc4`,`content_loc5`,`content_loc6`,`content_loc7`,`content_loc8`,`sound`,`type`,`language`,`emote`,`comment`) VALUES
+-- INTRO
+(37221,-1668001,'The chill of this place... Brr... I can feel my blood freezing.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16631,1,0,0,'Jaina SAY_JAINA_INTRO_1'),
+(37221,-1668002,'What is that? Up ahead! Could it be... ? Heroes at my side!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16632,1,0,0,'Jaina SAY_JAINA_INTRO_2'),
+(37221,-1668003,'Frostmourne! The blade that destroyed our kingdom...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16633,1,0,0,'Jaina SAY_JAINA_INTRO_3'),
+(37221,-1668004,'Stand back! Touch that blade and your soul will be scarred for all eternity! I must attempt to commune with the spirits locked away within Frostmourne. Give me space, back up please!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16634,1,0,0,'Jaina SAY_JAINA_INTRO_4'),
+(37225,-1668005,'Jaina! Could it truly be you?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16666,1,0,0,'Uther SAY_UTHER_INTRO_A2_1'),
+(37221,-1668006,'Uther! Dear Uther! ... I... I''m so sorry.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16635,0,0,0,'Jaina SAY_JAINA_INTRO_5'),
+(37225,-1668007,'Jaina you haven''t much time. The Lich King sees what the sword sees. He will be here shortly!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16667,0,0,0,'Uther SAY_UTHER_INTRO_A2_2'),
+(37221,-1668008,'Arthas is here? Maybe I...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16636,0,0,0,'Jaina SAY_JAINA_INTRO_6'),
+(37225,-1668009,'No, girl. Arthas is not here. Arthas is merely a presence within the Lich King''s mind. A dwindling presence...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16668,0,0,0,'Uther SAY_UTHER_INTRO_A2_3'),
+(37221,-1668010,'But Uther, if there''s any hope of reaching Arthas. I... I must try.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16637,0,0,0,'Jaina SAY_JAINA_INTRO_7'),
+(37225,-1668011,'Jaina, listen to me. You must destroy the Lich King. You cannot reason with him. He will kill you and your allies and raise you all as powerful soldiers of the Scourge.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16669,0,0,0,'Uther SAY_UTHER_INTRO_A2_4'),
+(37221,-1668012,'Tell me how, Uther? How do I destroy my prince? My...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16638,0,0,0,'Jaina SAY_JAINA_INTRO_8'),
+(37225,-1668013,'Snap out of it, girl. You must destroy the Lich King at the place where he merged with Ner''zhul - atop the spire, at the Frozen Throne. It is the only way.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16670,0,0,0,'Uther SAY_UTHER_INTRO_A2_5'),
+(37221,-1668014,'You''re right, Uther. Forgive me. I... I don''t know what got a hold of me. We will deliver this information to the King and the knights that battle the Scourge within Icecrown Citadel.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16639,0,0,0,'Jaina SAY_JAINA_INTRO_9'),
+(37225,-1668015,'There is... something else that you should know about the Lich King. Control over the Scourge must never be lost. Even if you were to strike down the Lich King, another would have to take his place. For without the control of its master, the Scourge would run rampant across the world - destroying all living things.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16671,0,0,0,'Uther SAY_UTHER_INTRO_A2_6'),
+(37225,-1668016,'A grand sacrifice by a noble soul...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16672,0,0,0,'Uther SAY_UTHER_INTRO_A2_7'),
+(37221,-1668017,'Who could bear such a burden?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16640,0,0,0,'Jaina SAY_JAINA_INTRO_10'),
+(37225,-1668018,'I do not know, Jaina. I suspect that the piece of Arthas that might be left inside the Lich King is all that holds the Scourge from annihilating Azeroth.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16673,0,0,0,'Uther SAY_UTHER_INTRO_A2_8'),
+(37221,-1668019,'Then maybe there is still hope...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16641,0,0,0,'Jaina SAY_JAINA_INTRO_11'),
+(37225,-1668020,'No, Jaina! Aargh! He... He is coming! You... You must...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16674,0,0,0,'Uther SAY_UTHER_INTRO_A2_9'),
+(37223,-1668021,'I... I don''t believe it! Frostmourne stands before us, unguarded! Just as the Gnome claimed. Come, heroes!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17049,1,0,0,'Sylvanas SAY_SYLVANAS_INTRO_1'),
+(37223,-1668022,'Standing this close to the blade that ended my life... The pain... It is renewed.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17050,1,0,0,'Sylvanas SAY_SYLVANAS_INTRO_2'),
+(37223,-1668023,'I dare not touch it. Stand back! Stand back as I attempt to commune with the blade! Perhaps our salvation lies within...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17051,1,0,0,'Sylvanas SAY_SYLVANAS_INTRO_3'),
+(37225,-1668024,'Careful, girl. I''ve heard talk of that cursed blade saving us before. Look around you and see what has been born of Frostmourne.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16659,0,0,0,'Uther SAY_UTHER_INTRO_H2_1'),
+(37223,-1668025,'Uther...Uther the Lightbringer. How...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17052,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_4'),
+(37225,-1668026,'You haven''t much time. The Lich King sees what the sword sees. He will be here shortly.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16660,0,0,0,'Uther SAY_UTHER_INTRO_H2_2'),
+(37223,-1668027,'The Lich King is here? Then my destiny shall be fulfilled today!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17053,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_5'),
+(37225,-1668028,'You cannot defeat the Lich King. Not here. You would be a fool to try. He will kill those who follow you and raise them as powerful servants of the Scourge. But for you, Sylvanas, his reward for you would be worse than the last.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16661,0,0,0,'Uther SAY_UTHER_INTRO_H2_3'),
+(37223,-1668029,'There must be a way... ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17054,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_6'),
+(37225,-1668030,'Perhaps, but know this: there must always be a Lich King. Even if you were to strike down Arthas, another would have to take his place, for without the control of the Lich King, the Scourge would wash over this world like locusts, destroying all that they touched.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16662,0,0,0,'Uther SAY_UTHER_INTRO_H2_4'),
+(37223,-1668031,'Who could bear such a burden?',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17055,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_7'),
+(37225,-1668032,'I do not know, Banshee Queen. I suspect that the piece of Arthas that might be left inside the Lich King is all that holds the Scourge from annihilating Azeroth.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16663,0,0,0,'Uther SAY_UTHER_INTRO_H2_5'),
+(37225,-1668033,'Alas, the only way to defeat the Lich King is to destroy him at the place he was created.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16664,0,0,0,'Uther SAY_UTHER_INTRO_H2_6'),
+(37223,-1668034,'The Frozen Throne...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17056,0,0,0,'Sylvanas SAY_SYLVANAS_INTRO_8'),
+(37225,-1668035,'I... Aargh... He... He is coming... You... You must...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16665,0,0,0,'Uther SAY_UTHER_INTRO_H2_7'),
+(37226,-1668036,'SILENCE, PALADIN!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17225,1,0,0,'Lich King SAY_LK_INTRO_1'),
+(37226,-1668037,'So you wish to commune with the dead? You shall have your wish.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17226,1,0,0,'Lich King SAY_LK_INTRO_2'),
+(37226,-1668038,'Falric. Marwyn. Bring their corpses to my chamber when you are through.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17227,1,0,0,'Lich King SAY_LK_INTRO_3'),
+(38112,-1668039,'As you wish, my lord.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16717,1,0,0,'Falric SAY_FALRIC_INTRO_1'),
+(38113,-1668040,'As you wish, my lord.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16741,1,0,0,'Marwyn SAY_MARWYN_INTRO_1'),
+(38112,-1668041,'Soldiers of Lordaeron, rise to meet your master''s call!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16714,1,0,0,'Falric SAY_FALRIC_INTRO_2'),
+(37221,-1668042,'You won''t deny me this Arthas! I must know! I must find out!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16642,1,0,0,'Jaina SAY_JAINA_INTRO_END'),
+(37223,-1668043,'You will not escape me that easily, Arthas! I will have my vengeance!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,17057,1,0,0,'Sylvanas SAY_SYLVANAS_INTRO_END'),
+-- Falric
+(38112,-1668050,'Men, women and children... None were spared the master''s wrath. Your death will be no different.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16710,1,0,0,'Falric SAY_AGGRO'),
+(38112,-1668051,'Sniveling maggot!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16711,1,0,0,'Falric SAY_SLAY_1'),
+(38112,-1668052,'The children of Stratholme fought with more ferocity!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16712,1,0,0,'Falric SAY_SLAY_2'),
+(38112,-1668053,'Marwyn, finish them...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16713,1,0,0,'Falric SAY_DEATH'),
+(38112,-1668054,'Despair... so delicious...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16715,1,0,0,'Falric SAY_IMPENDING_DESPAIR'),
+(38112,-1668055,'Fear... so exhilarating...',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16716,1,0,0,'Falric SAY_DEFILING_HORROR'),
+-- Marwyn
+(38113,-1668060,'Death is all that you will find here!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16734,1,0,0,'Marwyn SAY_AGGRO'),
+(38113,-1668061,'I saw the same look in his eyes when he died. Terenas could hardly believe it. Hahahaha!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16735,1,0,0,'Marwyn SAY_SLAY_1'),
+(38113,-1668062,'Choke on your suffering!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16736,1,0,0,'Marwyn SAY_SLAY_2'),
+(38113,-1668063,'Yes... Run... Run to meet your destiny... Its bitter, cold embrace, awaits you.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16737,1,0,0,'Marwyn SAY_DEATH'),
+(38113,-1668064,'Your flesh has decayed before your very eyes!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16739,1,0,0,'Marwyn SAY_CORRUPTED_FLESH_1'),
+(38113,-1668065,'Waste away into nothingness!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,16740,1,0,0,'Marwyn SAY_CORRUPTED_FLESH_2');
diff --git a/src/game/ScriptLoader.cpp b/src/game/ScriptLoader.cpp
index 971ff4cbe35..20bda66a611 100644
--- a/src/game/ScriptLoader.cpp
+++ b/src/game/ScriptLoader.cpp
@@ -416,6 +416,10 @@ void AddSC_pit_of_saron();
void AddSC_boss_garfrost();
void AddSC_boss_ick();
void AddSC_boss_tyrannus();
+void AddSC_instance_halls_of_reflection(); // Halls of Reflection
+void AddSC_halls_of_reflection();
+void AddSC_boss_falric();
+void AddSC_boss_marwyn();
void AddSC_dalaran();
void AddSC_borean_tundra();
@@ -912,6 +916,10 @@ void AddScripts()
AddSC_boss_garfrost();
AddSC_boss_ick();
AddSC_boss_tyrannus();
+ AddSC_instance_halls_of_reflection(); // Halls of Reflection
+ AddSC_halls_of_reflection();
+ AddSC_boss_falric();
+ AddSC_boss_marwyn();
AddSC_dalaran();
AddSC_borean_tundra();
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index a531f24922e..1b2e0f5b6fd 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -1089,9 +1089,26 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster,
switch(GetSpellProto()->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
- // Remove the immunity shield marker on Avenging Wrath removal if Forbearance is not present
- if (GetId() == 61987 && target->HasAura(61988) && !target->HasAura(25771))
- target->RemoveAura(61988);
+ switch(GetId())
+ {
+ case 61987: // Avenging Wrath
+ // Remove the immunity shield marker on Avenging Wrath removal if Forbearance is not present
+ if (target->HasAura(61988) && !target->HasAura(25771))
+ target->RemoveAura(61988);
+ break;
+ case 72368: // Shared Suffering
+ case 72369:
+ if (caster)
+ {
+ if (AuraEffect* aurEff = GetEffect(0))
+ {
+ int32 remainingDamage = aurEff->GetAmount() * (aurEff->GetTotalTicks() - aurEff->GetTickNumber());
+ if (remainingDamage > 0)
+ caster->CastCustomSpell(caster, 72373, NULL, &remainingDamage, NULL, true);
+ }
+ }
+ break;
+ }
break;
case SPELLFAMILY_MAGE:
switch(GetId())
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 81c4ebaa76f..d7da9bb1e3b 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -3629,6 +3629,7 @@ void SpellMgr::LoadSpellCustomAttr()
case 42384: // Brutal Swipe
case 45150: // Meteor Slash
case 64422: case 64688: // Sonic Screech
+ case 72373: // Shared Suffering
// ONLY SPELLS WITH SPELLFAMILY_GENERIC and EFFECT_SCHOOL_DAMAGE
mSpellCustomAttr[i] |= SPELL_ATTR_CU_SHARE_DAMAGE;
count++;
diff --git a/src/scripts/CMakeLists.txt b/src/scripts/CMakeLists.txt
index e51130881f6..47dffe924dc 100644
--- a/src/scripts/CMakeLists.txt
+++ b/src/scripts/CMakeLists.txt
@@ -346,7 +346,10 @@ SET(scripts_STAT_SRCS
northrend/frozen_halls/forge_of_souls/boss_devourer_of_souls.cpp
northrend/frozen_halls/forge_of_souls/forge_of_souls.h
northrend/frozen_halls/forge_of_souls/forge_of_souls.cpp
+ northrend/frozen_halls/halls_of_reflection/boss_falric.cpp
+ northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp
northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
+ northrend/frozen_halls/halls_of_reflection/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
diff --git a/src/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp b/src/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp
new file mode 100644
index 00000000000..c9978faca6e
--- /dev/null
+++ b/src/scripts/northrend/frozen_halls/halls_of_reflection/boss_falric.cpp
@@ -0,0 +1,142 @@
+/* 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 "halls_of_reflection.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1668050,
+ SAY_SLAY_1 = -1668051,
+ SAY_SLAY_2 = -1668052,
+ SAY_DEATH = -1668053,
+ SAY_IMPENDING_DESPAIR = -1668054,
+ SAY_DEFILING_HORROR = -1668055,
+};
+
+enum Spells
+{
+ SPELL_QUIVERING_STRIKE = 72422,
+ SPELL_IMPENDING_DESPAIR = 72426,
+ SPELL_DEFILING_HORROR = 72435,
+ SPELL_HOPELESSNESS = 72395,
+ H_SPELL_HOPELESSNESS = 72390, // TODO: not in dbc. Add in DB.
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_QUIVERING_STRIKE,
+ EVENT_IMPENDING_DESPAIR,
+ EVENT_DEFILING_HORROR,
+};
+
+struct boss_falricAI : public boss_horAI
+{
+ boss_falricAI(Creature *pCreature) : boss_horAI(pCreature) {}
+
+ uint8 uiHopelessnessCount;
+
+ void Reset()
+ {
+ boss_horAI::Reset();
+
+ uiHopelessnessCount = 0;
+
+ if (pInstance)
+ pInstance->SetData(DATA_FALRIC_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ if (pInstance)
+ pInstance->SetData(DATA_FALRIC_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 23000);
+ events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 9000);
+ events.ScheduleEvent(EVENT_DEFILING_HORROR, urand(25000,45000)); // TODO adjust timer.
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_FALRIC_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_QUIVERING_STRIKE:
+ DoCast(SPELL_QUIVERING_STRIKE);
+ events.ScheduleEvent(EVENT_QUIVERING_STRIKE, 10000);
+ break;
+ case EVENT_IMPENDING_DESPAIR:
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ {
+ DoScriptText(SAY_IMPENDING_DESPAIR, me);
+ DoCast(pTarget, SPELL_IMPENDING_DESPAIR);
+ }
+ events.ScheduleEvent(EVENT_IMPENDING_DESPAIR, 13000);
+ break;
+ case EVENT_DEFILING_HORROR:
+ DoCast(SPELL_DEFILING_HORROR);
+ events.ScheduleEvent(EVENT_DEFILING_HORROR, urand(25000,45000)); // TODO adjust timer.
+ break;
+ }
+
+ if ((uiHopelessnessCount < 1 && HealthBelowPct(66))
+ || (uiHopelessnessCount < 2 && HealthBelowPct(33))
+ || (uiHopelessnessCount < 3 && HealthBelowPct(10)))
+ {
+ uiHopelessnessCount++;
+ DoCast(DUNGEON_MODE(SPELL_HOPELESSNESS,H_SPELL_HOPELESSNESS));
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_falric(Creature* pCreature)
+{
+ return new boss_falricAI(pCreature);
+}
+
+void AddSC_boss_falric()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_falric";
+ newscript->GetAI = &GetAI_boss_falric;
+ newscript->RegisterSelf();
+}
diff --git a/src/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp b/src/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp
new file mode 100644
index 00000000000..95fb2737ce9
--- /dev/null
+++ b/src/scripts/northrend/frozen_halls/halls_of_reflection/boss_marwyn.cpp
@@ -0,0 +1,133 @@
+/* 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 "halls_of_reflection.h"
+
+enum Yells
+{
+ SAY_AGGRO = -1668060,
+ SAY_SLAY_1 = -1668061,
+ SAY_SLAY_2 = -1668062,
+ SAY_DEATH = -1668063,
+ SAY_CORRUPTED_FLESH_1 = -1668064,
+ SAY_CORRUPTED_FLESH_2 = -1668065,
+};
+
+enum Spells
+{
+ SPELL_OBLITERATE = 72360,
+ SPELL_WELL_OF_CORRUPTION = 72362,
+ SPELL_CORRUPTED_FLESH = 72363,
+ SPELL_SHARED_SUFFERING = 72368,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_OBLITERATE,
+ EVENT_WELL_OF_CORRUPTION,
+ EVENT_CORRUPTED_FLESH,
+ EVENT_SHARED_SUFFERING,
+};
+
+struct boss_marwynAI : public boss_horAI
+{
+ boss_marwynAI(Creature *pCreature) : boss_horAI(pCreature) {}
+
+ void Reset()
+ {
+ boss_horAI::Reset();
+
+ if (pInstance)
+ pInstance->SetData(DATA_MARWYN_EVENT, NOT_STARTED);
+ }
+
+ void EnterCombat(Unit* who)
+ {
+ DoScriptText(SAY_AGGRO, me);
+ if (pInstance)
+ pInstance->SetData(DATA_MARWYN_EVENT, IN_PROGRESS);
+
+ events.ScheduleEvent(EVENT_OBLITERATE, 30000); // TODO Check timer
+ events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
+ events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000);
+ events.ScheduleEvent(EVENT_SHARED_SUFFERING, 20000); // TODO Check timer
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_DEATH, me);
+
+ if (pInstance)
+ pInstance->SetData(DATA_MARWYN_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ // Return since we have no target
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_OBLITERATE:
+ DoCast(SPELL_OBLITERATE);
+ events.ScheduleEvent(EVENT_OBLITERATE, 30000);
+ break;
+ case EVENT_WELL_OF_CORRUPTION:
+ DoCast(SPELL_WELL_OF_CORRUPTION);
+ events.ScheduleEvent(EVENT_WELL_OF_CORRUPTION, 13000);
+ break;
+ case EVENT_CORRUPTED_FLESH:
+ DoScriptText(RAND(SAY_CORRUPTED_FLESH_1,SAY_CORRUPTED_FLESH_2), me);
+ DoCast(SPELL_CORRUPTED_FLESH);
+ events.ScheduleEvent(EVENT_CORRUPTED_FLESH, 20000);
+ break;
+ case EVENT_SHARED_SUFFERING:
+ if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_SHARED_SUFFERING);
+ events.ScheduleEvent(EVENT_SHARED_SUFFERING, 20000);
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_boss_marwyn(Creature* pCreature)
+{
+ return new boss_marwynAI(pCreature);
+}
+
+void AddSC_boss_marwyn()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_marwyn";
+ newscript->GetAI = &GetAI_boss_marwyn;
+ newscript->RegisterSelf();
+}
diff --git a/src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp b/src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp
new file mode 100644
index 00000000000..fb3d3d5d752
--- /dev/null
+++ b/src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.cpp
@@ -0,0 +1,1022 @@
+/* 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 "halls_of_reflection.h"
+
+enum Yells
+{
+ SAY_JAINA_INTRO_1 = -1668001,
+ SAY_JAINA_INTRO_2 = -1668002,
+ SAY_JAINA_INTRO_3 = -1668003,
+ SAY_JAINA_INTRO_4 = -1668004,
+ SAY_UTHER_INTRO_A2_1 = -1668005,
+ SAY_JAINA_INTRO_5 = -1668006,
+ SAY_UTHER_INTRO_A2_2 = -1668007,
+ SAY_JAINA_INTRO_6 = -1668008,
+ SAY_UTHER_INTRO_A2_3 = -1668009,
+ SAY_JAINA_INTRO_7 = -1668010,
+ SAY_UTHER_INTRO_A2_4 = -1668011,
+ SAY_JAINA_INTRO_8 = -1668012,
+ SAY_UTHER_INTRO_A2_5 = -1668013,
+ SAY_JAINA_INTRO_9 = -1668014,
+ SAY_UTHER_INTRO_A2_6 = -1668015,
+ SAY_UTHER_INTRO_A2_7 = -1668016,
+ SAY_JAINA_INTRO_10 = -1668017,
+ SAY_UTHER_INTRO_A2_8 = -1668018,
+ SAY_JAINA_INTRO_11 = -1668019,
+ SAY_UTHER_INTRO_A2_9 = -1668020,
+
+ SAY_SYLVANAS_INTRO_1 = -1668021,
+ SAY_SYLVANAS_INTRO_2 = -1668022,
+ SAY_SYLVANAS_INTRO_3 = -1668023,
+ SAY_UTHER_INTRO_H2_1 = -1668024,
+ SAY_SYLVANAS_INTRO_4 = -1668025,
+ SAY_UTHER_INTRO_H2_2 = -1668026,
+ SAY_SYLVANAS_INTRO_5 = -1668027,
+ SAY_UTHER_INTRO_H2_3 = -1668028,
+ SAY_SYLVANAS_INTRO_6 = -1668029,
+ SAY_UTHER_INTRO_H2_4 = -1668030,
+ SAY_SYLVANAS_INTRO_7 = -1668031,
+ SAY_UTHER_INTRO_H2_5 = -1668032,
+ SAY_UTHER_INTRO_H2_6 = -1668033,
+ SAY_SYLVANAS_INTRO_8 = -1668034,
+ SAY_UTHER_INTRO_H2_7 = -1668035,
+
+ SAY_LK_INTRO_1 = -1668036,
+ SAY_LK_INTRO_2 = -1668037,
+ SAY_LK_INTRO_3 = -1668038,
+ SAY_FALRIC_INTRO_1 = -1668039,
+ SAY_MARWYN_INTRO_1 = -1668040,
+ SAY_FALRIC_INTRO_2 = -1668041,
+
+ SAY_JAINA_INTRO_END = -1668042,
+ SAY_SYLVANAS_INTRO_END = -1668043,
+};
+
+enum Events
+{
+ EVENT_NONE,
+
+ EVENT_START_INTRO,
+ EVENT_SKIP_INTRO,
+
+ EVENT_INTRO_A2_1,
+ EVENT_INTRO_A2_2,
+ EVENT_INTRO_A2_3,
+ EVENT_INTRO_A2_4,
+ EVENT_INTRO_A2_5,
+ EVENT_INTRO_A2_6,
+ EVENT_INTRO_A2_7,
+ EVENT_INTRO_A2_8,
+ EVENT_INTRO_A2_9,
+ EVENT_INTRO_A2_10,
+ EVENT_INTRO_A2_11,
+ EVENT_INTRO_A2_12,
+ EVENT_INTRO_A2_13,
+ EVENT_INTRO_A2_14,
+ EVENT_INTRO_A2_15,
+ EVENT_INTRO_A2_16,
+ EVENT_INTRO_A2_17,
+ EVENT_INTRO_A2_18,
+ EVENT_INTRO_A2_19,
+
+ EVENT_INTRO_H2_1,
+ EVENT_INTRO_H2_2,
+ EVENT_INTRO_H2_3,
+ EVENT_INTRO_H2_4,
+ EVENT_INTRO_H2_5,
+ EVENT_INTRO_H2_6,
+ EVENT_INTRO_H2_7,
+ EVENT_INTRO_H2_8,
+ EVENT_INTRO_H2_9,
+ EVENT_INTRO_H2_10,
+ EVENT_INTRO_H2_11,
+ EVENT_INTRO_H2_12,
+ EVENT_INTRO_H2_13,
+ EVENT_INTRO_H2_14,
+ EVENT_INTRO_H2_15,
+
+ EVENT_INTRO_LK_1,
+ EVENT_INTRO_LK_2,
+ EVENT_INTRO_LK_3,
+ EVENT_INTRO_LK_4,
+ EVENT_INTRO_LK_5,
+ EVENT_INTRO_LK_6,
+ EVENT_INTRO_LK_7,
+ EVENT_INTRO_LK_8,
+ EVENT_INTRO_LK_9,
+
+ EVENT_INTRO_END,
+};
+
+enum eEnum
+{
+ ACTION_START_INTRO,
+ ACTION_SKIP_INTRO,
+
+ QUEST_DELIVRANCE_FROM_THE_PIT_A2 = 24710,
+ QUEST_DELIVRANCE_FROM_THE_PIT_H2 = 24712,
+ QUEST_WRATH_OF_THE_LICH_KING_A2 = 24500,
+ QUEST_WRATH_OF_THE_LICH_KING_H2 = 24802,
+};
+
+static Position HallsofReflectionLocs[]=
+{
+ {5283.234863, 1990.946777, 707.695679, 0.929097}, // 2 Loralen Follows
+ {5408.031250, 2102.918213, 707.695251, 0.792756}, // 9 Sylvanas Follows
+ {5401.866699, 2110.837402, 707.695251, 0.800610}, // 10 Loralen follows
+};
+
+static Position SpawnPos = {5262.540527, 1949.693726, 707.695007, 0.808736}; // Jaina/Sylvanas Beginning Position
+static Position MoveThronePos = {5306.952148, 1998.499023, 709.341431, 1.277278}; // Jaina/Sylvanas walks to throne
+static Position UtherSpawnPos = {5308.310059, 2003.857178, 709.341431, 4.650315};
+static Position LichKingSpawnPos = {5362.917480, 2062.307129, 707.695374, 3.945812};
+static Position LichKingMoveThronePos = {5312.080566, 2009.172119, 709.341431, 3.973301}; // Lich King walks to throne
+static Position LichKingMoveAwayPos = {5400.069824, 2102.7131689, 707.69525, 0.843803}; // Lich King walks away
+
+// AI of Part1: handle the intro till start of gauntlet event.
+struct npc_jaina_or_sylvanas_horAI : public ScriptedAI
+{
+ npc_jaina_or_sylvanas_horAI(Creature *pCreature) : ScriptedAI(pCreature)
+ {
+ pInstance = me->GetInstanceData();
+ }
+
+ ScriptedInstance* pInstance;
+ uint64 uiUther;
+ uint64 uiLichKing;
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+
+ uiUther = 0;
+ uiLichKing = 0;
+
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->SetStandState(UNIT_STAND_STATE_STAND);
+ me->SetVisibility(VISIBILITY_ON);
+ }
+
+ void DoAction(const int32 actionId)
+ {
+ switch(actionId)
+ {
+ case ACTION_START_INTRO:
+ events.ScheduleEvent(EVENT_START_INTRO, 0);
+ break;
+ case ACTION_SKIP_INTRO:
+ events.ScheduleEvent(EVENT_SKIP_INTRO, 0);
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ events.Update(diff);
+ switch(events.ExecuteEvent())
+ {
+ case EVENT_START_INTRO:
+ me->GetMotionMaster()->MovePoint(0, MoveThronePos);
+ // Begining of intro is differents between factions as the speech sequence and timers are differents.
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ events.ScheduleEvent(EVENT_INTRO_A2_1, 0);
+ else
+ events.ScheduleEvent(EVENT_INTRO_H2_1, 0);
+ break;
+
+ // A2 Intro Events
+ case EVENT_INTRO_A2_1:
+ DoScriptText(SAY_JAINA_INTRO_3, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_2, 5000);
+ break;
+ case EVENT_INTRO_A2_2:
+ DoScriptText(SAY_JAINA_INTRO_4, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_3, 10000);
+ break;
+ case EVENT_INTRO_A2_3:
+ // TODO: she's doing some kind of spell casting emote
+ pInstance->HandleGameObject(pInstance->GetData64(DATA_FROSTMOURNE), true);
+ events.ScheduleEvent(EVENT_INTRO_A2_4, 10000);
+ break;
+ case EVENT_INTRO_A2_4:
+ // spawn UTHER during speach 2
+ if (Creature* pUther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ pUther->GetMotionMaster()->MoveIdle();
+ pUther->SetReactState(REACT_PASSIVE); // be sure he will not aggro arthas
+ uiUther = pUther->GetGUID();
+ }
+ events.ScheduleEvent(EVENT_INTRO_A2_5, 2000);
+ break;
+ case EVENT_INTRO_A2_5:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_1, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_6, 3000);
+ break;
+ case EVENT_INTRO_A2_6:
+ DoScriptText(SAY_JAINA_INTRO_5, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_7, 6000);
+ break;
+ case EVENT_INTRO_A2_7:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_2, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_8, 6500);
+ break;
+ case EVENT_INTRO_A2_8:
+ DoScriptText(SAY_JAINA_INTRO_6, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_9, 2000);
+ break;
+ case EVENT_INTRO_A2_9:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_3, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_10, 9000);
+ break;
+ case EVENT_INTRO_A2_10:
+ DoScriptText(SAY_JAINA_INTRO_7, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_11, 5000);
+ break;
+ case EVENT_INTRO_A2_11:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_4, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_12, 11000);
+ break;
+ case EVENT_INTRO_A2_12:
+ DoScriptText(SAY_JAINA_INTRO_8, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_13, 4000);
+ break;
+ case EVENT_INTRO_A2_13:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_5, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_14, 12500);
+ break;
+ case EVENT_INTRO_A2_14:
+ DoScriptText(SAY_JAINA_INTRO_9, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_15, 10000);
+ break;
+ case EVENT_INTRO_A2_15:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_6, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_16, 22000);
+ break;
+ case EVENT_INTRO_A2_16:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_A2_7, pUther);
+ events.ScheduleEvent(EVENT_INTRO_A2_17, 4000);
+ break;
+ case EVENT_INTRO_A2_17:
+ DoScriptText(SAY_JAINA_INTRO_10, me);
+ events.ScheduleEvent(EVENT_INTRO_A2_18, 2000);
+ break;
+ case EVENT_INTRO_A2_18:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ {
+ pUther->HandleEmoteCommand(EMOTE_ONESHOT_NO);
+ DoScriptText(SAY_UTHER_INTRO_A2_8, pUther);
+ }
+ events.ScheduleEvent(EVENT_INTRO_A2_19, 11000);
+ break;
+ case EVENT_INTRO_A2_19:
+ DoScriptText(SAY_JAINA_INTRO_11, me);
+ events.ScheduleEvent(EVENT_INTRO_LK_1, 2000);
+ break;
+
+ // H2 Intro Events
+ case EVENT_INTRO_H2_1:
+ DoScriptText(SAY_SYLVANAS_INTRO_1, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_2, 8000);
+ break;
+ case EVENT_INTRO_H2_2:
+ DoScriptText(SAY_SYLVANAS_INTRO_2, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_3, 6000);
+ break;
+ case EVENT_INTRO_H2_3:
+ DoScriptText(SAY_SYLVANAS_INTRO_3, me);
+ // TODO: she's doing some kind of spell casting emote
+ events.ScheduleEvent(EVENT_INTRO_H2_4, 6000);
+ break;
+ case EVENT_INTRO_H2_4:
+ // spawn UTHER during speach 2
+ if (Creature* pUther = me->SummonCreature(NPC_UTHER, UtherSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ pUther->GetMotionMaster()->MoveIdle();
+ pUther->SetReactState(REACT_PASSIVE); // be sure he will not aggro arthas
+ uiUther = pUther->GetGUID();
+ }
+ events.ScheduleEvent(EVENT_INTRO_H2_5, 2000);
+ break;
+ case EVENT_INTRO_H2_5:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_1, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_6, 11000);
+ break;
+ case EVENT_INTRO_H2_6:
+ DoScriptText(SAY_SYLVANAS_INTRO_4, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_7, 3000);
+ break;
+ case EVENT_INTRO_H2_7:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_2, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_8, 6000);
+ break;
+ case EVENT_INTRO_H2_8:
+ DoScriptText(SAY_SYLVANAS_INTRO_5, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_9, 5000);
+ break;
+ case EVENT_INTRO_H2_9:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_3, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_10, 19000);
+ break;
+ case EVENT_INTRO_H2_10:
+ DoScriptText(SAY_SYLVANAS_INTRO_6, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_11, 1500);
+ break;
+ case EVENT_INTRO_H2_11:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_4, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_12, 19500);
+ break;
+ case EVENT_INTRO_H2_12:
+ DoScriptText(SAY_SYLVANAS_INTRO_7, me);
+ events.ScheduleEvent(EVENT_INTRO_H2_13, 2000);
+ break;
+ case EVENT_INTRO_H2_13:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ {
+ pUther->HandleEmoteCommand(EMOTE_ONESHOT_NO);
+ DoScriptText(SAY_UTHER_INTRO_H2_5, pUther);
+ }
+ events.ScheduleEvent(EVENT_INTRO_H2_14, 12000);
+ break;
+ case EVENT_INTRO_H2_14:
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ DoScriptText(SAY_UTHER_INTRO_H2_6, pUther);
+ events.ScheduleEvent(EVENT_INTRO_H2_15, 8000);
+ break;
+ case EVENT_INTRO_H2_15:
+ DoScriptText(SAY_SYLVANAS_INTRO_8, me);
+ events.ScheduleEvent(EVENT_INTRO_LK_1, 2000);
+ break;
+
+ // Remaining Intro Events common for both faction
+ case EVENT_INTRO_LK_1:
+ // Spawn LK in front of door, and make him move to the sword.
+ if (Creature* pLichKing = me->SummonCreature(NPC_LICH_KING_EVENT, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
+ {
+ pLichKing->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos);
+ pLichKing->SetReactState(REACT_PASSIVE);
+ uiLichKing = pLichKing->GetGUID();
+ }
+
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ DoScriptText(SAY_UTHER_INTRO_A2_9, pUther);
+ else
+ DoScriptText(SAY_UTHER_INTRO_H2_7, pUther);
+
+ events.ScheduleEvent(EVENT_INTRO_LK_2, 11000);
+ break;
+
+ case EVENT_INTRO_LK_2:
+ if (Creature* pLichKing = me->GetCreature(*me, uiLichKing))
+ DoScriptText(SAY_LK_INTRO_1, pLichKing);
+ events.ScheduleEvent(EVENT_INTRO_LK_3, 2000);
+ break;
+
+ case EVENT_INTRO_LK_3:
+ // The Lich King banishes Uther to the abyss.
+ if (Creature* pUther = me->GetCreature(*me, uiUther))
+ {
+ pUther->DisappearAndDie();
+ uiUther = 0;
+ }
+
+ // He steps forward and removes the runeblade from the heap of skulls.
+
+ events.ScheduleEvent(EVENT_INTRO_LK_4, 4000);
+ break;
+
+ case EVENT_INTRO_LK_4:
+ if (Creature* pLichKing = me->GetCreature(*me, uiLichKing))
+ DoScriptText(SAY_LK_INTRO_2, pLichKing);
+ events.ScheduleEvent(EVENT_INTRO_LK_5, 10000);
+ break;
+
+ case EVENT_INTRO_LK_5:
+ // summon Falric and Marwyn. then go back to the door
+ if (Creature* pFalric = me->GetCreature(*me, pInstance->GetData64(DATA_FALRIC)))
+ pFalric->SetVisibility(VISIBILITY_ON);
+ if (Creature* pMarwyn = me->GetCreature(*me, pInstance->GetData64(DATA_MARWYN)))
+ pMarwyn->SetVisibility(VISIBILITY_ON);
+
+ if (Creature* pLichKing = me->GetCreature(*me, uiLichKing))
+ {
+ pLichKing->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
+ DoScriptText(SAY_LK_INTRO_3, pLichKing);
+ }
+
+ events.ScheduleEvent(EVENT_INTRO_LK_6, 8000);
+ break;
+
+ case EVENT_INTRO_LK_6:
+ if (Creature* pFalric = me->GetCreature(*me, pInstance->GetData64(DATA_FALRIC)))
+ DoScriptText(SAY_FALRIC_INTRO_1, pFalric);
+
+ events.ScheduleEvent(EVENT_INTRO_LK_7, 2000);
+ break;
+
+ case EVENT_INTRO_LK_7:
+ if (Creature* pMarwyn = me->GetCreature(*me, pInstance->GetData64(DATA_MARWYN)))
+ DoScriptText(SAY_MARWYN_INTRO_1, pMarwyn);
+
+ events.ScheduleEvent(EVENT_INTRO_LK_8, 2000);
+ break;
+
+ case EVENT_INTRO_LK_8:
+ if (Creature* pFalric = me->GetCreature(*me, pInstance->GetData64(DATA_FALRIC)))
+ DoScriptText(SAY_FALRIC_INTRO_2, pFalric);
+
+ events.ScheduleEvent(EVENT_INTRO_LK_9, 5000);
+ break;
+
+ case EVENT_INTRO_LK_9:
+ if (pInstance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE)
+ DoScriptText(SAY_JAINA_INTRO_END, me);
+ else
+ DoScriptText(SAY_SYLVANAS_INTRO_END, me);
+
+ me->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
+ // TODO: Loralen/Koreln shall run also
+ events.ScheduleEvent(EVENT_INTRO_END, 10000);
+ break;
+
+ case EVENT_INTRO_END:
+ if (pInstance)
+ pInstance->SetData(DATA_WAVE_COUNT, SPECIAL); // start first wave
+
+ // Loralen or Koreln disappearAndDie()
+ me->DisappearAndDie();
+ break;
+
+ case EVENT_SKIP_INTRO:
+ // TODO: implement
+
+ if (Creature* pFalric = me->GetCreature(*me, pInstance->GetData64(DATA_FALRIC)))
+ pFalric->SetVisibility(VISIBILITY_ON);
+ if (Creature* pMarwyn = me->GetCreature(*me, pInstance->GetData64(DATA_MARWYN)))
+ pMarwyn->SetVisibility(VISIBILITY_ON);
+
+ me->GetMotionMaster()->MovePoint(0, LichKingSpawnPos);
+ // TODO: Loralen/Koreln shall run also
+
+ events.ScheduleEvent(EVENT_INTRO_END, 15000);
+ break;
+ }
+ }
+};
+
+bool GossipHello_npc_sylvanas_hor(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_DELIVRANCE_FROM_THE_PIT_H2) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM( 0, "Can you remove the sword?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ // once last quest is completed, she offers this shortcut of the starting event
+ if (pPlayer->GetQuestStatus(QUEST_WRATH_OF_THE_LICH_KING_H2) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM( 0, "Dark Lady, I think I hear Arthas coming. Whatever you're going to do, do it quickly.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+
+ pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
+
+ return true;
+}
+
+bool GossipHello_npc_jaina_hor(Player* pPlayer, Creature* pCreature)
+{
+ if (pCreature->isQuestGiver())
+ pPlayer->PrepareQuestMenu(pCreature->GetGUID());
+
+ if (pPlayer->GetQuestStatus(QUEST_DELIVRANCE_FROM_THE_PIT_A2) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM( 0, "Can you remove the sword?", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+
+ // once last quest of the series is completed, she offers this shortcut of the starting event
+ if (pPlayer->GetQuestStatus(QUEST_WRATH_OF_THE_LICH_KING_A2) == QUEST_STATUS_COMPLETE)
+ pPlayer->ADD_GOSSIP_ITEM( 0, "My Lady, I think I hear Arthas coming. Whatever you're going to do, do it quickly.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
+
+ pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pCreature->GetGUID());
+ return true;
+}
+
+bool GossipSelect_npc_jaina_or_sylvanas_hor(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
+{
+ switch (uiAction)
+ {
+ case GOSSIP_ACTION_INFO_DEF+1:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ if (pCreature->AI())
+ pCreature->AI()->DoAction(ACTION_START_INTRO);
+ pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ break;
+ case GOSSIP_ACTION_INFO_DEF+2:
+ pPlayer->CLOSE_GOSSIP_MENU();
+ if (pCreature->AI())
+ pCreature->AI()->DoAction(ACTION_SKIP_INTRO);
+ pCreature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ break;
+ }
+
+ return true;
+}
+
+enum TrashSpells
+{
+ // Ghostly Priest
+ SPELL_SHADOW_WORD_PAIN = 72318,
+ SPELL_CIRCLE_OF_DESTRUCTION = 72320,
+ SPELL_COWER_IN_FEAR = 72321,
+ SPELL_DARK_MENDING = 72322,
+
+ // Phantom Mage
+ SPELL_FIREBALL = 72163,
+ SPELL_FLAMESTRIKE = 72169,
+ SPELL_FROSTBOLT = 72166,
+ SPELL_CHAINS_OF_ICE = 72121,
+ SPELL_HALLUCINATION = 72342,
+
+ // Phantom Hallucination (same as phantom mage + HALLUCINATION_2 when dies)
+ SPELL_HALLUCINATION_2 = 72344,
+
+ // Shadowy Mercenary
+ SPELL_SHADOW_STEP = 72326,
+ SPELL_DEADLY_POISON = 72329,
+ SPELL_ENVENOMED_DAGGER_THROW = 72333,
+ SPELL_KIDNEY_SHOT = 72335,
+
+ // Spectral Footman
+ SPELL_SPECTRAL_STRIKE = 72198,
+ SPELL_SHIELD_BASH = 72194,
+ SPELL_TORTURED_ENRAGE = 72203,
+
+ // Tortured Rifleman
+ SPELL_SHOOT = 72208,
+ SPELL_CURSED_ARROW = 72222,
+ SPELL_FROST_TRAP = 72215,
+ SPELL_ICE_SHOT = 72268,
+};
+
+enum TrashEvents
+{
+ EVENT_TRASH_NONE,
+
+ // Ghostly Priest
+ EVENT_SHADOW_WORD_PAIN,
+ EVENT_CIRCLE_OF_DESTRUCTION,
+ EVENT_COWER_IN_FEAR,
+ EVENT_DARK_MENDING,
+
+ // Phantom Mage
+ EVENT_FIREBALL,
+ EVENT_FLAMESTRIKE,
+ EVENT_FROSTBOLT,
+ EVENT_CHAINS_OF_ICE,
+ EVENT_HALLUCINATION,
+
+ // Shadowy Mercenary
+ EVENT_SHADOW_STEP,
+ EVENT_DEADLY_POISON,
+ EVENT_ENVENOMED_DAGGER_THROW,
+ EVENT_KIDNEY_SHOT,
+
+ // Spectral Footman
+ EVENT_SPECTRAL_STRIKE,
+ EVENT_SHIELD_BASH,
+ EVENT_TORTURED_ENRAGE,
+
+ // Tortured Rifleman
+ EVENT_SHOOT,
+ EVENT_CURSED_ARROW,
+ EVENT_FROST_TRAP,
+ EVENT_ICE_SHOT,
+};
+
+struct npc_ghostly_priestAI: public ScriptedAI
+{
+ npc_ghostly_priestAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000);
+ events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000);
+ events.ScheduleEvent(EVENT_DARK_MENDING, 20000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHADOW_WORD_PAIN:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_SHADOW_WORD_PAIN);
+ events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 8000);
+ return;
+ case EVENT_CIRCLE_OF_DESTRUCTION:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_CIRCLE_OF_DESTRUCTION);
+ events.ScheduleEvent(EVENT_CIRCLE_OF_DESTRUCTION, 12000);
+ return;
+ case EVENT_COWER_IN_FEAR:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_COWER_IN_FEAR);
+ events.ScheduleEvent(EVENT_COWER_IN_FEAR, 10000);
+ return;
+ case EVENT_DARK_MENDING:
+ // find an ally with missing HP
+ if (Unit *pTarget = DoSelectLowestHpFriendly(40, DUNGEON_MODE(30000,50000)))
+ {
+ DoCast(pTarget, SPELL_DARK_MENDING);
+ events.ScheduleEvent(EVENT_DARK_MENDING, 20000);
+ }
+ else
+ {
+ // no friendly unit with missing hp. re-check in just 5 sec.
+ events.ScheduleEvent(EVENT_DARK_MENDING, 5000);
+ }
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_phantom_mageAI: public ScriptedAI
+{
+ npc_phantom_mageAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_FIREBALL, 3000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_FLAMESTRIKE, 6000);
+ events.ScheduleEvent(EVENT_FROSTBOLT, 9000);
+ events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 12000);
+ events.ScheduleEvent(EVENT_HALLUCINATION, 40000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_FIREBALL:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_FIREBALL);
+ events.ScheduleEvent(EVENT_FIREBALL, 15000);
+ return;
+ case EVENT_FLAMESTRIKE:
+ DoCast(SPELL_FLAMESTRIKE);
+ events.ScheduleEvent(EVENT_FLAMESTRIKE, 15000);
+ return;
+ case EVENT_FROSTBOLT:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_FROSTBOLT);
+ events.ScheduleEvent(EVENT_FROSTBOLT, 15000);
+ return;
+ case EVENT_CHAINS_OF_ICE:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_CHAINS_OF_ICE);
+ events.ScheduleEvent(EVENT_CHAINS_OF_ICE, 15000);
+ return;
+ case EVENT_HALLUCINATION:
+ DoCast(SPELL_HALLUCINATION);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_phantom_hallucinationAI: public npc_phantom_mageAI
+{
+ npc_phantom_hallucinationAI(Creature *c) : npc_phantom_mageAI(c)
+ {
+ }
+
+ void JustDied(Unit * /*pWho*/)
+ {
+ DoCast(SPELL_HALLUCINATION_2);
+ }
+};
+
+struct npc_shadowy_mercenaryAI: public ScriptedAI
+{
+ npc_shadowy_mercenaryAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHADOW_STEP, 8000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_DEADLY_POISON, 5000);
+ events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000);
+ events.ScheduleEvent(EVENT_KIDNEY_SHOT, 12000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHADOW_STEP:
+ DoCast(SPELL_SHADOW_STEP);
+ events.ScheduleEvent(EVENT_SHADOW_STEP, 8000);
+ return;
+ case EVENT_DEADLY_POISON:
+ DoCast(me->getVictim(), SPELL_DEADLY_POISON);
+ events.ScheduleEvent(EVENT_DEADLY_POISON, 10000);
+ return;
+ case EVENT_ENVENOMED_DAGGER_THROW:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_ENVENOMED_DAGGER_THROW);
+ events.ScheduleEvent(EVENT_ENVENOMED_DAGGER_THROW, 10000);
+ return;
+ case EVENT_KIDNEY_SHOT:
+ DoCast(me->getVictim(), SPELL_KIDNEY_SHOT);
+ events.ScheduleEvent(EVENT_KIDNEY_SHOT, 10000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_spectral_footmanAI: public ScriptedAI
+{
+ npc_spectral_footmanAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_SHIELD_BASH, 10000);
+ events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SPECTRAL_STRIKE:
+ DoCast(me->getVictim(), SPELL_SPECTRAL_STRIKE);
+ events.ScheduleEvent(EVENT_SPECTRAL_STRIKE, 5000);
+ return;
+ case EVENT_SHIELD_BASH:
+ DoCast(me->getVictim(), SPELL_SHIELD_BASH);
+ events.ScheduleEvent(EVENT_SHIELD_BASH, 5000);
+ return;
+ case EVENT_TORTURED_ENRAGE:
+ DoCast(SPELL_TORTURED_ENRAGE);
+ events.ScheduleEvent(EVENT_TORTURED_ENRAGE, 15000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+struct npc_tortured_riflemanAI : public ScriptedAI
+{
+ npc_tortured_riflemanAI(Creature *c) : ScriptedAI(c)
+ {
+ }
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_SHOOT, 2000); // TODO: adjust timers
+ events.ScheduleEvent(EVENT_CURSED_ARROW, 10000);
+ events.ScheduleEvent(EVENT_FROST_TRAP, 1000);
+ events.ScheduleEvent(EVENT_ICE_SHOT, 15000);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch(eventId)
+ {
+ case EVENT_SHOOT:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_SHOOT);
+ events.ScheduleEvent(EVENT_SHOOT, 2000);
+ return;
+ case EVENT_CURSED_ARROW:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_CURSED_ARROW);
+ events.ScheduleEvent(EVENT_CURSED_ARROW, 10000);
+ return;
+ case EVENT_FROST_TRAP:
+ DoCast(SPELL_FROST_TRAP);
+ events.ScheduleEvent(EVENT_FROST_TRAP, 30000);
+ return;
+ case EVENT_ICE_SHOT:
+ if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
+ DoCast(pTarget, SPELL_ICE_SHOT);
+ events.ScheduleEvent(EVENT_ICE_SHOT, 15000);
+ return;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_npc_jaina_or_sylvanas_horAI(Creature* pCreature)
+{
+ return new npc_jaina_or_sylvanas_horAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_ghostly_priestAI(Creature* pCreature)
+{
+ return new npc_ghostly_priestAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_phantom_mageAI(Creature* pCreature)
+{
+ return new npc_phantom_mageAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_phantom_hallucinationAI(Creature* pCreature)
+{
+ return new npc_phantom_hallucinationAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_shadowy_mercenaryAI(Creature* pCreature)
+{
+ return new npc_shadowy_mercenaryAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_spectral_footmanAI(Creature* pCreature)
+{
+ return new npc_spectral_footmanAI(pCreature);
+}
+
+CreatureAI* GetAI_npc_tortured_riflemanAI(Creature* pCreature)
+{
+ return new npc_tortured_riflemanAI(pCreature);
+}
+
+void AddSC_halls_of_reflection()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name = "npc_sylvanas_hor_part1";
+ newscript->GetAI = &GetAI_npc_jaina_or_sylvanas_horAI;
+ newscript->pGossipHello = &GossipHello_npc_sylvanas_hor;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_or_sylvanas_hor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_jaina_hor_part1";
+ newscript->GetAI = &GetAI_npc_jaina_or_sylvanas_horAI;
+ newscript->pGossipHello = &GossipHello_npc_jaina_hor;
+ newscript->pGossipSelect = &GossipSelect_npc_jaina_or_sylvanas_hor;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_ghostly_priest";
+ newscript->GetAI = &GetAI_npc_ghostly_priestAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_phantom_mage";
+ newscript->GetAI = &GetAI_npc_phantom_mageAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_phantom_hallucination";
+ newscript->GetAI = &GetAI_npc_phantom_hallucinationAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_shadowy_mercenary";
+ newscript->GetAI = &GetAI_npc_shadowy_mercenaryAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_spectral_footman";
+ newscript->GetAI = &GetAI_npc_spectral_footmanAI;
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->Name = "npc_tortured_rifleman";
+ newscript->GetAI = &GetAI_npc_tortured_riflemanAI;
+ newscript->RegisterSelf();
+}
diff --git a/src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h b/src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h
index ac7ddc09b6d..46ae0cb283c 100644
--- a/src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h
+++ b/src/scripts/northrend/frozen_halls/halls_of_reflection/halls_of_reflection.h
@@ -16,16 +16,141 @@
#ifndef DEF_HALLS_OF_REFLECTION_H
#define DEF_HALLS_OF_REFLECTION_H
+
enum Data
{
DATA_FALRIC_EVENT,
DATA_MARWYN_EVENT,
- DATA_LICHKING_EVENT
+ DATA_LICHKING_EVENT,
+ DATA_WAVE_COUNT,
+ DATA_TEAM_IN_INSTANCE,
+};
+
+enum Data64
+{
+ DATA_FALRIC,
+ DATA_MARWYN,
+ DATA_LICHKING,
+ DATA_FROSTMOURNE,
};
+
enum Creatures
{
- CREATURE_FALRIC = 36494,
- CREATURE_MARWYN = 36476,
- CREATURE_LICHKING = 36658
+ NPC_FALRIC = 38112,
+ NPC_MARWYN = 38113,
+ NPC_LICH_KING_EVENT = 37226,
+ NPC_LICH_KING_BOSS = 36954,
+
+ NPC_UTHER = 37225,
+ NPC_JAINA_PART1 = 37221,
+ NPC_JAINA_PART2 = 36955,
+ NPC_SYLVANAS_PART1 = 37223,
+ NPC_SYLVANAS_PART2 = 37554,
+
+ NPC_WAVE_MERCENARY = 38177,
+ NPC_WAVE_FOOTMAN = 38173,
+ NPC_WAVE_RIFLEMAN = 38176,
+ NPC_WAVE_PRIEST = 38175,
+ NPC_WAVE_MAGE = 38172,
+};
+
+enum GameObjects
+{
+ GO_FROSTMOURNE = 202302,
+ GO_FROSTMOURNE_ALTAR = 202236,
+ GO_FRONT_DOOR = 201976,
+ GO_ARTHAS_DOOR = 197341,
};
+
+enum HorWorldStates
+{
+ WORLD_STATE_HOR = 4884,
+ WORLD_STATE_HOR_WAVE_COUNT = 4882,
+};
+
+// Common actions from Instance Script to Boss Script
+enum Actions
+{
+ ACTION_ENTER_COMBAT,
+};
+
+// Base class for FALRIC and MARWYN
+// handled the summonList and the notification events to/from the InstanceData
+struct boss_horAI : ScriptedAI
+{
+ boss_horAI(Creature *pCreature) : ScriptedAI(pCreature), summons(pCreature)
+ {
+ pInstance = me->GetInstanceData();
+ }
+
+ InstanceData* pInstance;
+ EventMap events;
+ SummonList summons;
+
+ void Reset()
+ {
+ events.Reset();
+ me->SetVisibility(VISIBILITY_OFF);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void DamageTaken(Unit *pWho, uint32 &uiDamage)
+ {
+ if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
+ uiDamage = 0;
+ }
+
+ void DoAction(const int32 actionID)
+ {
+ switch(actionID)
+ {
+ case ACTION_ENTER_COMBAT: // called by InstanceData when boss shall enter in combat.
+ // Just in case. Should have been done by InstanceData
+ me->SetVisibility(VISIBILITY_ON);
+
+ // Reset flags
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+
+ if (Unit *pUnit = me->SelectNearestTarget())
+ AttackStart(pUnit);
+
+ DoZoneInCombat();
+ break;
+ }
+ }
+
+ void JustSummoned(Creature *pSummoned)
+ {
+ summons.Summon(pSummoned);
+
+ if (Unit *pUnit = pSummoned->SelectNearestTarget())
+ {
+ if (pSummoned->AI())
+ pSummoned->AI()->AttackStart(pUnit);
+ else
+ {
+ pSummoned->GetMotionMaster()->MoveChase(pUnit);
+ pSummoned->Attack(pUnit, true);
+ }
+ }
+
+ if (pSummoned->AI())
+ pSummoned->AI()->DoZoneInCombat();
+ }
+
+ void SummonedCreatureDespawn(Creature *pSummoned)
+ {
+ summons.Despawn(pSummoned);
+ if (summons.empty())
+ {
+ if (pSummoned->isAlive())
+ pInstance->SetData(DATA_WAVE_COUNT, NOT_STARTED);
+ else
+ pInstance->SetData(DATA_WAVE_COUNT, SPECIAL);
+ }
+ }
+};
+
#endif
diff --git a/src/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp b/src/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
index 3c0c1321a77..7a5d2479b7c 100644
--- a/src/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
+++ b/src/scripts/northrend/frozen_halls/halls_of_reflection/instance_halls_of_reflection.cpp
@@ -25,61 +25,212 @@
2- The Lich King
*/
+enum eEnum
+{
+ ENCOUNTER_WAVE_MERCENARY = 6,
+ ENCOUNTER_WAVE_FOOTMAN = 10,
+ ENCOUNTER_WAVE_RIFLEMAN = 6,
+ ENCOUNTER_WAVE_PRIEST = 6,
+ ENCOUNTER_WAVE_MAGE = 6,
+};
+
+enum Events
+{
+ EVENT_NONE,
+ EVENT_NEXT_WAVE,
+ EVENT_START_LICH_KING,
+};
+
+static Position PriestSpawnPos[ENCOUNTER_WAVE_PRIEST] =
+{
+ {5277.74,2016.88,707.778,5.96903},
+ {5295.88,2040.34,707.778,5.07891},
+ {5320.37,1980.13,707.778,2.00713},
+ {5280.51,1997.84,707.778,0.296706},
+ {5302.45,2042.22,707.778,4.90438},
+ {5306.57,1977.47,707.778,1.50098},
+};
+
+static Position MageSpawnPos[ENCOUNTER_WAVE_MAGE] =
+{
+ {5312.75,2037.12,707.778,4.59022},
+ {5309.58,2042.67,707.778,4.69494},
+ {5275.08,2008.72,707.778,6.21337},
+ {5279.65,2004.66,707.778,0.069813},
+ {5275.48,2001.14,707.778,0.174533},
+ {5316.7,2041.55,707.778,4.50295},
+};
+
+static Position MercenarySpawnPos[ENCOUNTER_WAVE_MERCENARY] =
+{
+ {5302.25,1972.41,707.778,1.37881},
+ {5311.03,1972.23,707.778,1.64061},
+ {5277.36,1993.23,707.778,0.401426},
+ {5318.7,2036.11,707.778,4.2237},
+ {5335.72,1996.86,707.778,2.74017},
+ {5299.43,1979.01,707.778,1.23918},
+};
+
+static Position FootmenSpawnPos[ENCOUNTER_WAVE_FOOTMAN] =
+{
+ {5306.06,2037,707.778,4.81711},
+ {5344.15,2007.17,707.778,3.15905},
+ {5337.83,2010.06,707.778,3.22886},
+ {5343.29,1999.38,707.778,2.9147},
+ {5340.84,1992.46,707.778,2.75762},
+ {5325.07,1977.6,707.778,2.07694},
+ {5336.6,2017.28,707.778,3.47321},
+ {5313.82,1978.15,707.778,1.74533},
+ {5280.63,2012.16,707.778,6.05629},
+ {5322.96,2040.29,707.778,4.34587},
+};
+
+static Position RiflemanSpawnPos[ENCOUNTER_WAVE_RIFLEMAN] =
+{
+ {5343.47,2015.95,707.778,3.49066},
+ {5337.86,2003.4,707.778,2.98451},
+ {5319.16,1974,707.778,1.91986},
+ {5299.25,2036,707.778,5.02655},
+ {5295.64,1973.76,707.778,1.18682},
+ {5282.9,2019.6,707.778,5.88176},
+};
+
struct instance_halls_of_reflection : public ScriptedInstance
{
- instance_halls_of_reflection(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
+ instance_halls_of_reflection(Map* pMap) : ScriptedInstance(pMap) {};
uint64 uiFalric;
uint64 uiMarwyn;
- uint64 uiLichKing;
+ uint64 uiLichKingEvent;
+ uint64 uiJainaPart1;
+ uint64 uiSylvanasPart1;
- uint32 m_auiEncounter[MAX_ENCOUNTER];
+ uint64 uiFrostmourne;
+ uint64 uiFrostmourneAltar;
+ uint64 uiArthasDoor;
+ uint64 uiFrontDoor;
+
+ uint32 uiEncounter[MAX_ENCOUNTER];
+ uint32 uiTeamInInstance;
+ uint32 uiWaveCount;
+ bool bIntroDone;
+
+ EventMap events;
void Initialize()
{
+ events.Reset();
+
uiFalric = 0;
uiMarwyn = 0;
- uiLichKing = 0;
+ uiLichKingEvent = 0;
+ uiJainaPart1 = 0;
+ uiSylvanasPart1 = 0;
+
+ uiFrostmourne = 0;
+ uiFrostmourneAltar = 0;
+ uiArthasDoor = 0;
+ uiFrontDoor = 0;
+ uiTeamInInstance = 0;
+ uiWaveCount = 0;
+ bIntroDone = false;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- m_auiEncounter[i] = NOT_STARTED;
+ uiEncounter[i] = NOT_STARTED;
}
- void OnCreatureCreate(Creature* pCreature, bool /*add*/)
+ void OnCreatureCreate(Creature* pCreature, bool add)
{
+ if (!add)
+ return;
+
+ Map::PlayerList const &players = instance->GetPlayers();
+ if (!players.isEmpty())
+ if (Player* pPlayer = players.begin()->getSource())
+ uiTeamInInstance = pPlayer->GetTeam();
+
switch(pCreature->GetEntry())
{
- case CREATURE_FALRIC:
+ case NPC_FALRIC:
uiFalric = pCreature->GetGUID();
break;
- case CREATURE_MARWYN:
+ case NPC_MARWYN:
uiMarwyn = pCreature->GetGUID();
break;
- case CREATURE_LICHKING:
- uiLichKing = pCreature->GetGUID();
+ case NPC_LICH_KING_EVENT:
+ uiLichKingEvent = pCreature->GetGUID();
+ break;
+ case NPC_JAINA_PART1:
+ uiJainaPart1 = pCreature->GetGUID();
+ break;
+ case NPC_SYLVANAS_PART1:
+ uiSylvanasPart1 = pCreature->GetGUID();
break;
}
}
-/*
+
void OnGameObjectCreate(GameObject* pGo, bool add)
{
+ if (!add)
+ return;
+
+ // TODO: init state depending on encounters
switch(pGo->GetEntry())
{
+ case GO_FROSTMOURNE:
+ uiFrostmourne = pGo->GetGUID();
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ HandleGameObject(0, false, pGo);
+ break;
+ case GO_FROSTMOURNE_ALTAR:
+ uiFrostmourneAltar = pGo->GetGUID();
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ HandleGameObject(0, true, pGo);
+ break;
+ case GO_FRONT_DOOR:
+ uiFrontDoor = pGo->GetGUID();
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+ HandleGameObject(0, true, pGo);
+ break;
+ case GO_ARTHAS_DOOR:
+ uiArthasDoor = pGo->GetGUID();
+ pGo->SetFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
+
+ if (uiEncounter[1] == DONE)
+ HandleGameObject(0, true, pGo);
+ else
+ HandleGameObject(0, false, pGo);
+ break;
}
}
-*/
+
void SetData(uint32 type, uint32 data)
{
+ if (type == DATA_WAVE_COUNT && data == SPECIAL)
+ {
+ bIntroDone = true;
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
+ return;
+ }
+
+
+ if (uiWaveCount && data == NOT_STARTED)
+ DoWipe();
+
switch(type)
{
case DATA_FALRIC_EVENT:
- m_auiEncounter[0] = data;
+ uiEncounter[0] = data;
+ if (data == DONE)
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 60000);
break;
case DATA_MARWYN_EVENT:
- m_auiEncounter[1] = data;
+ uiEncounter[1] = data;
+ if (data == DONE)
+ HandleGameObject(uiArthasDoor, true);
break;
case DATA_LICHKING_EVENT:
- m_auiEncounter[2] = data;
+ uiEncounter[2] = data;
break;
}
@@ -91,29 +242,35 @@ struct instance_halls_of_reflection : public ScriptedInstance
{
switch(type)
{
- case DATA_FALRIC_EVENT: return m_auiEncounter[0];
- case DATA_MARWYN_EVENT: return m_auiEncounter[1];
- case DATA_LICHKING_EVENT: return m_auiEncounter[2];
+ case DATA_FALRIC_EVENT: return uiEncounter[0];
+ case DATA_MARWYN_EVENT: return uiEncounter[1];
+ case DATA_LICHKING_EVENT: return uiEncounter[2];
+ case DATA_WAVE_COUNT: return uiWaveCount;
+ case DATA_TEAM_IN_INSTANCE: return uiTeamInInstance;
}
return 0;
}
-/*
+
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
+ case DATA_FALRIC: return uiFalric;
+ case DATA_MARWYN: return uiMarwyn;
+ case DATA_LICHKING: return uiLichKingEvent;
+ case DATA_FROSTMOURNE: return uiFrostmourne;
}
return 0;
}
-*/
+
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
- saveStream << "H R " << m_auiEncounter[0] << " " << m_auiEncounter[1] << m_auiEncounter[2];
+ saveStream << "H R 1 " << uiEncounter[0] << " " << uiEncounter[1] << " " << uiEncounter[2];
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
@@ -130,25 +287,133 @@ struct instance_halls_of_reflection : public ScriptedInstance
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
+ uint16 version;
uint16 data0, data1, data2;
std::istringstream loadStream(in);
- loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2;
+ loadStream >> dataHead1 >> dataHead2 >> version >> data0 >> data1 >> data2;
if (dataHead1 == 'H' && dataHead2 == 'R')
{
- 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;
+ if (uiEncounter[0] == DONE || uiEncounter[1] == DONE)
+ bIntroDone = true;
+
OUT_LOAD_INST_DATA_COMPLETE;
}
+
+ void AddWave()
+ {
+ DoUpdateWorldState(WORLD_STATE_HOR, 1);
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount);
+
+ switch(uiWaveCount)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ if (Creature *pFalric = instance->GetCreature(uiFalric))
+ SpawnWave(pFalric);
+ break;
+ case 5:
+ if (GetData(DATA_FALRIC_EVENT) == DONE)
+ events.ScheduleEvent(EVENT_NEXT_WAVE, 10000);
+ else if (Creature *pFalric = instance->GetCreature(uiFalric))
+ if (pFalric->AI())
+ pFalric->AI()->DoAction(ACTION_ENTER_COMBAT);
+ break;
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ if (Creature *pMarwyn = instance->GetCreature(uiMarwyn))
+ SpawnWave(pMarwyn);
+ break;
+ case 10:
+ if (GetData(DATA_MARWYN_EVENT) != DONE) // wave should not have been started if DONE. Check anyway to avoid bug exploit!
+ if (Creature *pMarwyn = instance->GetCreature(uiMarwyn))
+ if (pMarwyn->AI())
+ pMarwyn->AI()->DoAction(ACTION_ENTER_COMBAT);
+ break;
+ }
+ }
+
+ // Wipe has been detected. Perform cleanup and reset.
+ void DoWipe()
+ {
+ uiWaveCount = 0;
+ events.Reset();
+ DoUpdateWorldState(WORLD_STATE_HOR, 1);
+ DoUpdateWorldState(WORLD_STATE_HOR_WAVE_COUNT, uiWaveCount);
+ HandleGameObject(uiFrontDoor, true);
+
+ // TODO
+ // in case of wipe, the event is normally restarted by jumping into the center of the room.
+ // As I can't find a trigger area there, just respawn Jaina/Sylvanas so the event may be restarted.
+ if (Creature* pJaina = instance->GetCreature(uiJainaPart1))
+ pJaina->Respawn();
+ if (Creature* pSylvanas = instance->GetCreature(uiSylvanasPart1))
+ pSylvanas->Respawn();
+
+ if (Creature* pFalric = instance->GetCreature(uiFalric))
+ pFalric->SetVisibility(VISIBILITY_OFF);
+ if (Creature* pMarwyn = instance->GetCreature(uiMarwyn))
+ pMarwyn->SetVisibility(VISIBILITY_OFF);
+ }
+
+ // spawn a wave on behalf of the summoner.
+ void SpawnWave(Creature *pSummoner)
+ {
+ uint32 index;
+
+ pSummoner->SetVisibility(VISIBILITY_ON);
+
+ // TODO: do composition at random. # of spawn also depends on uiWaveCount
+ // As of now, it is just one of each.
+ index = urand(0,ENCOUNTER_WAVE_MERCENARY-1);
+ pSummoner->SummonCreature(NPC_WAVE_MERCENARY, MercenarySpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ index = urand(0,ENCOUNTER_WAVE_FOOTMAN-1);
+ pSummoner->SummonCreature(NPC_WAVE_FOOTMAN, FootmenSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ index = urand(0,ENCOUNTER_WAVE_RIFLEMAN-1);
+ pSummoner->SummonCreature(NPC_WAVE_RIFLEMAN, RiflemanSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ index = urand(0,ENCOUNTER_WAVE_PRIEST-1);
+ pSummoner->SummonCreature(NPC_WAVE_PRIEST, PriestSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+
+ index = urand(0,ENCOUNTER_WAVE_MAGE-1);
+ pSummoner->SummonCreature(NPC_WAVE_MAGE, MageSpawnPos[index], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 0);
+ }
+
+ void Update(uint32 diff)
+ {
+ if (!instance->HavePlayers())
+ return;
+
+ events.Update(diff);
+
+ switch(uint32 eventId = events.ExecuteEvent())
+ {
+ case EVENT_NEXT_WAVE:
+ uiWaveCount++;
+ AddWave();
+ break;
+ case EVENT_START_LICH_KING:
+ // TODO
+ break;
+ }
+ }
};
InstanceData* GetInstanceData_instance_halls_of_reflection(Map* pMap)
@@ -156,7 +421,7 @@ InstanceData* GetInstanceData_instance_halls_of_reflection(Map* pMap)
return new instance_halls_of_reflection(pMap);
}
-void AddSC_halls_of_reflection()
+void AddSC_instance_halls_of_reflection()
{
Script *newscript;
newscript = new Script;
diff --git a/win/VC90/game.vcproj b/win/VC90/game.vcproj
index 3d3c96ad3be..13e2d79f83f 100644
--- a/win/VC90/game.vcproj
+++ b/win/VC90/game.vcproj
@@ -3240,6 +3240,18 @@
Name="Halls of Reflection"
>
<File
+ RelativePath="..\..\src\scripts\northrend\frozen_halls\halls_of_reflection\boss_falric.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\scripts\northrend\frozen_halls\halls_of_reflection\boss_marwyn.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\scripts\northrend\frozen_halls\halls_of_reflection\halls_of_reflection.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\src\scripts\northrend\frozen_halls\halls_of_reflection\halls_of_reflection.h"
>
</File>