aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/scripts/world_scripts_full.sql18
-rw-r--r--sql/updates/world/2011_05_13_04_world_areatrigger_scripts.sql5
-rw-r--r--sql/updates/world/2011_05_13_04_world_instance_misc.sql83
-rw-r--r--sql/updates/world/2011_05_13_04_world_scriptname.sql8
-rw-r--r--sql/updates/world/2011_05_13_04_world_spell_script_names.sql7
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp1263
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h47
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp46
8 files changed, 1470 insertions, 7 deletions
diff --git a/sql/scripts/world_scripts_full.sql b/sql/scripts/world_scripts_full.sql
index 66673c51bc9..09d3001aa93 100644
--- a/sql/scripts/world_scripts_full.sql
+++ b/sql/scripts/world_scripts_full.sql
@@ -9,7 +9,7 @@ UPDATE `gameobject_template` SET `ScriptName`='';
UPDATE `outdoorpvp_template` SET `ScriptName`='';
/* AREA TRIGGERS */
-DELETE FROM `areatrigger_scripts` WHERE `entry` IN (822,5284,5285,5286,5287,4871,4872,4873,5108,5332,5338,5334,5340,5369,5423,5633,5604,5698,5649,5729);
+DELETE FROM `areatrigger_scripts` WHERE `entry` IN (822,5284,5285,5286,5287,4871,4872,4873,5108,5332,5338,5334,5340,5369,5423,5633,5604,5698,5649,5729,5616,5617,5618);
DELETE FROM `areatrigger_scripts` WHERE `entry` BETWEEN 1726 AND 1740;
INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES
(822, 'at_map_chamber'),
@@ -46,7 +46,10 @@ INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES
(5604, 'at_sindragosa_lair'),
(5698, 'at_icc_saurfang_portal'),
(5649, 'at_icc_shutdown_traps'),
-(5729, 'at_icc_start_blood_quickening');
+(5729, 'at_icc_start_blood_quickening'),
+(5616,'at_icc_start_frostwing_gauntlet'),
+(5617,'at_icc_start_frostwing_gauntlet'),
+(5618,'at_icc_start_frostwing_gauntlet');
/* WORLD BOSS */
UPDATE `creature_template` SET `ScriptName`='boss_ysondre' WHERE `entry`=14887;
@@ -880,6 +883,14 @@ UPDATE `creature_template` SET `ScriptName`='npc_kinetic_bomb' WHERE `entry`=384
UPDATE `creature_template` SET `ScriptName`='npc_dark_nucleus' WHERE `entry`=38369;
UPDATE `creature_template` SET `ScriptName`='npc_ball_of_flame' WHERE `entry` IN (38332,38451);
UPDATE `creature_template` SET `ScriptName`='boss_blood_queen_lana_thel' WHERE `entry`=37955;
+UPDATE `creature_template` SET `ScriptName`='boss_sister_svalna' WHERE `entry`=37126;
+UPDATE `creature_template` SET `ScriptName`='npc_crok_scourgebane' WHERE `entry`=37129;
+UPDATE `creature_template` SET `ScriptName`='npc_captain_arnath' WHERE `entry`=37122;
+UPDATE `creature_template` SET `ScriptName`='npc_captain_brandon' WHERE `entry`=37123;
+UPDATE `creature_template` SET `ScriptName`='npc_captain_grondel' WHERE `entry`=37124;
+UPDATE `creature_template` SET `ScriptName`='npc_captain_rupert' WHERE `entry`=37125;
+UPDATE `creature_template` SET `ScriptName`='npc_frostwing_vrykul' WHERE `entry` IN (37132,38125,37127,37134,37133);
+UPDATE `creature_template` SET `ScriptName`='npc_impaling_spear' WHERE `entry`=38248;
UPDATE `creature_template` SET `ScriptName`='boss_sindragosa' WHERE `entry`=36853;
UPDATE `creature_template` SET `ScriptName`='npc_ice_tomb' WHERE `entry`=36980;
UPDATE `creature_template` SET `ScriptName`='npc_spinestalker' WHERE `entry`=37534;
@@ -2070,6 +2081,9 @@ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
( 71390, 'spell_blood_queen_pact_of_the_darkfallen'),
( 71340, 'spell_blood_queen_pact_of_the_darkfallen_dmg'),
( 71341, 'spell_blood_queen_pact_of_the_darkfallen_dmg_target'),
+( 70078, 'spell_svalna_caress_of_death'),
+( 70053, 'spell_svalna_revive_champion'),
+( 71462, 'spell_svalna_remove_spear'),
( 71357, 'spell_frostwarden_handler_order_whelp'),
( 71350, 'spell_frostwarden_handler_focus_fire'),
( 71376, 'spell_rimefang_icy_blast'),
diff --git a/sql/updates/world/2011_05_13_04_world_areatrigger_scripts.sql b/sql/updates/world/2011_05_13_04_world_areatrigger_scripts.sql
new file mode 100644
index 00000000000..ff81007753c
--- /dev/null
+++ b/sql/updates/world/2011_05_13_04_world_areatrigger_scripts.sql
@@ -0,0 +1,5 @@
+DELETE FROM `areatrigger_scripts` WHERE `entry` BETWEEN 5616 AND 5618;
+INSERT INTO `areatrigger_scripts` (`entry`,`ScriptName`) VALUES
+(5616,'at_icc_start_frostwing_gauntlet'),
+(5617,'at_icc_start_frostwing_gauntlet'),
+(5618,'at_icc_start_frostwing_gauntlet');
diff --git a/sql/updates/world/2011_05_13_04_world_instance_misc.sql b/sql/updates/world/2011_05_13_04_world_instance_misc.sql
new file mode 100644
index 00000000000..3956de0f35b
--- /dev/null
+++ b/sql/updates/world/2011_05_13_04_world_instance_misc.sql
@@ -0,0 +1,83 @@
+-- delete excessive spawns
+DELETE FROM `creature` WHERE `guid` IN (137758,137759);
+DELETE FROM `creature_addon` WHERE `guid` IN (137758,137759);
+DELETE FROM `linked_respawn` WHERE `guid` IN (137758,137759) AND `linkType`=0;
+
+UPDATE `creature_addon` SET `auras`='70203 71465' WHERE `guid`=137753; -- Sister Svalna
+
+DELETE FROM `creature_text` WHERE `entry` IN (37126,37129,37122,37123,37124,37125);
+INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES
+(37126,0,0, 'You may have once fought beside me, Crok, but now you are nothing more than a traitor. Come, your second death approaches!',1,0,0,0,0,17017, 'Sister Svalna - SAY_EVENT_START'),
+(37126,1,0, 'Miserable creatures! Die!',1,0,0,0,0,17018, 'Sister Svalna - SAY_KILL_CAPTAIN'),
+(37126,2,0, 'Foolish Crok. You brought my reinforcements with you. Arise, Argent Champions, and serve the Lich King in death!',1,0,0,0,0,17019, 'Sister Svanlna - SAY_RESURRECT_CAPTAINS'),
+(37126,3,0, 'Come, Scourgebane. I''ll show the master which of us is truly worthy of the title of \"Champion\"!',1,0,0,0,0,17020, 'Sister Svalna - SAY_AGGRO'),
+(37126,4,0, 'What a pitiful choice of an ally, Crok!',1,0,0,0,0,17021, 'Sister Svalna - SAY_KILL'),
+(37126,5,0, 'What? They died so easily? No matter.',1,0,0,0,0,17022, 'Sister Svalna - SAY_CAPTAIN_DEATH'),
+(37126,6,0, 'Perhaps... you were right, Crok.',1,0,0,0,0,17023, 'Sister Svalna - SAY_DEATH'),
+(37126,7,0, '%s has impaled $N!',3,0,0,0,0,0, 'Sister Svalna - EMOTE_SVALNA_IMPALE'),
+(37126,8,0, '%s''s Aether Shield has been shattered by $N!',3,0,0,0,0,0, 'Sister Svalna - EMOTE_SVALNA_BROKEN_SHIELD'),
+(37129,0,0, 'Ready your arms, my Argent Brothers. The Vrykul will protect the Frost Queen with their lives.',1,0,0,0,0,16819, 'Crok Scourgebane - SAY_CROK_INTRO_1'),
+(37129,1,0, 'Enough idle banter! Our champions have arrived - support them as we push our way through the hall!',1,0,0,0,0,16820, 'Crok Scourgebane - SAY_CROK_INTRO_3'),
+(37129,2,0, 'Draw them back to us, and we''ll assist you.',1,0,0,0,0,16821, 'Crok Scourgebane - SAY_CROK_COMBAT_WP_0'),
+(37129,3,0, 'Quickly, push on!',1,0,0,0,0,16823, 'Crok Scourgebane - SAY_CROK_COMBAT_WP_1'),
+(37129,4,0, 'Her reinforcements will arrive shortly, we must bring her down quickly!',1,0,0,0,0,16824, 'Crok Scourgebane - SAY_CROK_FINAL_WP'),
+(37129,5,0, 'I''ll draw her attacks. Return our brothers to their graves, then help me bring her down!',1,0,0,15,0,16826, 'Crok Scourgebane - SAY_CROK_COMBAT_SVALNA'),
+(37129,6,0, 'I must rest for a moment',1,0,0,0,0,16826, 'Crok Scourgebane - SAY_CROK_WEAKENING_GAUNTLET'),
+(37129,7,0, 'Champions, I cannot hold her back any longer!',1,0,0,0,0,16827, 'Crok Scourgebane - SAY_CROK_WEAKENING_SVALNA'),
+(37129,8,0, 'Vengeance alone... was not enough!',1,0,0,0,0,16828, 'Crok Scourgebane - SAY_CROK_DEATH'),
+(37122,0,0, 'Never... could reach... the top shelf...',1,0,0,0,0,16586, 'Captain Arnath - SAY_ARNATH_DEATH'),
+(37122,1,0, 'You miserable fools never did manage to select a decent bat wing.',1,0,0,0,0,16587, 'Captain Arnath - SAY_ARNATH_RESURRECTED'),
+(37122,2,0, 'THAT was for bringing me spoiled spider ichor!',1,0,0,0,0,16588, 'Captain Arnath - SAY_ARNATH_KILL'),
+(37122,3,0, 'Don''t... let Finklestein use me... for his potions...',1,0,0,0,0,16589, 'Captain Arnath - SAY_ARNATH_SECOND_DEATH'),
+(37122,4,0, 'The loss of our comrades was unpreventable. They lived and died in the service of the Argent Crusade.',1,0,0,0,0,16590, 'Captain Arnath - SAY_ARNATH_SURVIVE_TALK'),
+(37122,5,0, 'Even dying here beats spending another day collecting reagents for that madman, Finklestein.',1,0,0,0,0,16585, 'Captain Arnath - SAY_ARNATH_INTRO_2'),
+(37123,0,0, 'No amount of healing can save me now. Fight on, brothers...',1,0,0,0,0,16810, 'Captain Brandon - SAY_BRANDON_DEATH'),
+(37123,1,0, 'What? This strength...? All of the pain is gone! You... must join me in the eternal embrace of death!',1,0,0,0,0,16811, 'Captain Brandon - SAY_BRANDON_RESURRECTED'),
+(37123,2,0, 'It doesn''t hurt anymore, does it?',1,0,0,0,0,16812, 'Captain Brandon - SAY_BRANDON_KILL'),
+(37123,3,0, 'I''m sorry...',1,0,0,0,0,16813, 'Captain Brandon - SAY_BRANDON_SECOND_DEATH'),
+(37123,4,0, 'You have done much in this war against the Scourge. May the light embrace you.',1,0,0,0,0,16815, 'Captain Brandon - SAY_BRANDON_SURVIVE_TALK'),
+(37124,0,0, 'Please... burn my remains. Let me live warm in the afterlife...',1,0,0,0,0,16844, 'Captain Grondel - SAY_GRONDEL_DEATH'),
+(37124,1,0, 'No! Why was I denied a death by flame? You must all BURN!',1,0,0,0,0,16845, 'Captain Grondel - SAY_GRONDEL_RESURRECTED'),
+(37124,2,0, 'Can you feel the burn?',1,0,0,0,0,16846, 'Captain Grondel - SAY_GRONDEL_KILL'),
+(37124,3,0, 'What... have I done? No!',1,0,0,0,0,16847, 'Captain Grondel - SAY_GRONDEL_SECOND_DEATH'),
+(37124,4,0, 'What can possibly redeem this unholy place? Thank you...',1,0,0,0,0,16849, 'Captain Grondel - SAY_GRONDEL_SURVIVE_TALK'),
+(37125,0,0, 'It was... a worthy afterlife.',1,0,0,0,0,16998, 'Captain Rupert - SAY_RUPERT_DEATH'),
+(37125,1,0, 'There is no escaping the Lich King''s will. Prepare for an explosive encounter!',1,0,0,0,0,16999, 'Captain Rupert - SAY_RUPERT_RESURRECTED'),
+(37125,2,0, 'So that''s what happens when you stand too close to a bomb!',1,0,0,0,0,17000, 'Captain Rupert - SAY_RUPERT_KILL'),
+(37125,3,0, 'What an... explosive ending!',1,0,0,0,0,17001, 'Captain Rupert - SAY_RUPERT_SECOND_DEATH'),
+(37125,4,0, 'Beware the dangers that lie ahead... and do try to remain in one piece.',1,0,0,0,0,17003, 'Captain Rupert - SAY_RUPERT_SURVIVE_TALK');
+
+DELETE FROM `script_waypoint` WHERE `entry`=37129;
+INSERT INTO `script_waypoint` (`entry`,`pointid`,`location_x`,`location_y`,`location_z`,`waittime`,`point_comment`) VALUES
+(37129,0,4356.90,2648.00,350.285,0, 'Crok Scourgebane - at first trash pack'),
+(37129,1,4357.00,2582.17,351.101,0, 'Crok Scourgebane - at second trash pack'),
+(37129,2,4357.21,2555.91,354.478,0, NULL),
+(37129,3,4357.09,2547.81,354.766,0, NULL),
+(37129,4,4356.88,2512.40,358.436,0, 'Crok Scourgebane - at Sister Svalna');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (70078,70053);
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=18 AND `SourceEntry`=50307;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
+(13,0,70078,0,18,1,37122,0,0, '', 'Sister Svalna - Caress of Death'),
+(13,0,70078,0,18,1,37123,0,0, '', 'Sister Svalna - Caress of Death'),
+(13,0,70078,0,18,1,37124,0,0, '', 'Sister Svalna - Caress of Death'),
+(13,0,70078,0,18,1,37125,0,0, '', 'Sister Svalna - Caress of Death'),
+(13,0,70053,0,18,1,37122,0,0, '', 'Sister Svalna - Revive Champion'),
+(13,0,70053,0,18,1,37123,0,0, '', 'Sister Svalna - Revive Champion'),
+(13,0,70053,0,18,1,37124,0,0, '', 'Sister Svalna - Revive Champion'),
+(13,0,70053,0,18,1,37125,0,0, '', 'Sister Svalna - Revive Champion'),
+(18,0,50307,0,24,1,37126,0,0, '', 'Infernal Spear- Sister Svalna target');
+
+UPDATE `creature_template` SET `difficulty_entry_1`=38349,`minlevel`=81,`maxlevel`=81,`exp`=2,`faction_A`=2209,`faction_H`=2209,`unit_class`=2,`mindmg`=425,`maxdmg`=602,`attackpower`=670,`baseattacktime`=1500,`minrangedmg`=351,`maxrangedmg`=511,`rangedattackpower`=86,`equipment_id`=2423 WHERE `entry`=37491; -- Captain Arnath (Undead)
+UPDATE `creature_template` SET `minlevel`=81,`maxlevel`=81,`exp`=2,`faction_A`=2209,`faction_H`=2209,`unit_class`=2,`mindmg`=425,`maxdmg`=602,`attackpower`=670,`baseattacktime`=1500,`minrangedmg`=351,`maxrangedmg`=511,`dmg_multiplier`=13,`rangedattackpower`=86,`dynamicflags`=8,`equipment_id`=2423 WHERE `entry`=38349; -- Captain Arnath (Undead)
+UPDATE `creature_template` SET `difficulty_entry_1`=38350,`minlevel`=81,`maxlevel`=81,`exp`=2,`faction_A`=2209,`faction_H`=2209,`unit_class`=2,`mindmg`=425,`maxdmg`=602,`attackpower`=670,`baseattacktime`=1500,`minrangedmg`=351,`maxrangedmg`=511,`rangedattackpower`=86,`equipment_id`=2424 WHERE `entry`=37493; -- Captain Brandon (Undead)
+UPDATE `creature_template` SET `minlevel`=81,`maxlevel`=81,`exp`=2,`faction_A`=2209,`faction_H`=2209,`unit_class`=2,`mindmg`=425,`maxdmg`=602,`attackpower`=670,`baseattacktime`=1500,`minrangedmg`=351,`maxrangedmg`=511,`dmg_multiplier`=13,`rangedattackpower`=86,`dynamicflags`=8,`equipment_id`=2424 WHERE `entry`=38350; -- Captain Brandon (Undead)
+UPDATE `creature_template` SET `difficulty_entry_1`=38351,`minlevel`=81,`maxlevel`=81,`exp`=2,`faction_A`=2209,`faction_H`=2209,`mindmg`=464,`maxdmg`=604,`attackpower`=708,`baseattacktime`=1500,`minrangedmg`=353,`maxrangedmg`=512,`rangedattackpower`=112,`equipment_id`=2425 WHERE `entry`=37494; -- Captain Grondel (Undead)
+UPDATE `creature_template` SET `minlevel`=81,`maxlevel`=81,`exp`=2,`faction_A`=2209,`faction_H`=2209,`mindmg`=464,`maxdmg`=604,`attackpower`=708,`baseattacktime`=1500,`minrangedmg`=353,`maxrangedmg`=512,`dmg_multiplier`=13,`rangedattackpower`=112,`dynamicflags`=8,`equipment_id`=2425 WHERE `entry`=38351; -- Captain Grondel (Undead)
+UPDATE `creature_template` SET `difficulty_entry_1`=38352,`minlevel`=81,`maxlevel`=81,`exp`=2,`faction_A`=2209,`faction_H`=2209,`mindmg`=464,`maxdmg`=604,`attackpower`=708,`baseattacktime`=1500,`minrangedmg`=353,`maxrangedmg`=512,`rangedattackpower`=112,`equipment_id`=2426 WHERE `entry`=37495; -- Captain Rupert (Undead)
+UPDATE `creature_template` SET `minlevel`=81,`maxlevel`=81,`exp`=2,`faction_A`=2209,`faction_H`=2209,`mindmg`=464,`maxdmg`=604,`attackpower`=708,`baseattacktime`=1500,`minrangedmg`=353,`maxrangedmg`=512,`dmg_multiplier`=13,`rangedattackpower`=112,`dynamicflags`=8,`equipment_id`=2426 WHERE `entry`=38352; -- Captain Rupert (Undead)
+UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`faction_A`=2209,`faction_H`=2209,`npcflag`=`npcflag`|16777216,`dynamicflags`=0,`equipment_id`=2364 WHERE `entry`=38248; -- Impaling Spear
+
+DELETE FROM `npc_spellclick_spells` WHERE `npc_entry`=38248;
+INSERT INTO `npc_spellclick_spells` (`npc_entry`,`spell_id`,`quest_start`,`quest_start_active`,`quest_end`,`cast_flags`,`aura_required`,`aura_forbidden`,`user_type`) VALUES
+(38248,71462,0,0,0,1,0,71443,2); -- Impaling Spear
diff --git a/sql/updates/world/2011_05_13_04_world_scriptname.sql b/sql/updates/world/2011_05_13_04_world_scriptname.sql
new file mode 100644
index 00000000000..ee328cd35e5
--- /dev/null
+++ b/sql/updates/world/2011_05_13_04_world_scriptname.sql
@@ -0,0 +1,8 @@
+UPDATE `creature_template` SET `ScriptName`='boss_sister_svalna' WHERE `entry`=37126;
+UPDATE `creature_template` SET `ScriptName`='npc_crok_scourgebane' WHERE `entry`=37129;
+UPDATE `creature_template` SET `ScriptName`='npc_captain_arnath' WHERE `entry`=37122;
+UPDATE `creature_template` SET `ScriptName`='npc_captain_brandon' WHERE `entry`=37123;
+UPDATE `creature_template` SET `ScriptName`='npc_captain_grondel' WHERE `entry`=37124;
+UPDATE `creature_template` SET `ScriptName`='npc_captain_rupert' WHERE `entry`=37125;
+UPDATE `creature_template` SET `ScriptName`='npc_frostwing_vrykul' WHERE `entry` IN (37132,38125,37127,37134,37133);
+UPDATE `creature_template` SET `ScriptName`='npc_impaling_spear' WHERE `entry`=38248;
diff --git a/sql/updates/world/2011_05_13_04_world_spell_script_names.sql b/sql/updates/world/2011_05_13_04_world_spell_script_names.sql
new file mode 100644
index 00000000000..3829bc7c4f5
--- /dev/null
+++ b/sql/updates/world/2011_05_13_04_world_spell_script_names.sql
@@ -0,0 +1,7 @@
+DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_svalna_caress_of_death';
+DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_svalna_revive_champion';
+DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_svalna_remove_spear';
+INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
+(70078, 'spell_svalna_caress_of_death'),
+(70053, 'spell_svalna_revive_champion'),
+(71462, 'spell_svalna_remove_spear');
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index 0ae0515a35b..04dd5cda4e4 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -18,7 +18,9 @@
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "ScriptedEscortAI.h"
#include "SpellAuraEffects.h"
+#include "SmartAI.h"
#include "icecrown_citadel.h"
// Weekly quest support
@@ -61,6 +63,33 @@ enum Texts
// Rotting Frost Giant
EMOTE_DEATH_PLAGUE_WARNING = 0,
+
+ // Sister Svalna
+ SAY_SVALNA_KILL_CAPTAIN = 1, // happens when she kills a captain
+ SAY_SVALNA_KILL = 4,
+ SAY_SVALNA_CAPTAIN_DEATH = 5, // happens when a captain resurrected by her dies
+ SAY_SVALNA_DEATH = 6,
+ EMOTE_SVALNA_IMPALE = 7,
+ EMOTE_SVALNA_BROKEN_SHIELD = 8,
+
+ SAY_CROK_INTRO_1 = 0, // Ready your arms, my Argent Brothers. The Vrykul will protect the Frost Queen with their lives.
+ SAY_ARNATH_INTRO_2 = 5, // Even dying here beats spending another day collecting reagents for that madman, Finklestein.
+ SAY_CROK_INTRO_3 = 1, // Enough idle banter! Our champions have arrived - support them as we push our way through the hall!
+ SAY_SVALNA_EVENT_START = 0, // You may have once fought beside me, Crok, but now you are nothing more than a traitor. Come, your second death approaches!
+ SAY_CROK_COMBAT_WP_0 = 2, // Draw them back to us, and we'll assist you.
+ SAY_CROK_COMBAT_WP_1 = 3, // Quickly, push on!
+ SAY_CROK_FINAL_WP = 4, // Her reinforcements will arrive shortly, we must bring her down quickly!
+ SAY_SVALNA_RESURRECT_CAPTAINS = 2, // Foolish Crok. You brought my reinforcements with you. Arise, Argent Champions, and serve the Lich King in death!
+ SAY_CROK_COMBAT_SVALNA = 5, // I'll draw her attacks. Return our brothers to their graves, then help me bring her down!
+ SAY_SVALNA_AGGRO = 3, // Come, Scourgebane. I'll show the master which of us is truly worthy of the title of "Champion"!
+ SAY_CAPTAIN_DEATH = 0,
+ SAY_CAPTAIN_RESURRECTED = 1,
+ SAY_CAPTAIN_KILL = 2,
+ SAY_CAPTAIN_SECOND_DEATH = 3,
+ SAY_CAPTAIN_SURVIVE_TALK = 4,
+ SAY_CROK_WEAKENING_GAUNTLET = 6,
+ SAY_CROK_WEAKENING_SVALNA = 7,
+ SAY_CROK_DEATH = 8,
};
enum Spells
@@ -79,8 +108,62 @@ enum Spells
// Alchemist Adrianna
SPELL_HARVEST_BLIGHT_SPECIMEN = 72155,
SPELL_HARVEST_BLIGHT_SPECIMEN25 = 72162,
+
+ // Crok Scourgebane
+ SPELL_ICEBOUND_ARMOR = 70714,
+ SPELL_SCOURGE_STRIKE = 71488,
+ SPELL_DEATH_STRIKE = 71489,
+
+ // Sister Svalna
+ SPELL_CARESS_OF_DEATH = 70078,
+ SPELL_IMPALING_SPEAR_KILL = 70196,
+ SPELL_REVIVE_CHAMPION = 70053,
+ SPELL_UNDEATH = 70089,
+ SPELL_IMPALING_SPEAR = 71443,
+ SPELL_AETHER_SHIELD = 71463,
+ SPELL_HURL_SPEAR = 71466,
+
+ // Captain Arnath
+ SPELL_DOMINATE_MIND = 14515,
+ SPELL_FLASH_HEAL_NORMAL = 71595,
+ SPELL_POWER_WORD_SHIELD_NORMAL = 71548,
+ SPELL_SMITE_NORMAL = 71546,
+ SPELL_FLASH_HEAL_UNDEAD = 71782,
+ SPELL_POWER_WORD_SHIELD_UNDEAD = 71780,
+ SPELL_SMITE_UNDEAD = 71778,
+
+ // Captain Brandon
+ SPELL_CRUSADER_STRIKE = 71549,
+ SPELL_DIVINE_SHIELD = 71550,
+ SPELL_JUDGEMENT_OF_COMMAND = 71551,
+ SPELL_HAMMER_OF_BETRAYAL = 71784,
+
+ // Captain Grondel
+ SPELL_CHARGE = 71553,
+ SPELL_MORTAL_STRIKE = 71552,
+ SPELL_SUNDER_ARMOR = 71554,
+ SPELL_CONFLAGRATION = 71785,
+
+ // Captain Rupert
+ SPELL_FEL_IRON_BOMB_NORMAL = 71592,
+ SPELL_MACHINE_GUN_NORMAL = 71594,
+ SPELL_ROCKET_LAUNCH_NORMAL = 71590,
+ SPELL_FEL_IRON_BOMB_UNDEAD = 71787,
+ SPELL_MACHINE_GUN_UNDEAD = 71788,
+ SPELL_ROCKET_LAUNCH_UNDEAD = 71786,
};
+// Helper defines
+// Captain Arnath
+#define SPELL_FLASH_HEAL (IsUndead ? SPELL_FLASH_HEAL_UNDEAD : SPELL_FLASH_HEAL_NORMAL)
+#define SPELL_POWER_WORD_SHIELD (IsUndead ? SPELL_POWER_WORD_SHIELD_UNDEAD : SPELL_POWER_WORD_SHIELD_NORMAL)
+#define SPELL_SMITE (IsUndead ? SPELL_SMITE_UNDEAD : SPELL_SMITE_NORMAL)
+
+// Captain Rupert
+#define SPELL_FEL_IRON_BOMB (IsUndead ? SPELL_FEL_IRON_BOMB_UNDEAD : SPELL_FEL_IRON_BOMB_NORMAL)
+#define SPELL_MACHINE_GUN (IsUndead ? SPELL_MACHINE_GUN_UNDEAD : SPELL_MACHINE_GUN_NORMAL)
+#define SPELL_ROCKET_LAUNCH (IsUndead ? SPELL_ROCKET_LAUNCH_UNDEAD : SPELL_ROCKET_LAUNCH_NORMAL)
+
enum EventTypes
{
// Highlord Tirion Fordring (at Light's Hammer)
@@ -121,6 +204,43 @@ enum EventTypes
// Frost Freeze Trap
EVENT_ACTIVATE_TRAP = 28,
+ // Crok Scourgebane
+ EVENT_SCOURGE_STRIKE = 29,
+ EVENT_DEATH_STRIKE = 30,
+ EVENT_HEALTH_CHECK = 31,
+ EVENT_CROK_INTRO_3 = 32,
+ EVENT_START_PATHING = 33,
+
+ // Sister Svalna
+ EVENT_ARNATH_INTRO_2 = 34,
+ EVENT_SVALNA_START = 35,
+ EVENT_SVALNA_RESURRECT = 36,
+ EVENT_SVALNA_COMBAT = 37,
+ EVENT_IMPALING_SPEAR = 38,
+ EVENT_AETHER_SHIELD = 39,
+
+ // Captain Arnath
+ EVENT_ARNATH_FLASH_HEAL = 40,
+ EVENT_ARNATH_PW_SHIELD = 41,
+ EVENT_ARNATH_SMITE = 42,
+ EVENT_ARNATH_DOMINATE_MIND = 43,
+
+ // Captain Brandon
+ EVENT_BRANDON_CRUSADER_STRIKE = 44,
+ EVENT_BRANDON_DIVINE_SHIELD = 45,
+ EVENT_BRANDON_JUDGEMENT_OF_COMMAND = 46,
+ EVENT_BRANDON_HAMMER_OF_BETRAYAL = 47,
+
+ // Captain Grondel
+ EVENT_GRONDEL_CHARGE_CHECK = 48,
+ EVENT_GRONDEL_MORTAL_STRIKE = 49,
+ EVENT_GRONDEL_SUNDER_ARMOR = 50,
+ EVENT_GRONDEL_CONFLAGRATION = 51,
+
+ // Captain Rupert
+ EVENT_RUPERT_FEL_IRON_BOMB = 52,
+ EVENT_RUPERT_MACHINE_GUN = 53,
+ EVENT_RUPERT_ROCKET_LAUNCH = 54,
};
enum DataTypesICC
@@ -128,6 +248,106 @@ enum DataTypesICC
DATA_DAMNED_KILLS = 1,
};
+enum Actions
+{
+ // Sister Svalna
+ ACTION_KILL_CAPTAIN = 1,
+ ACTION_START_GAUNTLET = 2,
+ ACTION_RESURRECT_CAPTAINS = 3,
+ ACTION_CAPTAIN_DIES = 4,
+ ACTION_RESET_EVENT = 5,
+};
+
+class FrostwingVrykulSearcher
+{
+ public:
+ FrostwingVrykulSearcher(Creature const* source, float range) : _source(source), _range(range) {}
+
+ bool operator()(Unit* unit)
+ {
+ if (!unit->isAlive())
+ return false;
+
+ switch (unit->GetEntry())
+ {
+ case NPC_YMIRJAR_BATTLE_MAIDEN:
+ case NPC_YMIRJAR_DEATHBRINGER:
+ case NPC_YMIRJAR_FROSTBINDER:
+ case NPC_YMIRJAR_HUNTRESS:
+ case NPC_YMIRJAR_WARLORD:
+ break;
+ default:
+ return false;
+ }
+
+ if (!unit->IsWithinDist(_source, _range, false))
+ return false;
+
+ return true;
+ }
+
+ private:
+ Creature const* _source;
+ float _range;
+};
+
+class FrostwingGauntletRespawner
+{
+ public:
+ void operator()(Creature* creature)
+ {
+ switch (creature->GetOriginalEntry())
+ {
+ case NPC_YMIRJAR_BATTLE_MAIDEN:
+ case NPC_YMIRJAR_DEATHBRINGER:
+ case NPC_YMIRJAR_FROSTBINDER:
+ case NPC_YMIRJAR_HUNTRESS:
+ case NPC_YMIRJAR_WARLORD:
+ break;
+ case NPC_CROK_SCOURGEBANE:
+ case NPC_CAPTAIN_ARNATH:
+ case NPC_CAPTAIN_BRANDON:
+ case NPC_CAPTAIN_GRONDEL:
+ case NPC_CAPTAIN_RUPERT:
+ creature->AI()->DoAction(ACTION_RESET_EVENT);
+ break;
+ case NPC_SISTER_SVALNA:
+ creature->AI()->DoAction(ACTION_RESET_EVENT);
+ // return, this creature is never dead if event is reset
+ return;
+ default:
+ return;
+ }
+
+ uint32 corpseDelay = creature->GetCorpseDelay();
+ uint32 respawnDelay = creature->GetRespawnDelay();
+ creature->SetCorpseDelay(1);
+ creature->SetRespawnDelay(2);
+
+ if (CreatureData const* data = creature->GetCreatureData())
+ creature->SetPosition(data->posX, data->posY, data->posZ, data->orientation);
+ creature->ForcedDespawn();
+
+ creature->SetCorpseDelay(corpseDelay);
+ creature->SetRespawnDelay(respawnDelay);
+ }
+};
+
+class CaptainSurviveTalk : public BasicEvent
+{
+ public:
+ explicit CaptainSurviveTalk(Creature const& owner) : _owner(owner) { }
+
+ bool Execute(uint64 /*currTime*/, uint32 /*diff*/)
+ {
+ _owner.AI()->Talk(SAY_CAPTAIN_SURVIVE_TALK);
+ return true;
+ }
+
+ private:
+ Creature const& _owner;
+};
+
// at Light's Hammer
class npc_highlord_tirion_fordring_lh : public CreatureScript
{
@@ -475,6 +695,958 @@ class npc_alchemist_adrianna : public CreatureScript
}
};
+class boss_sister_svalna : public CreatureScript
+{
+ public:
+ boss_sister_svalna() : CreatureScript("boss_sister_svalna") { }
+
+ struct boss_sister_svalnaAI : public BossAI
+ {
+ boss_sister_svalnaAI(Creature* creature) : BossAI(creature, DATA_SISTER_SVALNA),
+ _isEventInProgress(false)
+ {
+ }
+
+ void InitializeAI()
+ {
+ if (!me->isDead())
+ Reset();
+
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void Reset()
+ {
+ _Reset();
+ me->SetReactState(REACT_DEFENSIVE);
+ _isEventInProgress = false;
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ _JustDied();
+ Talk(SAY_SVALNA_DEATH);
+
+ uint64 delay = 1;
+ for (uint32 i = 0; i < 4; ++i)
+ {
+ if (Creature* crusader = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_CAPTAIN_ARNATH + i)))
+ {
+ if (crusader->isAlive() && crusader->GetEntry() == crusader->GetCreatureData()->id)
+ {
+ crusader->m_Events.AddEvent(new CaptainSurviveTalk(*crusader), crusader->m_Events.CalculateTime(delay));
+ delay += 6000;
+ }
+ }
+ }
+ }
+
+ void EnterCombat(Unit* /*attacker*/)
+ {
+ _EnterCombat();
+ if (Creature* crok = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_CROK_SCOURGEBANE)))
+ crok->AI()->Talk(SAY_CROK_COMBAT_SVALNA);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_1);
+ events.ScheduleEvent(EVENT_SVALNA_COMBAT, 9000);
+ events.ScheduleEvent(EVENT_IMPALING_SPEAR, urand(40000, 50000));
+ events.ScheduleEvent(EVENT_AETHER_SHIELD, urand(100000, 110000));
+ }
+
+ void KilledUnit(Unit* victim)
+ {
+ switch (victim->GetTypeId())
+ {
+ case TYPEID_PLAYER:
+ Talk(SAY_SVALNA_KILL);
+ break;
+ case TYPEID_UNIT:
+ switch (victim->GetEntry())
+ {
+ case NPC_CAPTAIN_ARNATH:
+ case NPC_CAPTAIN_BRANDON:
+ case NPC_CAPTAIN_GRONDEL:
+ case NPC_CAPTAIN_RUPERT:
+ Talk(SAY_SVALNA_KILL_CAPTAIN);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void JustReachedHome()
+ {
+ _JustReachedHome();
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void DoAction(int32 const action)
+ {
+ switch (action)
+ {
+ case ACTION_KILL_CAPTAIN:
+ me->CastCustomSpell(SPELL_CARESS_OF_DEATH, SPELLVALUE_MAX_TARGETS, 1, me, true);
+ break;
+ case ACTION_START_GAUNTLET:
+ me->setActive(true);
+ _isEventInProgress = true;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_PASSIVE);
+ events.ScheduleEvent(EVENT_SVALNA_START, 25000);
+ break;
+ case ACTION_RESURRECT_CAPTAINS:
+ events.ScheduleEvent(EVENT_SVALNA_RESURRECT, 7000);
+ break;
+ case ACTION_CAPTAIN_DIES:
+ Talk(SAY_SVALNA_CAPTAIN_DEATH);
+ break;
+ case ACTION_RESET_EVENT:
+ me->setActive(false);
+ Reset();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void SpellHit(Unit* caster, SpellEntry const* spell)
+ {
+ if (spell->Id == SPELL_HURL_SPEAR && me->HasAura(SPELL_AETHER_SHIELD))
+ {
+ me->RemoveAurasDueToSpell(SPELL_AETHER_SHIELD);
+ Talk(EMOTE_SVALNA_BROKEN_SHIELD, caster->GetGUID());
+ }
+ }
+
+ void SpellHitTarget(Unit* target, SpellEntry const* spell)
+ {
+ switch (spell->Id)
+ {
+ case SPELL_REVIVE_CHAMPION:
+ if (!_isEventInProgress)
+ break;
+ _isEventInProgress = false;
+ me->setActive(false);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_PASSIVE);
+ break;
+ case SPELL_IMPALING_SPEAR_KILL:
+ me->Kill(target);
+ break;
+ case SPELL_IMPALING_SPEAR:
+ if (TempSummon* summon = target->SummonCreature(NPC_IMPALING_SPEAR, *target))
+ {
+ Talk(EMOTE_SVALNA_IMPALE, target->GetGUID());
+ summon->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_UNK1 | 0x4000);
+ summon->CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, 1, target, false);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim() && !_isEventInProgress)
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SVALNA_START:
+ Talk(SAY_SVALNA_EVENT_START);
+ break;
+ case EVENT_SVALNA_RESURRECT:
+ Talk(SAY_SVALNA_RESURRECT_CAPTAINS);
+ me->CastSpell(me, SPELL_REVIVE_CHAMPION, false);
+ break;
+ case EVENT_SVALNA_COMBAT:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_1);
+ me->SetReactState(REACT_DEFENSIVE);
+ Talk(SAY_SVALNA_AGGRO);
+ break;
+ case EVENT_IMPALING_SPEAR:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true, -SPELL_IMPALING_SPEAR))
+ DoCast(target, SPELL_IMPALING_SPEAR);
+ events.ScheduleEvent(EVENT_IMPALING_SPEAR, urand(20000, 25000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ bool _isEventInProgress;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<boss_sister_svalnaAI>(creature);
+ }
+};
+
+class npc_crok_scourgebane : public CreatureScript
+{
+ public:
+ npc_crok_scourgebane() : CreatureScript("npc_crok_scourgebane") { }
+
+ struct npc_crok_scourgebaneAI : public npc_escortAI
+ {
+ npc_crok_scourgebaneAI(Creature* creature) : npc_escortAI(creature),
+ _instance(creature->GetInstanceScript()), _respawnTime(creature->GetRespawnDelay()),
+ _corpseDelay(creature->GetCorpseDelay())
+ {
+ SetDespawnAtEnd(false);
+ SetDespawnAtFar(false);
+ _isEventActive = false;
+ _isEventDone = false;
+ _didUnderTenPercentText = false;
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_SCOURGE_STRIKE, urand(7500, 12500));
+ _events.ScheduleEvent(EVENT_DEATH_STRIKE, urand(25000, 30000));
+ me->SetReactState(REACT_DEFENSIVE);
+ _didUnderTenPercentText = false;
+ _wipeCheckTimer = 1000;
+ }
+
+ void DoAction(int32 const action)
+ {
+ if (action == ACTION_START_GAUNTLET)
+ {
+ if (_isEventDone || !me->isAlive())
+ return;
+
+ _isEventActive = true;
+ _isEventDone = true;
+ // Load Grid with Sister Svalna
+ me->GetMap()->LoadGrid(4356.71f, 2484.33f);
+ if (Creature* svalna = me->FindNearestCreature(NPC_SISTER_SVALNA, 333.0f, true))
+ svalna->AI()->DoAction(ACTION_START_GAUNTLET);
+ Talk(SAY_CROK_INTRO_1);
+ _events.ScheduleEvent(EVENT_ARNATH_INTRO_2, 7000);
+ _events.ScheduleEvent(EVENT_CROK_INTRO_3, 14000);
+ _events.ScheduleEvent(EVENT_START_PATHING, 37000);
+ me->setActive(true);
+ for (uint32 i = 0; i < 4; ++i)
+ if (Creature* crusader = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_CAPTAIN_ARNATH + i)))
+ crusader->AI()->DoAction(ACTION_START_GAUNTLET);
+ }
+ else if (action == ACTION_RESET_EVENT)
+ {
+ _isEventActive = false;
+ _isEventDone = false;
+ me->setActive(false);
+ _aliveTrash.clear();
+ _currentWPid = 0;
+ }
+ }
+
+ void SetGUID(uint64 const& guid, int32 type/* = 0*/)
+ {
+ if (type == ACTION_VRYKUL_DEATH)
+ {
+ _aliveTrash.erase(guid);
+ if (_aliveTrash.empty())
+ {
+ SetEscortPaused(false);
+ if (_currentWPid == 4 && _isEventActive)
+ {
+ _isEventActive = false;
+ me->setActive(false);
+ Talk(SAY_CROK_FINAL_WP);
+ if (Creature* svalna = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_SISTER_SVALNA)))
+ svalna->AI()->DoAction(ACTION_RESURRECT_CAPTAINS);
+ }
+ }
+ }
+ }
+
+ void WaypointReached(uint32 waypointId)
+ {
+ switch (waypointId)
+ {
+ // pause pathing until trash pack is cleared
+ case 0:
+ Talk(SAY_CROK_COMBAT_WP_0);
+ if (!_aliveTrash.empty())
+ SetEscortPaused(true);
+ break;
+ case 1:
+ Talk(SAY_CROK_COMBAT_WP_1);
+ if (!_aliveTrash.empty())
+ SetEscortPaused(true);
+ break;
+ case 4:
+ if (_aliveTrash.empty() && _isEventActive)
+ {
+ _isEventActive = false;
+ me->setActive(false);
+ Talk(SAY_CROK_FINAL_WP);
+ if (Creature* svalna = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_SISTER_SVALNA)))
+ svalna->AI()->DoAction(ACTION_RESURRECT_CAPTAINS);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void WaypointStart(uint32 waypointId)
+ {
+ _currentWPid = waypointId;
+ switch (waypointId)
+ {
+ case 0:
+ case 1:
+ case 4:
+ {
+ // get spawns by home position
+ float minY = 2600.0f;
+ float maxY = 2650.0f;
+ if (waypointId == 1)
+ {
+ minY -= 50.0f;
+ maxY -= 50.0f;
+ // at waypoints 1 and 2 she kills one captain
+ if (Creature* svalna = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_SISTER_SVALNA)))
+ svalna->AI()->DoAction(ACTION_KILL_CAPTAIN);
+ }
+ else if (waypointId == 4)
+ {
+ minY -= 100.0f;
+ maxY -= 100.0f;
+ }
+
+ // get all nearby vrykul
+ std::list<Creature*> temp;
+ FrostwingVrykulSearcher check(me, 80.0f);
+ Trinity::CreatureListSearcher<FrostwingVrykulSearcher> searcher(me, temp, check);
+ me->VisitNearbyGridObject(80.0f, searcher);
+
+ _aliveTrash.clear();
+ for (std::list<Creature*>::iterator itr = temp.begin(); itr != temp.end(); ++itr)
+ if ((*itr)->GetHomePosition().GetPositionY() < maxY && (*itr)->GetHomePosition().GetPositionY() > minY)
+ _aliveTrash.insert((*itr)->GetGUID());
+ break;
+ }
+ // at waypoints 1 and 2 she kills one captain
+ case 2:
+ if (Creature* svalna = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_SISTER_SVALNA)))
+ svalna->AI()->DoAction(ACTION_KILL_CAPTAIN);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage)
+ {
+ // check wipe
+ if (!_wipeCheckTimer)
+ {
+ _wipeCheckTimer = 1000;
+ Player* player = NULL;
+ Trinity::AnyPlayerInObjectRangeCheck check(me, 60.0f);
+ Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(me, player, check);
+ me->VisitNearbyWorldObject(60.0f, searcher);
+ // wipe
+ if (!player)
+ {
+ damage *= 100;
+ if (damage >= me->GetHealth())
+ {
+ FrostwingGauntletRespawner respawner;
+ Trinity::CreatureWorker<FrostwingGauntletRespawner> worker(me, respawner);
+ me->VisitNearbyGridObject(333.0f, worker);
+ Talk(SAY_CROK_DEATH);
+ }
+ return;
+ }
+ }
+
+ if (HealthBelowPct(10))
+ {
+ if (!_didUnderTenPercentText)
+ {
+ _didUnderTenPercentText = true;
+ if (_isEventActive)
+ Talk(SAY_CROK_WEAKENING_GAUNTLET);
+ else
+ Talk(SAY_CROK_WEAKENING_SVALNA);
+ }
+
+ damage = 0;
+ DoCast(me, SPELL_ICEBOUND_ARMOR);
+ _events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
+ }
+ }
+
+ void UpdateEscortAI(uint32 const diff)
+ {
+ if (_wipeCheckTimer <= diff)
+ _wipeCheckTimer = 0;
+ else
+ _wipeCheckTimer -= diff;
+
+ if (!UpdateVictim() && !_isEventActive)
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_ARNATH_INTRO_2:
+ if (Creature* arnath = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_CAPTAIN_ARNATH)))
+ arnath->AI()->Talk(SAY_ARNATH_INTRO_2);
+ break;
+ case EVENT_CROK_INTRO_3:
+ Talk(SAY_CROK_INTRO_3);
+ break;
+ case EVENT_START_PATHING:
+ Start(true, true);
+ break;
+ case EVENT_SCOURGE_STRIKE:
+ DoCastVictim(SPELL_SCOURGE_STRIKE);
+ _events.ScheduleEvent(EVENT_SCOURGE_STRIKE, urand(10000, 14000));
+ break;
+ case EVENT_DEATH_STRIKE:
+ if (HealthBelowPct(20))
+ DoCastVictim(SPELL_DEATH_STRIKE);
+ _events.ScheduleEvent(EVENT_DEATH_STRIKE, urand(5000, 10000));
+ break;
+ case EVENT_HEALTH_CHECK:
+ if (HealthAbovePct(15))
+ {
+ me->RemoveAurasDueToSpell(SPELL_ICEBOUND_ARMOR);
+ _didUnderTenPercentText = false;
+ }
+ else
+ {
+ me->DealHeal(me, me->CountPctFromMaxHealth(5));
+ _events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ bool CanAIAttack(Unit const* target) const
+ {
+ // do not see targets inside Frostwing Halls when we are not there
+ return (me->GetPositionY() > 2660.0f) == (target->GetPositionY() > 2660.0f);
+ }
+
+ private:
+ EventMap _events;
+ std::set<uint64> _aliveTrash;
+ InstanceScript* _instance;
+ uint32 _currentWPid;
+ uint32 _wipeCheckTimer;
+ uint32 const _respawnTime;
+ uint32 const _corpseDelay;
+ bool _isEventActive;
+ bool _isEventDone;
+ bool _didUnderTenPercentText;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_crok_scourgebaneAI>(creature);
+ }
+};
+
+struct npc_argent_captainAI : public ScriptedAI
+{
+ public:
+ npc_argent_captainAI(Creature* creature) : ScriptedAI(creature), Instance(creature->GetInstanceScript()), _firstDeath(true)
+ {
+ FollowAngle = PET_FOLLOW_ANGLE;
+ FollowDist = PET_FOLLOW_DIST;
+ IsUndead = false;
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ if (_firstDeath)
+ {
+ _firstDeath = false;
+ Talk(SAY_CAPTAIN_DEATH);
+ }
+ else
+ Talk(SAY_CAPTAIN_SECOND_DEATH);
+ }
+
+ void KilledUnit(Unit* victim)
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_CAPTAIN_KILL);
+ }
+
+ void DoAction(int32 const action)
+ {
+ if (action == ACTION_START_GAUNTLET)
+ {
+ if (Creature* crok = ObjectAccessor::GetCreature(*me, Instance->GetData64(DATA_CROK_SCOURGEBANE)))
+ {
+ me->SetReactState(REACT_DEFENSIVE);
+ FollowAngle = me->GetAngle(crok) + me->GetOrientation();
+ FollowDist = me->GetDistance2d(crok);
+ me->GetMotionMaster()->MoveFollow(crok, FollowDist, FollowAngle, MOTION_SLOT_IDLE);
+ }
+
+ me->setActive(true);
+ }
+ else if (action == ACTION_RESET_EVENT)
+ {
+ _firstDeath = true;
+ }
+ }
+
+ void EnterCombat(Unit* /*target*/)
+ {
+ me->SetHomePosition(*me);
+ if (IsUndead)
+ DoZoneInCombat();
+ }
+
+ bool CanAIAttack(Unit const* target) const
+ {
+ // do not see targets inside Frostwing Halls when we are not there
+ return (me->GetPositionY() > 2660.0f) == (target->GetPositionY() > 2660.0f);
+ }
+
+ void EnterEvadeMode()
+ {
+ // not yet following
+ if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != TARGETED_MOTION_TYPE || IsUndead)
+ {
+ ScriptedAI::EnterEvadeMode();
+ return;
+ }
+
+ if (!_EnterEvadeMode())
+ return;
+
+ if (!me->GetVehicle())
+ {
+ me->GetMotionMaster()->Clear(false);
+ if (Creature* crok = ObjectAccessor::GetCreature(*me, Instance->GetData64(DATA_CROK_SCOURGEBANE)))
+ me->GetMotionMaster()->MoveFollow(crok, FollowDist, FollowAngle, MOTION_SLOT_IDLE);
+ }
+
+ Reset();
+ }
+
+ void SpellHit(Unit* /*caster*/, SpellEntry const* spell)
+ {
+ if (spell->Id == SPELL_REVIVE_CHAMPION && !IsUndead)
+ {
+ IsUndead = true;
+ me->setDeathState(JUST_ALIVED);
+ uint32 newEntry = 0;
+ switch (me->GetEntry())
+ {
+ case NPC_CAPTAIN_ARNATH:
+ newEntry = NPC_CAPTAIN_ARNATH_UNDEAD;
+ break;
+ case NPC_CAPTAIN_BRANDON:
+ newEntry = NPC_CAPTAIN_BRANDON_UNDEAD;
+ break;
+ case NPC_CAPTAIN_GRONDEL:
+ newEntry = NPC_CAPTAIN_GRONDEL_UNDEAD;
+ break;
+ case NPC_CAPTAIN_RUPERT:
+ newEntry = NPC_CAPTAIN_RUPERT_UNDEAD;
+ break;
+ default:
+ return;
+ }
+
+ Talk(SAY_CAPTAIN_RESURRECTED);
+ me->UpdateEntry(newEntry, Instance->GetData(DATA_TEAM_IN_INSTANCE), me->GetCreatureData());
+ DoCast(me, SPELL_UNDEATH, true);
+ }
+ }
+
+ protected:
+ EventMap Events;
+ InstanceScript* Instance;
+ float FollowAngle;
+ float FollowDist;
+ bool IsUndead;
+
+ private:
+ bool _firstDeath;
+};
+
+class npc_captain_arnath : public CreatureScript
+{
+ public:
+ npc_captain_arnath() : CreatureScript("npc_captain_arnath") { }
+
+ struct npc_captain_arnathAI : public npc_argent_captainAI
+ {
+ npc_captain_arnathAI(Creature* creature) : npc_argent_captainAI(creature)
+ {
+ }
+
+ void Reset()
+ {
+ Events.Reset();
+ Events.ScheduleEvent(EVENT_ARNATH_FLASH_HEAL, urand(4000, 7000));
+ Events.ScheduleEvent(EVENT_ARNATH_PW_SHIELD, urand(8000, 14000));
+ Events.ScheduleEvent(EVENT_ARNATH_SMITE, urand(3000, 6000));
+ if (Is25ManRaid() && IsUndead)
+ Events.ScheduleEvent(EVENT_ARNATH_DOMINATE_MIND, urand(22000, 27000));
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ Events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = Events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_ARNATH_FLASH_HEAL:
+ if (Creature* target = FindFriendlyCreature())
+ DoCast(target, SPELL_FLASH_HEAL);
+ Events.ScheduleEvent(EVENT_ARNATH_FLASH_HEAL, urand(6000, 9000));
+ break;
+ case EVENT_ARNATH_PW_SHIELD:
+ {
+ std::list<Creature*> targets = DoFindFriendlyMissingBuff(40.0f, SPELL_POWER_WORD_SHIELD);
+ std::list<Creature*>::iterator itr = targets.begin();
+ std::advance(itr, urand(0, targets.size() - 1));
+ DoCast(*itr, SPELL_POWER_WORD_SHIELD);
+ Events.ScheduleEvent(EVENT_ARNATH_PW_SHIELD, urand(15000, 20000));
+ break;
+ }
+ case EVENT_ARNATH_SMITE:
+ DoCastVictim(SPELL_SMITE);
+ Events.ScheduleEvent(EVENT_ARNATH_SMITE, urand(4000, 7000));
+ break;
+ case EVENT_ARNATH_DOMINATE_MIND:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
+ DoCast(target, SPELL_DOMINATE_MIND);
+ Events.ScheduleEvent(EVENT_ARNATH_DOMINATE_MIND, urand(28000, 37000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ Creature* FindFriendlyCreature() const
+ {
+ Creature* target = NULL;
+ Trinity::MostHPMissingInRange u_check(me, 60.0f, 0);
+ Trinity::CreatureLastSearcher<Trinity::MostHPMissingInRange> searcher(me, target, u_check);
+ me->VisitNearbyGridObject(60.0f, searcher);
+ return target;
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_captain_arnathAI>(creature);
+ }
+};
+
+class npc_captain_brandon : public CreatureScript
+{
+ public:
+ npc_captain_brandon() : CreatureScript("npc_captain_brandon") { }
+
+ struct npc_captain_brandonAI : public npc_argent_captainAI
+ {
+ npc_captain_brandonAI(Creature* creature) : npc_argent_captainAI(creature)
+ {
+ }
+
+ void Reset()
+ {
+ Events.Reset();
+ Events.ScheduleEvent(EVENT_BRANDON_CRUSADER_STRIKE, urand(6000, 10000));
+ Events.ScheduleEvent(EVENT_BRANDON_DIVINE_SHIELD, 500);
+ Events.ScheduleEvent(EVENT_BRANDON_JUDGEMENT_OF_COMMAND, urand(8000, 13000));
+ if (IsUndead)
+ Events.ScheduleEvent(EVENT_BRANDON_HAMMER_OF_BETRAYAL, urand(25000, 30000));
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ Events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = Events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_BRANDON_CRUSADER_STRIKE:
+ DoCastVictim(SPELL_CRUSADER_STRIKE);
+ Events.ScheduleEvent(EVENT_BRANDON_CRUSADER_STRIKE, urand(6000, 12000));
+ break;
+ case EVENT_BRANDON_DIVINE_SHIELD:
+ if (HealthBelowPct(20))
+ DoCast(me, SPELL_DIVINE_SHIELD);
+ Events.ScheduleEvent(EVENT_BRANDON_DIVINE_SHIELD, 500);
+ break;
+ case EVENT_BRANDON_JUDGEMENT_OF_COMMAND:
+ DoCastVictim(SPELL_JUDGEMENT_OF_COMMAND);
+ Events.ScheduleEvent(EVENT_BRANDON_JUDGEMENT_OF_COMMAND, urand(8000, 13000));
+ break;
+ case EVENT_BRANDON_HAMMER_OF_BETRAYAL:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
+ DoCast(target, SPELL_HAMMER_OF_BETRAYAL);
+ Events.ScheduleEvent(EVENT_BRANDON_HAMMER_OF_BETRAYAL, urand(45000, 60000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_captain_brandonAI>(creature);
+ }
+};
+
+class npc_captain_grondel : public CreatureScript
+{
+ public:
+ npc_captain_grondel() : CreatureScript("npc_captain_grondel") { }
+
+ struct npc_captain_grondelAI : public npc_argent_captainAI
+ {
+ npc_captain_grondelAI(Creature* creature) : npc_argent_captainAI(creature)
+ {
+ }
+
+ void Reset()
+ {
+ Events.Reset();
+ Events.ScheduleEvent(EVENT_GRONDEL_CHARGE_CHECK, 500);
+ Events.ScheduleEvent(EVENT_GRONDEL_MORTAL_STRIKE, urand(8000, 14000));
+ Events.ScheduleEvent(EVENT_GRONDEL_SUNDER_ARMOR, urand(3000, 12000));
+ if (IsUndead)
+ Events.ScheduleEvent(EVENT_GRONDEL_CONFLAGRATION, urand(12000, 17000));
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ Events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = Events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_GRONDEL_CHARGE_CHECK:
+ if (CanCast(me->getVictim(), sSpellStore.LookupEntry(SPELL_CHARGE)))
+ DoCastVictim(SPELL_CHARGE);
+ Events.ScheduleEvent(EVENT_GRONDEL_CHARGE_CHECK, 500);
+ break;
+ case EVENT_GRONDEL_MORTAL_STRIKE:
+ DoCastVictim(SPELL_MORTAL_STRIKE);
+ Events.ScheduleEvent(EVENT_GRONDEL_MORTAL_STRIKE, urand(10000, 15000));
+ break;
+ case EVENT_GRONDEL_SUNDER_ARMOR:
+ DoCastVictim(SPELL_SUNDER_ARMOR);
+ Events.ScheduleEvent(EVENT_GRONDEL_SUNDER_ARMOR, urand(5000, 17000));
+ break;
+ case EVENT_GRONDEL_CONFLAGRATION:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_CONFLAGRATION);
+ Events.ScheduleEvent(EVENT_GRONDEL_CONFLAGRATION, urand(10000, 15000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_captain_grondelAI>(creature);
+ }
+};
+
+class npc_captain_rupert : public CreatureScript
+{
+ public:
+ npc_captain_rupert() : CreatureScript("npc_captain_rupert") { }
+
+ struct npc_captain_rupertAI : public npc_argent_captainAI
+ {
+ npc_captain_rupertAI(Creature* creature) : npc_argent_captainAI(creature)
+ {
+ }
+
+ void Reset()
+ {
+ Events.Reset();
+ Events.ScheduleEvent(EVENT_RUPERT_FEL_IRON_BOMB, urand(15000, 20000));
+ Events.ScheduleEvent(EVENT_RUPERT_MACHINE_GUN, urand(25000, 30000));
+ Events.ScheduleEvent(EVENT_RUPERT_ROCKET_LAUNCH, urand(10000, 15000));
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ Events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = Events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_RUPERT_FEL_IRON_BOMB:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_FEL_IRON_BOMB);
+ Events.ScheduleEvent(EVENT_RUPERT_FEL_IRON_BOMB, urand(15000, 20000));
+ break;
+ case EVENT_RUPERT_MACHINE_GUN:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ DoCast(target, SPELL_MACHINE_GUN);
+ Events.ScheduleEvent(EVENT_RUPERT_MACHINE_GUN, urand(25000, 30000));
+ break;
+ case EVENT_RUPERT_ROCKET_LAUNCH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ DoCast(target, SPELL_ROCKET_LAUNCH);
+ Events.ScheduleEvent(EVENT_RUPERT_ROCKET_LAUNCH, urand(10000, 15000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return GetIcecrownCitadelAI<npc_captain_rupertAI>(creature);
+ }
+};
+
+class npc_frostwing_vrykul : public CreatureScript
+{
+ public:
+ npc_frostwing_vrykul() : CreatureScript("npc_frostwing_vrykul") { }
+
+ struct npc_frostwing_vrykulAI : public SmartAI
+ {
+ npc_frostwing_vrykulAI(Creature* creature) : SmartAI(creature)
+ {
+ }
+
+ bool CanAIAttack(Unit const* target) const
+ {
+ // do not see targets inside Frostwing Halls when we are not there
+ return (me->GetPositionY() > 2660.0f) == (target->GetPositionY() > 2660.0f) && SmartAI::CanAIAttack(target);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_frostwing_vrykulAI(creature);
+ }
+};
+
+class npc_impaling_spear : public CreatureScript
+{
+ public:
+ npc_impaling_spear() : CreatureScript("npc_impaling_spear") { }
+
+ struct npc_impaling_spearAI : public CreatureAI
+ {
+ npc_impaling_spearAI(Creature* creature) : CreatureAI(creature)
+ {
+ }
+
+ void Reset()
+ {
+ me->SetReactState(REACT_PASSIVE);
+ _vehicleCheckTimer = 500;
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (_vehicleCheckTimer <= diff)
+ {
+ _vehicleCheckTimer = 500;
+ if (!me->GetVehicle())
+ me->DespawnOrUnsummon(100);
+ }
+ else
+ _vehicleCheckTimer -= diff;
+ }
+
+ uint32 _vehicleCheckTimer;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_impaling_spearAI(creature);
+ }
+};
+
class DeathPlagueTargetSelector
{
public:
@@ -595,6 +1767,70 @@ class spell_icc_harvest_blight_specimen : public SpellScriptLoader
}
};
+class AliveCheck
+{
+ public:
+ bool operator()(Unit* unit)
+ {
+ return unit->isAlive();
+ }
+};
+
+class spell_svalna_revive_champion : public SpellScriptLoader
+{
+ public:
+ spell_svalna_revive_champion() : SpellScriptLoader("spell_svalna_revive_champion") { }
+
+ class spell_svalna_revive_champion_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_svalna_revive_champion_SpellScript);
+
+ void RemoveAliveTarget(std::list<Unit*>& unitList)
+ {
+ unitList.remove_if(AliveCheck());
+ Trinity::RandomResizeList(unitList, 2);
+ }
+
+ void Register()
+ {
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_svalna_revive_champion_SpellScript::RemoveAliveTarget, EFFECT_0, TARGET_UNIT_AREA_ENTRY_DST);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_svalna_revive_champion_SpellScript();
+ }
+};
+
+class spell_svalna_remove_spear : public SpellScriptLoader
+{
+ public:
+ spell_svalna_remove_spear() : SpellScriptLoader("spell_svalna_remove_spear") { }
+
+ class spell_svalna_remove_spear_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_svalna_remove_spear_SpellScript);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ if (Creature* target = GetHitCreature())
+ target->DespawnOrUnsummon();
+ }
+
+ void Register()
+ {
+ OnEffect += SpellEffectFn(spell_svalna_remove_spear_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_svalna_remove_spear_SpellScript();
+ }
+};
+
class at_icc_saurfang_portal : public AreaTriggerScript
{
public:
@@ -624,6 +1860,7 @@ class at_icc_saurfang_portal : public AreaTriggerScript
instant = !instant;
}
}
+
return true;
}
};
@@ -656,15 +1893,41 @@ class at_icc_start_blood_quickening : public AreaTriggerScript
}
};
+class at_icc_start_frostwing_gauntlet : public AreaTriggerScript
+{
+ public:
+ at_icc_start_frostwing_gauntlet() : AreaTriggerScript("at_icc_start_frostwing_gauntlet") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/)
+ {
+ if (InstanceScript* instance = player->GetInstanceScript())
+ if (Creature* crok = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_CROK_SCOURGEBANE)))
+ crok->AI()->DoAction(ACTION_START_GAUNTLET);
+ return true;
+ }
+};
+
void AddSC_icecrown_citadel()
{
new npc_highlord_tirion_fordring_lh();
new npc_rotting_frost_giant();
new npc_frost_freeze_trap();
new npc_alchemist_adrianna();
+ new boss_sister_svalna();
+ new npc_crok_scourgebane();
+ new npc_captain_arnath();
+ new npc_captain_brandon();
+ new npc_captain_grondel();
+ new npc_captain_rupert();
+ new npc_frostwing_vrykul();
+ new npc_impaling_spear();
new spell_frost_giant_death_plague();
new spell_icc_harvest_blight_specimen();
+ new spell_trigger_spell_from_caster("spell_svalna_caress_of_death", SPELL_IMPALING_SPEAR_KILL);
+ new spell_svalna_revive_champion();
+ new spell_svalna_remove_spear();
new at_icc_saurfang_portal();
new at_icc_shutdown_traps();
new at_icc_start_blood_quickening();
+ new at_icc_start_frostwing_gauntlet();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index f46de1a6cd7..137ac32df24 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -24,7 +24,7 @@
#define ICCScriptName "instance_icecrown_citadel"
-uint32 const EncounterCount = 12;
+uint32 const EncounterCount = 13;
uint32 const WeeklyNPCs = 9;
uint32 const MaxHeroicAttempts = 50;
// Defined in boss_sindragosa.cpp
@@ -64,12 +64,13 @@ enum DataTypes
DATA_PROFESSOR_PUTRICIDE = 6,
DATA_BLOOD_PRINCE_COUNCIL = 7,
DATA_BLOOD_QUEEN_LANA_THEL = 8,
- DATA_VALITHRIA_DREAMWALKER = 9,
- DATA_SINDRAGOSA = 10,
- DATA_THE_LICH_KING = 11,
+ DATA_SISTER_SVALNA = 9,
+ DATA_VALITHRIA_DREAMWALKER = 10,
+ DATA_SINDRAGOSA = 11,
+ DATA_THE_LICH_KING = 12,
// Additional data
- DATA_SAURFANG_EVENT_NPC = 12,
+ DATA_SAURFANG_EVENT_NPC = 34,
DATA_BONED_ACHIEVEMENT = 13,
DATA_OOZE_DANCE_ACHIEVEMENT = 14,
DATA_PUTRICIDE_TABLE = 15,
@@ -86,6 +87,11 @@ enum DataTypes
DATA_TEAM_IN_INSTANCE = 26,
DATA_BLOOD_QUICKENING_STATE = 27,
DATA_HEROIC_ATTEMPTS = 28,
+ DATA_CROK_SCOURGEBANE = 29,
+ DATA_CAPTAIN_ARNATH = 30,
+ DATA_CAPTAIN_BRANDON = 31,
+ DATA_CAPTAIN_GRONDEL = 32,
+ DATA_CAPTAIN_RUPERT = 33,
};
enum CreaturesIds
@@ -186,6 +192,34 @@ enum CreaturesIds
// Blood-Queen Lana'thel
NPC_BLOOD_QUEEN_LANA_THEL = 37955,
+ // Frostwing Halls gauntlet event
+ NPC_CROK_SCOURGEBANE = 37129,
+ NPC_CAPTAIN_ARNATH = 37122,
+ NPC_CAPTAIN_BRANDON = 37123,
+ NPC_CAPTAIN_GRONDEL = 37124,
+ NPC_CAPTAIN_RUPERT = 37125,
+ NPC_CAPTAIN_ARNATH_UNDEAD = 37491,
+ NPC_CAPTAIN_BRANDON_UNDEAD = 37493,
+ NPC_CAPTAIN_GRONDEL_UNDEAD = 37494,
+ NPC_CAPTAIN_RUPERT_UNDEAD = 37495,
+ NPC_YMIRJAR_BATTLE_MAIDEN = 37132,
+ NPC_YMIRJAR_DEATHBRINGER = 38125,
+ NPC_YMIRJAR_FROSTBINDER = 37127,
+ NPC_YMIRJAR_HUNTRESS = 37134,
+ NPC_YMIRJAR_WARLORD = 37133,
+ NPC_SISTER_SVALNA = 37126,
+ NPC_IMPALING_SPEAR = 38248,
+
+ // Valithria Dreamwalker
+ NPC_VALITHRIA_DREAMWALKER = 36789,
+ NPC_GREEN_DRAGON_COMBAT_TRIGGER = 38752,
+ NPC_RISEN_ARCHMAGE = 37868,
+ NPC_BLAZING_SKELETON = 36791,
+ NPC_SUPPRESSER = 37863,
+ NPC_BLISTERING_ZOMBIE = 37934,
+ NPC_GLUTTONOUS_ABOMINATION = 37886,
+ NPC_THE_LICH_KING_VALITHRIA = 16980,
+
// Sindragosa
NPC_SINDRAGOSA = 36853,
NPC_SPINESTALKER = 37534,
@@ -305,6 +339,9 @@ enum SharedActions
// Blood-Queen Lana'thel
ACTION_KILL_MINCHAR = -379550,
+ // Frostwing Halls gauntlet event
+ ACTION_VRYKUL_DEATH = 37129,
+
// Sindragosa
ACTION_START_FROSTWYRM = -368530,
ACTION_TRIGGER_ASPHYXIATION = -368531,
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index 7f00fa08ad7..f537a70d61e 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -38,6 +38,7 @@ DoorData const doorData[] =
{GO_BLOOD_ELF_COUNCIL_DOOR_RIGHT, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_E },
{GO_DOODAD_ICECROWN_BLOODPRINCE_DOOR_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_ROOM, BOUNDARY_S },
{GO_DOODAD_ICECROWN_GRATE_01, DATA_BLOOD_QUEEN_LANA_THEL, DOOR_TYPE_PASSAGE, BOUNDARY_NONE},
+ {GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_SISTER_SVALNA, DOOR_TYPE_PASSAGE, BOUNDARY_S },
{GO_GREEN_DRAGON_BOSS_ENTRANCE, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_ROOM, BOUNDARY_N },
{GO_GREEN_DRAGON_BOSS_EXIT, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_PASSAGE, BOUNDARY_S },
{GO_SINDRAGOSA_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_S },
@@ -101,6 +102,9 @@ class instance_icecrown_citadel : public InstanceMapScript
memset(BloodCouncilGUIDs, 0, 3*sizeof(uint64));
BloodCouncilControllerGUID = 0;
BloodQueenLanaThelGUID = 0;
+ CrokScourgebaneGUID = 0;
+ memset(CrokCaptainGUIDs, 0, 4 * sizeof(uint64));
+ SisterSvalnaGUID = 0;
SindragosaGUID = 0;
SpinestalkerGUID = 0;
RimefangGUID = 0;
@@ -221,6 +225,19 @@ class instance_icecrown_citadel : public InstanceMapScript
case NPC_BLOOD_QUEEN_LANA_THEL:
BloodQueenLanaThelGUID = creature->GetGUID();
break;
+ case NPC_CROK_SCOURGEBANE:
+ CrokScourgebaneGUID = creature->GetGUID();
+ break;
+ // we can only do this because there are no gaps in their entries
+ case NPC_CAPTAIN_ARNATH:
+ case NPC_CAPTAIN_BRANDON:
+ case NPC_CAPTAIN_GRONDEL:
+ case NPC_CAPTAIN_RUPERT:
+ CrokCaptainGUIDs[creature->GetEntry()-NPC_CAPTAIN_ARNATH] = creature->GetGUID();
+ break;
+ case NPC_SISTER_SVALNA:
+ SisterSvalnaGUID = creature->GetGUID();
+ break;
case NPC_SINDRAGOSA:
SindragosaGUID = creature->GetGUID();
break;
@@ -278,6 +295,23 @@ class instance_icecrown_citadel : public InstanceMapScript
ColdflameJetGUIDs.erase(creature->GetGUID());
}
+ void OnCreatureDeath(Creature* creature)
+ {
+ switch (creature->GetEntry())
+ {
+ case NPC_YMIRJAR_BATTLE_MAIDEN:
+ case NPC_YMIRJAR_DEATHBRINGER:
+ case NPC_YMIRJAR_FROSTBINDER:
+ case NPC_YMIRJAR_HUNTRESS:
+ case NPC_YMIRJAR_WARLORD:
+ if (Creature* crok = instance->GetCreature(CrokScourgebaneGUID))
+ crok->AI()->SetGUID(creature->GetGUID(), ACTION_VRYKUL_DEATH);
+ break;
+ default:
+ break;
+ }
+ }
+
void OnGameObjectCreate(GameObject* go)
{
switch (go->GetEntry())
@@ -466,6 +500,15 @@ class instance_icecrown_citadel : public InstanceMapScript
return SpinestalkerGUID;
case DATA_RIMEFANG:
return RimefangGUID;
+ case DATA_CROK_SCOURGEBANE:
+ return CrokScourgebaneGUID;
+ case DATA_CAPTAIN_ARNATH:
+ case DATA_CAPTAIN_BRANDON:
+ case DATA_CAPTAIN_GRONDEL:
+ case DATA_CAPTAIN_RUPERT:
+ return CrokCaptainGUIDs[type-DATA_CAPTAIN_ARNATH];
+ case DATA_SISTER_SVALNA:
+ return SisterSvalnaGUID;
default:
break;
}
@@ -1011,6 +1054,9 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 BloodCouncilGUIDs[3];
uint64 BloodCouncilControllerGUID;
uint64 BloodQueenLanaThelGUID;
+ uint64 CrokScourgebaneGUID;
+ uint64 CrokCaptainGUIDs[4];
+ uint64 SisterSvalnaGUID;
uint64 SindragosaGUID;
uint64 SpinestalkerGUID;
uint64 RimefangGUID;