diff options
12 files changed, 1688 insertions, 57 deletions
diff --git a/sql/scripts/world_scripts_full.sql b/sql/scripts/world_scripts_full.sql index 97109710071..139988a6fa0 100644 --- a/sql/scripts/world_scripts_full.sql +++ b/sql/scripts/world_scripts_full.sql @@ -891,6 +891,16 @@ UPDATE `creature_template` SET `ScriptName`='npc_captain_grondel' WHERE `entry`= 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_valithria_dreamwalker' WHERE `entry`=36789; +UPDATE `creature_template` SET `ScriptName`='npc_green_dragon_combat_trigger' WHERE `entry`=38752; +UPDATE `creature_template` SET `ScriptName`='npc_the_lich_king_controller' WHERE `entry`=16980; +UPDATE `creature_template` SET `ScriptName`='npc_risen_archmage' WHERE `entry`=37868; +UPDATE `creature_template` SET `ScriptName`='npc_blazing_skeleton' WHERE `entry`=36791; +UPDATE `creature_template` SET `ScriptName`='npc_suppresser' WHERE `entry`=37863; +UPDATE `creature_template` SET `ScriptName`='npc_blistering_zombie' WHERE `entry`=37934; +UPDATE `creature_template` SET `ScriptName`='npc_gluttonous_abomination' WHERE `entry`=37886; +UPDATE `creature_template` SET `ScriptName`='npc_dream_portal' WHERE `entry` IN (37945,38430); +UPDATE `creature_template` SET `ScriptName`='npc_dream_cloud' WHERE `entry` IN (37985,38421); 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; @@ -1800,7 +1810,7 @@ UPDATE `outdoorpvp_template` SET `ScriptName`='outdoorpvp_si' WHERE `TypeId`=5; UPDATE `outdoorpvp_template` SET `ScriptName`='outdoorpvp_ep' WHERE `TypeId`=6; /* ACHIEVEMENTS */ -DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (3693,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,1234,1239,5605,5606,12778,13036,13035,13037,12977,12967,12986,12982,12993,12780,13012,13011,13013,12062,12063,12064,12065,12183,12068,12060,12061,12822,12996,12972,12989,10062,10063,10054,10055,10046,10047,10048,10049,10050,10051,10044,10045,6446,7625,7628,5541,5542,5543,7573,7574,7265,7549) AND `type` IN (0,11); +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (3693,3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,1234,1239,5605,5606,12778,13036,13035,13037,12977,12967,12986,12982,12993,12780,13012,13011,13013,12062,12063,12064,12065,12183,12068,12060,12061,12822,12996,12972,12989,10062,10063,10054,10055,10046,10047,10048,10049,10050,10051,10044,10045,6446,7625,7628,5541,5542,5543,7573,7574,7265,7549,12971,12978,12979,12980) AND `type` IN (0,11); INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES (3693,11,0,0, 'achievement_storm_glory'), (3804,11,0,0, 'achievement_resilient_victory'), @@ -1862,7 +1872,11 @@ INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`, (7573,11,0,0,'achievement_denyin_the_scion'), (7574,11,0,0,'achievement_denyin_the_scion'), (7265,11,0,0,'achievement_momma_said_knock_you_out'), -(7549,11,0,0,'achievement_momma_said_knock_you_out'); +(7549,11,0,0,'achievement_momma_said_knock_you_out'), +(12978,11,0,0,'achievement_portal_jockey'), +(12979,11,0,0,'achievement_portal_jockey'), +(12971,11,0,0,'achievement_portal_jockey'), +(12980,11,0,0,'achievement_portal_jockey'); /* SPELLS */ INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES @@ -2103,6 +2117,21 @@ 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'), +( 71085, 'spell_dreamwalker_mana_void'), +( 70915, 'spell_dreamwalker_decay_periodic_timer'), +( 70912, 'spell_dreamwalker_decay_periodic_timer'), +( 70916, 'spell_dreamwalker_decay_periodic_timer'), +( 70913, 'spell_dreamwalker_decay_periodic_timer'), +( 70921, 'spell_dreamwalker_summoner'), +( 70912, 'spell_dreamwalker_summon_suppresser'), +( 71032, 'spell_dreamwalker_summoner'), +( 71078, 'spell_dreamwalker_summoner'), +( 70933, 'spell_dreamwalker_summoner'), +( 72224, 'spell_dreamwalker_summon_dream_portal'), +( 72480, 'spell_dreamwalker_summon_nightmare_portal'), +( 71970, 'spell_dreamwalker_nightmare_cloud'), +( 72868, 'spell_putricide_slime_puddle_aura'), +( 72869, 'spell_putricide_slime_puddle_aura'), ( 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_20_01_world_achievment_criteria_data.sql b/sql/updates/world/2011_05_20_01_world_achievment_criteria_data.sql new file mode 100644 index 00000000000..25488d8ccae --- /dev/null +++ b/sql/updates/world/2011_05_20_01_world_achievment_criteria_data.sql @@ -0,0 +1,21 @@ +DELETE FROM `disables` WHERE `entry` IN (12757,12954,12971,12978,12979,12980,13048,13059,13099,13124,13125,13126,13335,13355) AND `sourceType`=4; +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (12757,12954,12971,12978,12979,12980,13048,13059,13099,13124,13125,13126,13335,13355); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(12978,12,0,0,''), +(12979,12,1,0,''), +(12971,12,2,0,''), +(12980,12,3,0,''), +(12978,11,0,0,'achievement_portal_jockey'), +(12979,11,0,0,'achievement_portal_jockey'), +(12971,11,0,0,'achievement_portal_jockey'), +(12980,11,0,0,'achievement_portal_jockey'), +(13355,12,1,0,''), +(13335,12,0,0,''), +(12757,12,0,0,''), +(12954,12,1,0,''), +(13048,12,2,0,''), +(13059,12,3,0,''), +(13099,12,0,0,''), +(13125,12,2,0,''), +(13124,12,1,0,''), +(13126,12,3,0,''); diff --git a/sql/updates/world/2011_05_20_01_world_instance_misc.sql b/sql/updates/world/2011_05_20_01_world_instance_misc.sql new file mode 100644 index 00000000000..c3ada3e3f44 --- /dev/null +++ b/sql/updates/world/2011_05_20_01_world_instance_misc.sql @@ -0,0 +1,117 @@ +DELETE FROM `creature_text` WHERE `entry` IN (16980,36789,37491,37493,37494,37495); +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(16980,0,0,'Intruders have breached the inner sanctum. Hasten the destruction of the green dragon! Leave only bones and sinew for the reanimation!',14,0,0,0,0,17251,'The Lich King - SAY_LICH_KING_INTRO'), +(36789,0,0,'Heroes, lend me your aid. I... I cannot hold them off much longer. You must heal my wounds!',14,0,0,0,0,17064,'Valithria Dreamwalker - SAY_VALITHRIA_ENTER_COMBAT'), +(36789,1,0,'I have opened a portal into the Dream. Your salvation lies within, heroes...',14,0,0,0,0,17068,'Valithria Dreamwalker - SAY_VALITHRIA_DREAM_PORTAL'), +(36789,2,0,'My strength is returning! Press on, heroes!',14,0,0,0,0,17070,'Valithria Dreamwalker - SAY_VALITHRIA_75_PERCENT'), +(36789,3,0,'I will not last much longer!',14,0,0,0,0,17069,'Valithria Dreamwalker - SAY_VALITHRIA_25_PERCENT'), +(36789,4,0,'Forgive me for what I do! I... cannot... stop... ONLY NIGHTMARES REMAIN!',14,0,0,0,0,17072,'Valithria Dreamwalker - SAY_VALITHRIA_DEATH'), +(36789,5,0,'A tragic loss...',14,0,0,0,0,17066,'Valithria Dreamwalker - SAY_VALITHRIA_PLAYER_DEATH'), +(36789,6,0,'FAILURES!',14,0,0,0,0,17067,'Valithria Dreamwalker - SAY_VALITHRIA_BERSERK'), +(36789,7,0,'I am renewed! Ysera grants me the favor to lay these foul creatures to rest!',14,0,0,0,0,17071,'Valithria Dreamwalker - SAY_VALITHRIA_SUCCESS'), +(37491,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'), +(37491,2,0, 'THAT was for bringing me spoiled spider ichor!',1,0,0,0,0,16588, 'Captain Arnath - SAY_ARNATH_KILL'), +(37491,3,0, 'Don''t... let Finklestein use me... for his potions...',1,0,0,0,0,16589, 'Captain Arnath - SAY_ARNATH_SECOND_DEATH'), +(37493,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'), +(37493,2,0, 'It doesn''t hurt anymore, does it?',1,0,0,0,0,16812, 'Captain Brandon - SAY_BRANDON_KILL'), +(37493,3,0, 'I''m sorry...',1,0,0,0,0,16813, 'Captain Brandon - SAY_BRANDON_SECOND_DEATH'), +(37494,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'), +(37494,2,0, 'Can you feel the burn?',1,0,0,0,0,16846, 'Captain Grondel - SAY_GRONDEL_KILL'), +(37494,3,0, 'What... have I done? No!',1,0,0,0,0,16847, 'Captain Grondel - SAY_GRONDEL_SECOND_DEATH'), +(37495,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'), +(37495,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'), +(37495,3,0, 'What an... explosive ending!',1,0,0,0,0,17001, 'Captain Rupert - SAY_RUPERT_SECOND_DEATH'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (71948,70588,70602,71946,72031,72032,72033,70921,71032,71078,70933,72706,73843); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES +(13,0,71948,0,18,1,37950,0,0,'','Valithria Dreamwalker - Copy Damage on Valithria'), +(13,0,70588,0,18,1,36789,0,0,'','Suppresser - Suppression target Valithria'), +(13,0,70602,0,18,1,36789,0,0,'','Risen Archmage - Corruption target Valithria'), +(13,0,71946,0,18,1,36789,0,0,'','Valithria Dreamwalker - Nightmare Cloud'), +(13,0,72031,0,18,1,36789,0,0,'','Valithria Dreamwalker - Nightmare Cloud'), +(13,0,72032,0,18,1,36789,0,0,'','Valithria Dreamwalker - Nightmare Cloud'), +(13,0,72033,0,18,1,36789,0,0,'','Valithria Dreamwalker - Nightmare Cloud'), +(13,0,70921,0,18,1,22515,0,0,'','The Lich King - Summon Gluttonous Abomination'), +(13,0,71032,0,18,1,22515,0,0,'','The Lich King - Summon Blistering Zombie'), +(13,0,71078,0,18,1,22515,0,0,'','The Lich King - Summon Risen Archmage'), +(13,0,70933,0,18,1,22515,0,0,'','The Lich King - Summon Blazing Skeleton'), +(13,0,72706,0,18,1,0,0,0,'','Valithria Dreamwalker - Achievement Check'), +(13,0,73843,0,18,1,0,0,0,'','Valithria Dreamwalker - Reputation reward'); + +DELETE FROM `creature_template_addon` WHERE `entry` IN (36789,38174,37934,37950,38068,37918,37907,38168,38726,38736,37945,38430,38186,38429,37985,38421); +INSERT INTO `creature_template_addon` (`entry`,`mount`,`bytes1`,`bytes2`,`emote`,`auras`) VALUES +(36789,0,0x0000000,1,0,'72724 70904'), +(38174,0,0x0000000,1,0,'72724 70904'), +(37934,0,0x0000000,1,0,'70749'), +(37950,0,0x3000000,1,0,''), +(38068,0,0x0000000,1,0,'71085'), +(37918,0,0x0000000,1,0,'70715'), +(37907,0,0x0000000,1,0,'72962'), +(38168,0,0x0000000,1,0,'72962'), +(38726,0,0x0000000,1,0,'72962'), +(38736,0,0x0000000,1,0,'72962'), +(37945,0,0x0000000,1,0,'70763'), -- Dream Portal +(38430,0,0x0000000,1,0,'71994'), -- Nightmare Portal +(38186,0,0x0000000,1,0,'71304'), -- Dream Portal (Pre-effect) +(38429,0,0x0000000,1,0,'71986'), -- Nightmare Portal (Pre-effect) +(37985,0,0x3000000,1,0,'70876'), -- Dream Cloud +(38421,0,0x3000000,1,0,'71939 71970'); -- Nightmre Cloud + +UPDATE `creature_template` SET `minlevel`=83,`maxlevel`=83,`exp`=2,`unit_class`=1,`faction_A`=1665,`faction_H`=1665,`unit_flags`=`unit_flags`|33554432,`baseattacktime`=2000,`scale`=1,`InhabitType`=7 WHERE `entry`=37950; -- Valithria Dreamwalker +UPDATE `creature_template` SET `minlevel`=60,`maxlevel`=60,`unit_class`=1,`faction_A`=14,`faction_H`=14,`unit_flags`=`unit_flags`|33554432,`baseattacktime`=2000,`flags_extra`=`flags_extra`|128 WHERE `entry`=38068; -- Mana Void +UPDATE `creature_template` SET `minlevel`=60,`maxlevel`=60,`unit_class`=1,`faction_A`=14,`faction_H`=14,`unit_flags`=`unit_flags`|33554432,`baseattacktime`=2000,`flags_extra`=`flags_extra`|128 WHERE `entry`=37918; -- Column of Frost +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`unit_class`=1,`faction_A`=35,`faction_H`=35,`npcflag`=`npcflag`|16777216 WHERE `entry` IN (37945,38430); -- Dream Portal and Nightmare Portal +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`faction_A`=35,`faction_H`=35,`unit_flags`=`unit_flags`|33554432,`npcflag`=`npcflag`|16777216,`baseattacktime`=2000 WHERE `entry`=38186; -- Dream Portal (Pre-effect) +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`faction_A`=35,`faction_H`=35,`unit_flags`=`unit_flags`|33554432,`npcflag`=`npcflag`|16777216,`baseattacktime`=2000 WHERE `entry`=38429; -- Nightmare Portal (Pre-effect) +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`unit_class`=1,`faction_A`=2022,`faction_H`=2022,`unit_flags`=`unit_flags`|33554432,`baseattacktime`=2000,`InhabitType`=7,`flags_extra`=`flags_extra`|128 WHERE `entry`=37985; -- Dream Cloud +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`unit_class`=1,`faction_A`=2022,`faction_H`=2022,`unit_flags`=`unit_flags`|33554432,`baseattacktime`=2000,`InhabitType`=7,`flags_extra`=`flags_extra`|128 WHERE `entry`=38421; -- Nightmare Cloud +UPDATE `creature_template` SET `minlevel`=83,`maxlevel`=83,`exp`=2,`unit_class`=1,`faction_A`=35,`faction_H`=35,`npcflag`=`npcflag`|3,`baseattacktime`=2000,`scale`=1 WHERE `entry`=38589; -- Valithria Dreamwalker (questgiver) + +SET @GUID := 137794; +UPDATE `creature` SET `phaseMask`=`phaseMask`|4 WHERE `id`=36789; +-- Add The Lich King and Green Dragon Combat Trigger to all encounter phases, fixes evading when all players enter portals +UPDATE `creature` SET `phaseMask`=`phaseMask`|16 WHERE `guid` IN (137789,137752); +DELETE FROM `creature` WHERE `id` IN (37950,37985,38421) OR `guid`=137793 OR `guid` BETWEEN @GUID+00 AND @GUID+27; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`DeathState`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES +(1636,37950,631,15,20,0,0,4202.847,2484.917,383.8368,0.00000,604800,0,0,0,0,0,0,0,0,0), -- Valithria Dreamwalker (dream phase) +(137793,22515,631,10,1,0,0,4166.170,2411.520,364.9520,1.57080,120,0,0,0,0,0,0,0,0,0), -- World Trigger +-- Dream Cloud +(@GUID+00,37985,631,3,16,0,0,4155.51,2478.76,382.494,4.97053,30,10,0,0,0,0,1,0,0,0), +(@GUID+01,37985,631,3,16,0,0,4158.75,2494.08,384.334,2.31129,30,10,0,0,0,0,1,0,0,0), +(@GUID+02,37985,631,3,16,0,0,4172.57,2464.47,385.368,3.72021,30,10,0,0,0,0,1,0,0,0), +(@GUID+03,37985,631,3,16,0,0,4173.67,2504.13,386.174,2.67313,30,10,0,0,0,0,1,0,0,0), +(@GUID+04,37985,631,3,16,0,0,4181.62,2514.91,386.374,2.65209,30,10,0,0,0,0,1,0,0,0), +(@GUID+05,37985,631,3,16,0,0,4186.72,2450.97,388.373,4.95968,30,10,0,0,0,0,1,0,0,0), +(@GUID+06,37985,631,3,16,0,0,4200.96,2456.00,387.128,3.58291,30,10,0,0,0,0,1,0,0,0), +(@GUID+07,37985,631,3,16,0,0,4202.23,2508.00,383.985,2.09137,30,10,0,0,0,0,1,0,0,0), +(@GUID+08,37985,631,3,16,0,0,4220.35,2515.16,388.649,2.34469,30,10,0,0,0,0,1,0,0,0), +(@GUID+09,37985,631,3,16,0,0,4222.26,2455.20,385.568,0.00000,30,10,0,0,0,0,1,0,0,0), +(@GUID+10,37985,631,3,16,0,0,4231.61,2464.44,389.011,0.00000,30,10,0,0,0,0,1,0,0,0), +(@GUID+11,37985,631,3,16,0,0,4236.75,2500.62,383.373,5.97527,30,10,0,0,0,0,1,0,0,0), +(@GUID+12,37985,631,3,16,0,0,4243.29,2476.89,386.076,0.00000,30,10,0,0,0,0,1,0,0,0), +(@GUID+13,37985,631,3,16,0,0,4244.83,2493.18,387.677,4.29139,30,10,0,0,0,0,1,0,0,0), +-- Nightmare Cloud +(@GUID+14,38421,631,12,20,0,0,4155.51,2478.76,382.494,4.97053,30,10,0,0,0,0,1,0,0,0), +(@GUID+15,38421,631,12,20,0,0,4158.75,2494.08,384.334,2.31129,30,10,0,0,0,0,1,0,0,0), +(@GUID+16,38421,631,12,20,0,0,4172.57,2464.47,385.368,3.72021,30,10,0,0,0,0,1,0,0,0), +(@GUID+17,38421,631,12,20,0,0,4181.62,2514.91,386.374,2.65209,30,10,0,0,0,0,1,0,0,0), +(@GUID+18,38421,631,12,20,0,0,4200.96,2456.00,387.128,3.58291,30,10,0,0,0,0,1,0,0,0), +(@GUID+19,38421,631,12,20,0,0,4202.23,2508.00,383.985,2.09137,30,10,0,0,0,0,1,0,0,0), +(@GUID+20,38421,631,12,20,0,0,4220.35,2515.16,388.649,2.34469,30,10,0,0,0,0,1,0,0,0), +(@GUID+21,38421,631,12,20,0,0,4222.26,2455.20,385.568,0.00000,30,10,0,0,0,0,1,0,0,0), +(@GUID+22,38421,631,12,20,0,0,4236.75,2500.62,383.373,5.97527,30,10,0,0,0,0,1,0,0,0), +(@GUID+23,38421,631,12,20,0,0,4243.29,2476.89,386.076,0.00000,30,10,0,0,0,0,1,0,0,0); + +DELETE FROM `linked_respawn` WHERE `guid`=137789 AND `linkType`=0; +INSERT INTO `linked_respawn` (`guid`,`linkedGuid`,`linkType`) VALUES +(137789,137752,0); -- The Lich King link to Green Dragon Combat Trigger + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (37945,38430,38186,38429); +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 +(37945,70766,0,0,0,3,0,0,0), -- Dream Portal +(38430,70766,0,0,0,3,0,0,0), -- Nightmare Portal +(38186,70766,0,0,0,3,0,0,0), -- Dream Portal (Pre-effect) +(38429,70766,0,0,0,3,0,0,0); -- Nightmare Portal (Pre-effect) + +-- Gates should also exist in all phases, prevent players from leaving room +UPDATE `gameobject` SET `phaseMask`=`phaseMask`|16 WHERE `id` IN (201375,201374,201380,201381,201382,201383); diff --git a/sql/updates/world/2011_05_20_01_world_scriptname.sql b/sql/updates/world/2011_05_20_01_world_scriptname.sql new file mode 100644 index 00000000000..df6b179c8ca --- /dev/null +++ b/sql/updates/world/2011_05_20_01_world_scriptname.sql @@ -0,0 +1,10 @@ +UPDATE `creature_template` SET `ScriptName`='boss_valithria_dreamwalker' WHERE `entry`=36789; +UPDATE `creature_template` SET `ScriptName`='npc_green_dragon_combat_trigger' WHERE `entry`=38752; +UPDATE `creature_template` SET `ScriptName`='npc_the_lich_king_controller' WHERE `entry`=16980; +UPDATE `creature_template` SET `ScriptName`='npc_risen_archmage' WHERE `entry`=37868; +UPDATE `creature_template` SET `ScriptName`='npc_blazing_skeleton' WHERE `entry`=36791; +UPDATE `creature_template` SET `ScriptName`='npc_suppresser' WHERE `entry`=37863; +UPDATE `creature_template` SET `ScriptName`='npc_blistering_zombie' WHERE `entry`=37934; +UPDATE `creature_template` SET `ScriptName`='npc_gluttonous_abomination' WHERE `entry`=37886; +UPDATE `creature_template` SET `ScriptName`='npc_dream_portal' WHERE `entry` IN (37945,38430); +UPDATE `creature_template` SET `ScriptName`='npc_dream_cloud' WHERE `entry` IN (37985,38421); diff --git a/sql/updates/world/2011_05_20_01_world_spell_script_names.sql b/sql/updates/world/2011_05_20_01_world_spell_script_names.sql new file mode 100644 index 00000000000..106efd790e7 --- /dev/null +++ b/sql/updates/world/2011_05_20_01_world_spell_script_names.sql @@ -0,0 +1,25 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_dreamwalker_mana_void'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_dreamwalker_decay_periodic_timer'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_dreamwalker_summoner'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_dreamwalker_summon_suppresser'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_dreamwalker_summon_dream_portal'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_dreamwalker_summon_nightmare_portal'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_dreamwalker_nightmare_cloud'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_putricide_slime_puddle_aura'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(71085,'spell_dreamwalker_mana_void'), +(70915,'spell_dreamwalker_decay_periodic_timer'), +(70912,'spell_dreamwalker_decay_periodic_timer'), +(70916,'spell_dreamwalker_decay_periodic_timer'), +(70913,'spell_dreamwalker_decay_periodic_timer'), +(70921,'spell_dreamwalker_summoner'), +(70912,'spell_dreamwalker_summon_suppresser'), +(71032,'spell_dreamwalker_summoner'), +(71078,'spell_dreamwalker_summoner'), +(70933,'spell_dreamwalker_summoner'), +(72224,'spell_dreamwalker_summon_dream_portal'), +(72480,'spell_dreamwalker_summon_nightmare_portal'), +(71970,'spell_dreamwalker_nightmare_cloud'), +-- bind only on heroic modes, normal does not need this replacement +(72868,'spell_putricide_slime_puddle_aura'), +(72869,'spell_putricide_slime_puddle_aura'); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 482b8f51c73..969294733d5 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -476,6 +476,7 @@ void AddSC_boss_rotface(); void AddSC_boss_professor_putricide(); void AddSC_boss_blood_prince_council(); void AddSC_boss_blood_queen_lana_thel(); +void AddSC_boss_valithria_dreamwalker(); void AddSC_boss_sindragosa(); void AddSC_icecrown_citadel_teleport(); void AddSC_instance_icecrown_citadel(); @@ -1171,6 +1172,7 @@ void AddNorthrendScripts() AddSC_boss_professor_putricide(); AddSC_boss_blood_prince_council(); AddSC_boss_blood_queen_lana_thel(); + AddSC_boss_valithria_dreamwalker(); AddSC_boss_sindragosa(); AddSC_icecrown_citadel_teleport(); AddSC_instance_icecrown_citadel(); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 8d98ae1a5a9..5791d311281 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -4099,6 +4099,24 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->AreaGroupId = 0; ++count; break; + case 70588: // Suppression + case 70602: // Corruption + spellInfo->AttributesEx |= SPELL_ATTR1_STACK_FOR_DIFF_CASTERS; + ++count; + break; + case 70715: // Column of Frost (visual marker) + spellInfo->DurationIndex = 32; // 6 seconds (missing) + ++count; + break; + case 71085: // Mana Void (periodic aura) + spellInfo->DurationIndex = 9; // 30 seconds (missing) + ++count; + break; + case 70936: // Summon Suppressor + spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ANY; + spellInfo->EffectImplicitTargetB[0] = 0; + ++count; + break; case 71357: // Order Whelp spellInfo->EffectRadiusIndex[0] = 22; ++count; diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index 79f36fe3763..88e551cd6b6 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -165,6 +165,7 @@ set(scripts_STAT_SRCS Northrend/IcecrownCitadel/boss_professor_putricide.cpp Northrend/IcecrownCitadel/boss_blood_prince_council.cpp Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp + Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp Northrend/IcecrownCitadel/boss_sindragosa.cpp Northrend/zuldrak.cpp Northrend/icecrown.cpp diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp index 2844376fe21..af5d50fc11c 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp @@ -932,6 +932,34 @@ class spell_putricide_slime_puddle : public SpellScriptLoader } }; +// this is here only because on retail you dont actually enter HEROIC mode for ICC +class spell_putricide_slime_puddle_aura : public SpellScriptLoader +{ + public: + spell_putricide_slime_puddle_aura() : SpellScriptLoader("spell_putricide_slime_puddle_aura") { } + + class spell_putricide_slime_puddle_aura_SpellScript : public SpellScript + { + PrepareSpellScript(spell_putricide_slime_puddle_aura_SpellScript); + + void ReplaceAura() + { + if (Unit* target = GetHitUnit()) + GetCaster()->AddAura((GetCaster()->GetMap()->GetSpawnMode() & 1) ? 72456 : 70346, target); + } + + void Register() + { + OnHit += SpellHitFn(spell_putricide_slime_puddle_aura_SpellScript::ReplaceAura); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_putricide_slime_puddle_aura_SpellScript(); + } +}; + class spell_putricide_unstable_experiment : public SpellScriptLoader { public: @@ -1516,6 +1544,7 @@ void AddSC_boss_professor_putricide() new spell_putricide_ooze_channel(); new spell_putricide_expunged_gas(); new spell_putricide_slime_puddle(); + new spell_putricide_slime_puddle_aura(); new spell_putricide_unstable_experiment(); new spell_putricide_ooze_summon(); new spell_putricide_ooze_eruption_searcher(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp new file mode 100644 index 00000000000..d99b5395a74 --- /dev/null +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -0,0 +1,1324 @@ +/* + * Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "Cell.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "icecrown_citadel.h" + +enum Texts +{ + // The Lich King + SAY_LICH_KING_INTRO = 0, + + // Valithria Dreamwalker + SAY_VALITHRIA_ENTER_COMBAT = 0, + SAY_VALITHRIA_DREAM_PORTAL = 1, + SAY_VALITHRIA_75_PERCENT = 2, + SAY_VALITHRIA_25_PERCENT = 3, + SAY_VALITHRIA_DEATH = 4, + SAY_VALITHRIA_PLAYER_DEATH = 5, + SAY_VALITHRIA_BERSERK = 6, + SAY_VALITHRIA_SUCCESS = 7, +}; + +enum Spells +{ + // Valithria Dreamwalker + SPELL_COPY_DAMAGE = 71948, + SPELL_DREAM_PORTAL_VISUAL_PRE = 71304, + SPELL_NIGHTMARE_PORTAL_VISUAL_PRE = 71986, + SPELL_NIGHTMARE_CLOUD = 71970, + SPELL_NIGHTMARE_CLOUD_VISUAL = 71939, + SPELL_PRE_SUMMON_DREAM_PORTAL = 72224, + SPELL_PRE_SUMMON_NIGHTMARE_PORTAL = 72480, + SPELL_SUMMON_DREAM_PORTAL = 71305, + SPELL_SUMMON_NIGHTMARE_PORTAL = 71987, + SPELL_DREAMWALKERS_RAGE = 71189, + SPELL_DREAM_SLIP = 71196, + SPELL_ACHIEVEMENT_CHECK = 72706, + SPELL_CLEAR_ALL = 71721, + SPELL_AWARD_REPUTATION_BOSS_KILL = 73843, + SPELL_CORRUPTION_VALITHRIA = 70904, + + // The Lich King + SPELL_TIMER_GLUTTONOUS_ABOMINATION = 70915, + SPELL_TIMER_SUPPRESSER = 70912, + SPELL_TIMER_BLISTERING_ZOMBIE = 70914, + SPELL_TIMER_RISEN_ARCHMAGE = 70916, + SPELL_TIMER_BLAZING_SKELETON = 70913, + SPELL_SUMMON_SUPPRESSER = 70936, + SPELL_RECENTLY_SPAWNED = 72954, + SPELL_SPAWN_CHEST = 71207, + + // Risen Archmage + SPELL_CORRUPTION = 70602, + SPELL_FROSTBOLT_VOLLEY = 70759, + SPELL_MANA_VOID = 71179, + SPELL_COLUMN_OF_FROST = 70704, + SPELL_COLUMN_OF_FROST_DAMAGE = 70702, + + // Blazing Skeleton + SPELL_FIREBALL = 70754, + SPELL_LEY_WASTE = 69325, + + // Suppresser + SPELL_SUPPRESSION = 70588, + + // Blistering Zombie + SPELL_ACID_BURST = 70744, + + // Gluttonous Abomination + SPELL_GUT_SPRAY = 70633, + SPELL_ROT_WORM_SPAWNER = 70675, + + // Dream Cloud + SPELL_EMERALD_VIGOR = 70873, + + // Nightmare Cloud + SPELL_TWISTED_NIGHTMARE = 71941, +}; + +#define SUMMON_PORTAL RAID_MODE<uint32>(SPELL_PRE_SUMMON_DREAM_PORTAL, SPELL_PRE_SUMMON_DREAM_PORTAL, \ + SPELL_PRE_SUMMON_NIGHTMARE_PORTAL, SPELL_PRE_SUMMON_NIGHTMARE_PORTAL) + +#define EMERALD_VIGOR RAID_MODE<uint32>(SPELL_EMERALD_VIGOR, SPELL_EMERALD_VIGOR, \ + SPELL_TWISTED_NIGHTMARE, SPELL_TWISTED_NIGHTMARE) + +enum Events +{ + // Valithria Dreamwalker + EVENT_INTRO_TALK = 1, + EVENT_BERSERK, + EVENT_DREAM_PORTAL, + EVENT_DREAM_SLIP, + + // The Lich King + EVENT_GLUTTONOUS_ABOMINATION_SUMMONER, + EVENT_SUPPRESSER_SUMMONER, + EVENT_BLISTERING_ZOMBIE_SUMMONER, + EVENT_RISEN_ARCHMAGE_SUMMONER, + EVENT_BLAZING_SKELETON_SUMMONER, + + // Risen Archmage + EVENT_FROSTBOLT_VOLLEY, + EVENT_MANA_VOID, + EVENT_COLUMN_OF_FROST, + + // Blazing Skeleton + EVENT_FIREBALL, + EVENT_LEY_WASTE, + + // Suppresser + EVENT_SUPPRESSION, + + // Gluttonous Abomination + EVENT_GUT_SPRAY, + + // Dream Cloud + // Nightmare Cloud + EVENT_CHECK_PLAYER, + EVENT_EXPLODE, +}; + +enum Actions +{ + ACTION_ENTER_COMBAT = 1, + MISSED_PORTALS = 2, + ACTION_DEATH = 3, +}; + +Position const ValithriaSpawnPos = {4210.813f, 2484.443f, 364.9558f, 0.01745329f}; + +class RisenArchmageCheck +{ + public: + // look for all permanently spawned Risen Archmages that are not yet in combat + bool operator()(Creature* creature) + { + return creature->isAlive() && creature->GetEntry() == NPC_RISEN_ARCHMAGE && + creature->GetDBTableGUIDLow() && !creature->isInCombat(); + } +}; + +struct ManaVoidSelector : public std::unary_function<Unit*, bool> +{ + explicit ManaVoidSelector(WorldObject const* source) : _source(source) { } + + bool operator()(Unit* unit) const + { + return unit->getPowerType() == POWER_MANA && _source->GetDistance(unit) > 15.0f; + } + + WorldObject const* _source; +}; + +class DelayedCastEvent : public BasicEvent +{ + public: + DelayedCastEvent(Creature* trigger, uint32 spellId, uint64 originalCaster, uint32 despawnTime) : _trigger(trigger), _spellId(spellId), _originalCaster(originalCaster), _despawnTime(despawnTime) + { + } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) + { + _trigger->CastSpell(_trigger, _spellId, false, NULL, NULL, _originalCaster); + if (_despawnTime) + _trigger->DespawnOrUnsummon(_despawnTime); + return true; + } + + private: + Creature* _trigger; + uint64 _originalCaster; + uint32 _spellId; + uint32 _despawnTime; +}; + +class AuraRemoveEvent : public BasicEvent +{ + public: + AuraRemoveEvent(Creature* trigger, uint32 spellId) : _trigger(trigger), _spellId(spellId) + { + } + + bool Execute(uint64 /*time*/, uint32 /*diff*/) + { + _trigger->RemoveAurasDueToSpell(_spellId); + return true; + } + + private: + Creature* _trigger; + uint32 _spellId; +}; + +class SummonTargetSelector +{ + public: + bool operator()(Unit* unit) const + { + return unit->HasAura(SPELL_RECENTLY_SPAWNED); + } +}; + +class ValithriaDespawner : public BasicEvent +{ + public: + explicit ValithriaDespawner(Creature* creature) : _creature(creature) + { + } + + bool Execute(uint64 /*currTime*/, uint32 /*diff*/) + { + Trinity::CreatureWorker<ValithriaDespawner> worker(_creature, *this); + _creature->VisitNearbyGridObject(333.0f, worker); + return true; + } + + void operator()(Creature* creature) const + { + switch (creature->GetEntry()) + { + case NPC_VALITHRIA_DREAMWALKER: + if (InstanceScript* instance = creature->GetInstanceScript()) + instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, creature); + break; + case NPC_BLAZING_SKELETON: + case NPC_SUPPRESSER: + case NPC_BLISTERING_ZOMBIE: + case NPC_GLUTTONOUS_ABOMINATION: + case NPC_MANA_VOID: + case NPC_COLUMN_OF_FROST: + creature->DespawnOrUnsummon(); + return; + case NPC_RISEN_ARCHMAGE: + if (!creature->GetDBTableGUIDLow()) + { + creature->DespawnOrUnsummon(); + return; + } + creature->Respawn(true); + break; + default: + return; + } + + uint32 corpseDelay = creature->GetCorpseDelay(); + uint32 respawnDelay = creature->GetRespawnDelay(); + creature->SetCorpseDelay(1); + creature->SetRespawnDelay(10); + + if (CreatureData const* data = creature->GetCreatureData()) + creature->SetPosition(data->posX, data->posY, data->posZ, data->orientation); + creature->ForcedDespawn(); + + creature->SetCorpseDelay(corpseDelay); + creature->SetRespawnDelay(respawnDelay); + } + + private: + Creature* _creature; +}; + +class boss_valithria_dreamwalker : public CreatureScript +{ + public: + boss_valithria_dreamwalker() : CreatureScript("boss_valithria_dreamwalker") { } + + struct boss_valithria_dreamwalkerAI : public ScriptedAI + { + boss_valithria_dreamwalkerAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()), _portalCount(RAID_MODE<uint32>(3, 8, 3, 8)) + { + } + + void InitializeAI() + { + if (CreatureData const* data = sObjectMgr->GetCreatureData(me->GetDBTableGUIDLow())) + if (data->curhealth) + _spawnHealth = data->curhealth; + } + + void Reset() + { + me->SetHealth(_spawnHealth); + me->SetReactState(REACT_PASSIVE); + me->LoadCreaturesAddon(true); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + _missedPortals = 0; + _under25PercentTalkDone = false; + _over75PercentTalkDone = false; + _justDied = false; + } + + void AttackStart(Unit* /*target*/) + { + } + + void DoAction(int32 const action) + { + if (action != ACTION_ENTER_COMBAT) + return; + + DoCast(me, SPELL_COPY_DAMAGE); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ADD, me); + _events.ScheduleEvent(EVENT_INTRO_TALK, 15000); + _events.ScheduleEvent(EVENT_DREAM_PORTAL, urand(45000, 48000)); + if (IsHeroic()) + _events.ScheduleEvent(EVENT_BERSERK, 420000); + } + + void HealReceived(Unit* /*healer*/, uint32& heal) + { + // encounter complete + if (me->HealthAbovePctHealed(100, heal)) + { + Talk(SAY_VALITHRIA_SUCCESS); + me->RemoveAurasDueToSpell(SPELL_CORRUPTION_VALITHRIA); + DoCast(me, SPELL_ACHIEVEMENT_CHECK); + DoCast(me, SPELL_DREAMWALKERS_RAGE); + _events.ScheduleEvent(EVENT_DREAM_SLIP, 3500); + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_LICH_KING))) + lichKing->AI()->EnterEvadeMode(); + } + else if (!_over75PercentTalkDone && me->HealthAbovePctHealed(75, heal)) + { + _over75PercentTalkDone = true; + Talk(SAY_VALITHRIA_75_PERCENT); + } + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + if (me->HealthBelowPctDamaged(25, damage)) + { + if (!_under25PercentTalkDone) + { + _under25PercentTalkDone = true; + Talk(SAY_VALITHRIA_25_PERCENT); + } + + if (damage > me->GetHealth() && !_justDied) + { + _justDied = true; + Talk(SAY_VALITHRIA_DEATH); + _instance->SendEncounterUnit(ENCOUNTER_FRAME_REMOVE, me); + if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_TRIGGER))) + trigger->AI()->DoAction(ACTION_DEATH); + } + } + } + + void SpellHit(Unit* /*caster*/, SpellEntry const* spell) + { + if (spell->Id == SPELL_DREAM_SLIP) + { + DoCast(me, SPELL_CLEAR_ALL); + DoCast(me, SPELL_AWARD_REPUTATION_BOSS_KILL); + // this display id was found in sniff instead of the one on aura + me->SetDisplayId(11686); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->DespawnOrUnsummon(4000); + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_LICH_KING))) + lichKing->CastSpell(lichKing, SPELL_SPAWN_CHEST, false); + + if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_TRIGGER))) + me->Kill(trigger); + } + } + + void JustSummoned(Creature* summon) + { + if (summon->GetEntry() == NPC_DREAM_PORTAL_PRE_EFFECT) + { + summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_DREAM_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000)); + summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_DREAM_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000)); + } + else if (summon->GetEntry() == NPC_NIGHTMARE_PORTAL_PRE_EFFECT) + { + summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_NIGHTMARE_PORTAL, me->GetGUID(), 6000), summon->m_Events.CalculateTime(15000)); + summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_NIGHTMARE_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000)); + } + } + + void SummonedCreatureDespawn(Creature* summon) + { + if (summon->GetEntry() == NPC_DREAM_PORTAL || summon->GetEntry() == NPC_NIGHTMARE_PORTAL) + if (summon->AI()->GetData(MISSED_PORTALS)) + ++_missedPortals; + } + + void UpdateAI(uint32 const diff) + { + // does not enter combat + if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) != IN_PROGRESS) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_TALK: + Talk(SAY_VALITHRIA_ENTER_COMBAT); + break; + case EVENT_BERSERK: + Talk(SAY_VALITHRIA_BERSERK); + break; + case EVENT_DREAM_PORTAL: + if (!IsHeroic()) + Talk(SAY_VALITHRIA_DREAM_PORTAL); + for (uint32 i = 0; i < _portalCount; ++i) + DoCast(me, SUMMON_PORTAL); + _events.ScheduleEvent(EVENT_DREAM_PORTAL, urand(45000, 48000)); + break; + case EVENT_DREAM_SLIP: + DoCast(me, SPELL_DREAM_SLIP); + break; + default: + break; + } + } + } + + uint32 GetData(uint32 type) + { + if (type == MISSED_PORTALS) + return _missedPortals; + + return 0; + } + + private: + EventMap _events; + InstanceScript* _instance; + uint32 _spawnHealth; + uint32 const _portalCount; + uint32 _missedPortals; + bool _under25PercentTalkDone; + bool _over75PercentTalkDone; + bool _justDied; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<boss_valithria_dreamwalkerAI>(creature); + } +}; + +class npc_green_dragon_combat_trigger : public CreatureScript +{ + public: + npc_green_dragon_combat_trigger() : CreatureScript("npc_green_dragon_combat_trigger") { } + + struct npc_green_dragon_combat_triggerAI : public BossAI + { + npc_green_dragon_combat_triggerAI(Creature* creature) : BossAI(creature, DATA_VALITHRIA_DREAMWALKER) + { + } + + void Reset() + { + _Reset(); + me->SetReactState(REACT_PASSIVE); + } + + void EnterCombat(Unit* /*target*/) + { + me->setActive(true); + DoZoneInCombat(); + instance->SetBossState(DATA_VALITHRIA_DREAMWALKER, IN_PROGRESS); + if (Creature* valithria = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VALITHRIA_DREAMWALKER))) + valithria->AI()->DoAction(ACTION_ENTER_COMBAT); + } + + void AttackStart(Unit* target) + { + if (target->GetEntry() != NPC_VALITHRIA_DREAMWALKER) + BossAI::AttackStart(target); + } + + void JustReachedHome() + { + BossAI::JustReachedHome(); + DoAction(ACTION_DEATH); + } + + void DoAction(int32 const action) + { + if (action == ACTION_DEATH) + { + instance->SetBossState(DATA_VALITHRIA_DREAMWALKER, FAIL); + me->m_Events.AddEvent(new ValithriaDespawner(me), me->m_Events.CalculateTime(5000)); + } + } + + void UpdateAI(uint32 const /*diff*/) + { + UpdateVictim(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_green_dragon_combat_triggerAI>(creature); + } +}; + +class npc_the_lich_king_controller : public CreatureScript +{ + public: + npc_the_lich_king_controller() : CreatureScript("npc_the_lich_king_controller") { } + + struct npc_the_lich_king_controllerAI : public ScriptedAI + { + npc_the_lich_king_controllerAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_GLUTTONOUS_ABOMINATION_SUMMONER, 5000); + _events.ScheduleEvent(EVENT_SUPPRESSER_SUMMONER, 10000); + _events.ScheduleEvent(EVENT_BLISTERING_ZOMBIE_SUMMONER, 15000); + _events.ScheduleEvent(EVENT_RISEN_ARCHMAGE_SUMMONER, 20000); + _events.ScheduleEvent(EVENT_BLAZING_SKELETON_SUMMONER, 30000); + me->SetReactState(REACT_PASSIVE); + } + + void JustReachedHome() + { + me->setActive(false); + } + + void EnterCombat(Unit* /*target*/) + { + Talk(SAY_LICH_KING_INTRO); + me->setActive(true); + } + + void JustSummoned(Creature* summon) + { + // must not be in dream phase + summon->SetPhaseMask((summon->GetPhaseMask() & ~0x10), true); + } + + 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_GLUTTONOUS_ABOMINATION_SUMMONER: + DoCast(me, SPELL_TIMER_GLUTTONOUS_ABOMINATION); + break; + case EVENT_SUPPRESSER_SUMMONER: + DoCast(me, SPELL_TIMER_SUPPRESSER); + break; + case EVENT_BLISTERING_ZOMBIE_SUMMONER: + DoCast(me, SPELL_TIMER_BLISTERING_ZOMBIE); + break; + case EVENT_RISEN_ARCHMAGE_SUMMONER: + DoCast(me, SPELL_TIMER_RISEN_ARCHMAGE); + break; + case EVENT_BLAZING_SKELETON_SUMMONER: + DoCast(me, SPELL_TIMER_BLAZING_SKELETON); + break; + default: + break; + } + } + } + + private: + EventMap _events; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new npc_the_lich_king_controllerAI(creature); + } +}; + +class npc_risen_archmage : public CreatureScript +{ + public: + npc_risen_archmage() : CreatureScript("npc_risen_archmage") { } + + struct npc_risen_archmageAI : public ScriptedAI + { + npc_risen_archmageAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + bool CanAIAttack(Unit const* target) const + { + return target->GetEntry() != NPC_VALITHRIA_DREAMWALKER; + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, urand(5000, 15000)); + _events.ScheduleEvent(EVENT_MANA_VOID, urand(20000, 25000)); + _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, urand(10000, 20000)); + _canCallEnterCombat = true; + } + + void EnterCombat(Unit* /*target*/) + { + me->FinishSpell(CURRENT_CHANNELED_SPELL, false); + if (me->GetDBTableGUIDLow() && _canCallEnterCombat) + { + std::list<Creature*> archmages; + RisenArchmageCheck check; + Trinity::CreatureListSearcher<RisenArchmageCheck> searcher(me, archmages, check); + me->VisitNearbyGridObject(100.0f, searcher); + for (std::list<Creature*>::iterator itr = archmages.begin(); itr != archmages.end(); ++itr) + (*itr)->AI()->DoAction(ACTION_ENTER_COMBAT); + + if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_LICH_KING))) + lichKing->AI()->DoZoneInCombat(); + + if (Creature* trigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_TRIGGER))) + trigger->AI()->DoZoneInCombat(); + } + } + + void DoAction(int32 const action) + { + if (action != ACTION_ENTER_COMBAT) + return; + + _canCallEnterCombat = false; + DoZoneInCombat(); + _canCallEnterCombat = true; + } + + void JustSummoned(Creature* summon) + { + if (summon->GetEntry() == NPC_COLUMN_OF_FROST) + summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_COLUMN_OF_FROST_DAMAGE, 0, 8000), summon->m_Events.CalculateTime(2000)); + else if (summon->GetEntry() == NPC_MANA_VOID) + summon->DespawnOrUnsummon(36000); + } + + void UpdateAI(uint32 const diff) + { + if (!me->isInCombat()) + if (me->GetDBTableGUIDLow()) + if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) + DoCast(me, SPELL_CORRUPTION); + + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FROSTBOLT_VOLLEY: + DoCast(me, SPELL_FROSTBOLT_VOLLEY); + _events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, urand(8000, 15000)); + break; + case EVENT_MANA_VOID: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, ManaVoidSelector(me))) + DoCast(target, SPELL_MANA_VOID); + _events.ScheduleEvent(EVENT_MANA_VOID, urand(20000, 25000)); + break; + case EVENT_COLUMN_OF_FROST: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, -10.0f, true)) + DoCast(target, SPELL_COLUMN_OF_FROST); + _events.ScheduleEvent(EVENT_COLUMN_OF_FROST, urand(15000, 25000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + InstanceScript* _instance; + bool _canCallEnterCombat; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_risen_archmageAI>(creature); + } +}; + +class npc_blazing_skeleton : public CreatureScript +{ + public: + npc_blazing_skeleton() : CreatureScript("npc_blazing_skeleton") { } + + struct npc_blazing_skeletonAI : public ScriptedAI + { + npc_blazing_skeletonAI(Creature* creature) : ScriptedAI(creature) + { + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_FIREBALL, urand(2000, 4000)); + _events.ScheduleEvent(EVENT_LEY_WASTE, urand(15000, 20000)); + } + + 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_FIREBALL: + if (!me->IsWithinMeleeRange(me->getVictim())) + DoCastVictim(SPELL_FIREBALL); + _events.ScheduleEvent(EVENT_FIREBALL, urand(2000, 4000)); + break; + case EVENT_LEY_WASTE: + DoCast(me, SPELL_LEY_WASTE); + _events.ScheduleEvent(EVENT_LEY_WASTE, urand(15000, 20000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_blazing_skeletonAI>(creature); + } +}; + +class npc_suppresser : public CreatureScript +{ + public: + npc_suppresser() : CreatureScript("npc_suppresser") { } + + struct npc_suppresserAI : public ScriptedAI + { + npc_suppresserAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_SUPPRESSION, urand(10000, 15000)); + me->SetReactState(REACT_PASSIVE); + } + + void IsSummonedBy(Unit* /*summoner*/) + { + if (Creature* valithria = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_VALITHRIA_DREAMWALKER))) + AttackStart(valithria); + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + // this code will never be reached while channeling + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SUPPRESSION: + DoCast(me, SPELL_SUPPRESSION); + _events.ScheduleEvent(EVENT_SUPPRESSION, 5000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + InstanceScript* const _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_suppresserAI>(creature); + } +}; + +class npc_blistering_zombie : public CreatureScript +{ + public: + npc_blistering_zombie() : CreatureScript("npc_blistering_zombie") { } + + struct npc_blistering_zombieAI : public ScriptedAI + { + npc_blistering_zombieAI(Creature* creature) : ScriptedAI(creature) + { + } + + void JustDied(Unit* killer) + { + DoCast(me, SPELL_ACID_BURST, true); + } + + void UpdateAI(uint32 const diff) + { + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_blistering_zombieAI>(creature); + } +}; + +class npc_gluttonous_abomination : public CreatureScript +{ + public: + npc_gluttonous_abomination() : CreatureScript("npc_gluttonous_abomination") { } + + struct npc_gluttonous_abominationAI : public ScriptedAI + { + npc_gluttonous_abominationAI(Creature* creature) : ScriptedAI(creature) + { + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_GUT_SPRAY, urand(10000, 13000)); + } + + void JustDied(Unit* /*killer*/) + { + DoCast(me, SPELL_ROT_WORM_SPAWNER, true); + } + + 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_GUT_SPRAY: + DoCast(me, SPELL_GUT_SPRAY); + _events.ScheduleEvent(EVENT_GUT_SPRAY, urand(10000, 13000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_gluttonous_abominationAI>(creature); + } +}; + +class npc_dream_portal : public CreatureScript +{ + public: + npc_dream_portal() : CreatureScript("npc_dream_portal") { } + + struct npc_dream_portalAI : public CreatureAI + { + npc_dream_portalAI(Creature* creature) : CreatureAI(creature), + _used(false) + { + } + + void DoAction(int32 const action) + { + if (action != EVENT_SPELLCLICK) + return; + + _used = true; + me->DespawnOrUnsummon(); + } + + uint32 GetData(uint32 type) + { + return (type == MISSED_PORTALS && _used) ? 0 : 1; + } + + void UpdateAI(uint32 const /*diff*/) + { + UpdateVictim(); + } + + private: + bool _used; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_dream_portalAI>(creature); + } +}; + +class npc_dream_cloud : public CreatureScript +{ + public: + npc_dream_cloud() : CreatureScript("npc_dream_cloud") { } + + struct npc_dream_cloudAI : public ScriptedAI + { + npc_dream_cloudAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + } + + void Reset() + { + _events.Reset(); + _events.ScheduleEvent(EVENT_CHECK_PLAYER, 1000); + me->SetCorpseDelay(0); // remove corpse immediately + me->LoadCreaturesAddon(true); + } + + void UpdateAI(uint32 const diff) + { + // trigger + if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) != IN_PROGRESS) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CHECK_PLAYER: + { + Player* player = NULL; + Trinity::AnyPlayerInObjectRangeCheck check(me, 5.0f); + Trinity::PlayerSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(me, player, check); + me->VisitNearbyWorldObject(7.5f, searcher); + _events.ScheduleEvent(player ? EVENT_EXPLODE : EVENT_CHECK_PLAYER, 1000); + break; + } + case EVENT_EXPLODE: + me->GetMotionMaster()->MoveIdle(); + // must use originalCaster the same for all clouds to allow stacking + me->CastSpell(me, EMERALD_VIGOR, false, NULL, NULL, _instance->GetData64(DATA_VALITHRIA_DREAMWALKER)); + me->ForcedDespawn(100); + break; + default: + break; + } + } + } + + private: + EventMap _events; + InstanceScript* _instance; + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetIcecrownCitadelAI<npc_dream_cloudAI>(creature); + } +}; + +class spell_dreamwalker_mana_void : public SpellScriptLoader +{ + public: + spell_dreamwalker_mana_void() : SpellScriptLoader("spell_dreamwalker_mana_void") { } + + class spell_dreamwalker_mana_void_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dreamwalker_mana_void_AuraScript); + + void PeriodicTick(AuraEffect const* aurEff) + { + // first 3 ticks have amplitude 1 second + // remaining tick every 500ms + if (aurEff->GetTickNumber() <= 5) + if (!(aurEff->GetTickNumber() & 1)) + PreventDefaultAction(); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_dreamwalker_mana_void_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_dreamwalker_mana_void_AuraScript(); + } +}; + +class spell_dreamwalker_decay_periodic_timer : public SpellScriptLoader +{ + public: + spell_dreamwalker_decay_periodic_timer() : SpellScriptLoader("spell_dreamwalker_decay_periodic_timer") { } + + class spell_dreamwalker_decay_periodic_timer_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dreamwalker_decay_periodic_timer_AuraScript); + + bool Load() + { + _decayRate = GetId() != SPELL_TIMER_BLAZING_SKELETON ? 1000 : 5000; + return true; + } + + void DecayPeriodicTimer(AuraEffect* aurEff) + { + int32 timer = aurEff->GetPeriodicTimer(); + if (timer <= 5) + return; + + aurEff->SetPeriodicTimer(timer - _decayRate); + } + + void Register() + { + OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_dreamwalker_decay_periodic_timer_AuraScript::DecayPeriodicTimer, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + + int32 _decayRate; + }; + + AuraScript* GetAuraScript() const + { + return new spell_dreamwalker_decay_periodic_timer_AuraScript(); + } +}; + +class spell_dreamwalker_summoner : public SpellScriptLoader +{ + public: + spell_dreamwalker_summoner() : SpellScriptLoader("spell_dreamwalker_summoner") { } + + class spell_dreamwalker_summoner_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dreamwalker_summoner_SpellScript); + + void FilterTargets(std::list<Unit*>& targets) + { + targets.remove_if(SummonTargetSelector()); + if (targets.empty()) + return; + + std::list<Unit*>::iterator itr = targets.begin(); + std::advance(itr, urand(0, targets.size() - 1)); + Unit* target = *itr; + targets.clear(); + targets.push_back(target); + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_AREA_ENTRY_SRC); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dreamwalker_summoner_SpellScript(); + } +}; + +class spell_dreamwalker_summon_suppresser : public SpellScriptLoader +{ + public: + spell_dreamwalker_summon_suppresser() : SpellScriptLoader("spell_dreamwalker_summon_suppresser") { } + + class spell_dreamwalker_summon_suppresser_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dreamwalker_summon_suppresser_AuraScript); + + void PeriodicTick(AuraEffect const* aurEff) + { + PreventDefaultAction(); + Unit* caster = GetCaster(); + if (!caster) + return; + + std::list<Creature*> summoners; + GetCreatureListWithEntryInGrid(summoners, caster, 22515, 100.0f); + summoners.remove_if(SummonTargetSelector()); + Trinity::RandomResizeList(summoners, 2); + if (summoners.empty()) + return; + + for (uint32 i = 0; i < 3; ++i) + caster->CastSpell(summoners.front(), SPELL_SUMMON_SUPPRESSER, true); + for (uint32 i = 0; i < 3; ++i) + caster->CastSpell(summoners.back(), SPELL_SUMMON_SUPPRESSER, true); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_dreamwalker_summon_suppresser_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + + int32 _decayRate; + }; + + AuraScript* GetAuraScript() const + { + return new spell_dreamwalker_summon_suppresser_AuraScript(); + } +}; + +class spell_dreamwalker_summon_dream_portal : public SpellScriptLoader +{ + public: + spell_dreamwalker_summon_dream_portal() : SpellScriptLoader("spell_dreamwalker_summon_dream_portal") { } + + class spell_dreamwalker_summon_dream_portal_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dreamwalker_summon_dream_portal_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (!GetHitUnit()) + return; + + uint32 spellId = RAND<uint32>(71301, 72220, 72223, 72225); + GetHitUnit()->CastSpell(GetHitUnit(), spellId, true); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_dreamwalker_summon_dream_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dreamwalker_summon_dream_portal_SpellScript(); + } +}; + +class spell_dreamwalker_summon_nightmare_portal : public SpellScriptLoader +{ + public: + spell_dreamwalker_summon_nightmare_portal() : SpellScriptLoader("spell_dreamwalker_summon_nightmare_portal") { } + + class spell_dreamwalker_summon_nightmare_portal_SpellScript : public SpellScript + { + PrepareSpellScript(spell_dreamwalker_summon_nightmare_portal_SpellScript); + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + if (!GetHitUnit()) + return; + + uint32 spellId = RAND<uint32>(71977, 72481, 72482, 72483); + GetHitUnit()->CastSpell(GetHitUnit(), spellId, true); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_dreamwalker_summon_nightmare_portal_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_dreamwalker_summon_nightmare_portal_SpellScript(); + } +}; + +class spell_dreamwalker_nightmare_cloud : public SpellScriptLoader +{ + public: + spell_dreamwalker_nightmare_cloud() : SpellScriptLoader("spell_dreamwalker_nightmare_cloud") { } + + class spell_dreamwalker_nightmare_cloud_AuraScript : public AuraScript + { + PrepareAuraScript(spell_dreamwalker_nightmare_cloud_AuraScript); + + bool Load() + { + _instance = GetOwner()->GetInstanceScript(); + return _instance != NULL; + } + + void PeriodicTick(AuraEffect const* /*aurEff*/) + { + if (_instance->GetBossState(DATA_VALITHRIA_DREAMWALKER) != IN_PROGRESS) + PreventDefaultAction(); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_dreamwalker_nightmare_cloud_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + + InstanceScript* _instance; + }; + + AuraScript* GetAuraScript() const + { + return new spell_dreamwalker_nightmare_cloud_AuraScript(); + } +}; + +class achievement_portal_jockey : public AchievementCriteriaScript +{ + public: + achievement_portal_jockey() : AchievementCriteriaScript("achievement_portal_jockey") { } + + bool OnCheck(Player* /*source*/, Unit* target) + { + return target && !target->GetAI()->GetData(MISSED_PORTALS); + } +}; + +void AddSC_boss_valithria_dreamwalker() +{ + new boss_valithria_dreamwalker(); + new npc_green_dragon_combat_trigger(); + new npc_the_lich_king_controller(); + new npc_risen_archmage(); + new npc_blazing_skeleton(); + new npc_suppresser(); + new npc_blistering_zombie(); + new npc_gluttonous_abomination(); + new npc_dream_portal(); + new npc_dream_cloud(); + new spell_dreamwalker_mana_void(); + new spell_dreamwalker_decay_periodic_timer(); + new spell_dreamwalker_summoner(); + new spell_dreamwalker_summon_suppresser(); + new spell_dreamwalker_summon_dream_portal(); + new spell_dreamwalker_summon_nightmare_portal(); + new spell_dreamwalker_nightmare_cloud(); + new achievement_portal_jockey(); +} diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 137ac32df24..9453610a034 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -27,6 +27,8 @@ uint32 const EncounterCount = 13; uint32 const WeeklyNPCs = 9; uint32 const MaxHeroicAttempts = 50; + +extern Position const ValithriaSpawnPos; // Defined in boss_sindragosa.cpp extern Position const SindragosaSpawnPos; @@ -70,28 +72,30 @@ enum DataTypes DATA_THE_LICH_KING = 12, // Additional data - DATA_SAURFANG_EVENT_NPC = 34, - DATA_BONED_ACHIEVEMENT = 13, - DATA_OOZE_DANCE_ACHIEVEMENT = 14, - DATA_PUTRICIDE_TABLE = 15, - DATA_NAUSEA_ACHIEVEMENT = 16, - DATA_ORB_WHISPERER_ACHIEVEMENT = 17, - DATA_PRINCE_KELESETH_GUID = 18, - DATA_PRINCE_TALDARAM_GUID = 19, - DATA_PRINCE_VALANAR_GUID = 20, - DATA_BLOOD_PRINCES_CONTROL = 21, - DATA_SINDRAGOSA_FROSTWYRMS = 22, - DATA_SPINESTALKER = 23, - DATA_RIMEFANG = 24, - DATA_COLDFLAME_JETS = 25, - 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, + DATA_SAURFANG_EVENT_NPC = 13, + DATA_BONED_ACHIEVEMENT = 14, + DATA_OOZE_DANCE_ACHIEVEMENT = 15, + DATA_PUTRICIDE_TABLE = 16, + DATA_NAUSEA_ACHIEVEMENT = 17, + DATA_ORB_WHISPERER_ACHIEVEMENT = 18, + DATA_PRINCE_KELESETH_GUID = 19, + DATA_PRINCE_TALDARAM_GUID = 20, + DATA_PRINCE_VALANAR_GUID = 21, + DATA_BLOOD_PRINCES_CONTROL = 22, + DATA_SINDRAGOSA_FROSTWYRMS = 23, + DATA_SPINESTALKER = 24, + DATA_RIMEFANG = 25, + DATA_COLDFLAME_JETS = 26, + DATA_TEAM_IN_INSTANCE = 27, + DATA_BLOOD_QUICKENING_STATE = 28, + DATA_HEROIC_ATTEMPTS = 29, + DATA_CROK_SCOURGEBANE = 30, + DATA_CAPTAIN_ARNATH = 31, + DATA_CAPTAIN_BRANDON = 32, + DATA_CAPTAIN_GRONDEL = 33, + DATA_CAPTAIN_RUPERT = 34, + DATA_VALITHRIA_TRIGGER = 35, + DATA_VALITHRIA_LICH_KING = 36, }; enum CreaturesIds @@ -218,7 +222,13 @@ enum CreaturesIds NPC_SUPPRESSER = 37863, NPC_BLISTERING_ZOMBIE = 37934, NPC_GLUTTONOUS_ABOMINATION = 37886, + NPC_MANA_VOID = 38068, + NPC_COLUMN_OF_FROST = 37918, NPC_THE_LICH_KING_VALITHRIA = 16980, + NPC_DREAM_PORTAL_PRE_EFFECT = 38186, + NPC_NIGHTMARE_PORTAL_PRE_EFFECT = 38429, + NPC_DREAM_PORTAL = 37945, + NPC_NIGHTMARE_PORTAL = 38430, // Sindragosa NPC_SINDRAGOSA = 36853, @@ -275,6 +285,10 @@ enum GameObjectsIds // Valithria Dreamwalker GO_GREEN_DRAGON_BOSS_ENTRANCE = 201375, GO_GREEN_DRAGON_BOSS_EXIT = 201374, + GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01 = 201380, + GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02 = 201381, + GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03 = 201382, + GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04 = 201383, // Sindragosa GO_SINDRAGOSA_ENTRANCE_DOOR = 201373, diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index f537a70d61e..048def7a120 100755 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -25,28 +25,32 @@ DoorData const doorData[] = { - {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM, BOUNDARY_N }, - {GO_ICEWALL, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, - {GO_DOODAD_ICECROWN_ICEWALL02, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, - {GO_ORATORY_OF_THE_DAMNED_ENTRANCE, DATA_LADY_DEATHWHISPER, DOOR_TYPE_ROOM, BOUNDARY_N }, - {GO_SAURFANG_S_DOOR, DATA_DEATHBRINGER_SAURFANG, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, - {GO_ORANGE_PLAGUE_MONSTER_ENTRANCE, DATA_FESTERGUT, DOOR_TYPE_ROOM, BOUNDARY_E }, - {GO_GREEN_PLAGUE_MONSTER_ENTRANCE, DATA_ROTFACE, DOOR_TYPE_ROOM, BOUNDARY_E }, - {GO_SCIENTIST_ENTRANCE, DATA_PROFESSOR_PUTRICIDE, DOOR_TYPE_ROOM, BOUNDARY_E }, - {GO_CRIMSON_HALL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_ROOM, BOUNDARY_S }, - {GO_BLOOD_ELF_COUNCIL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_W }, - {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 }, - {GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_E }, - {GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, - {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SE }, - {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SW }, - {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} // END + {GO_LORD_MARROWGAR_S_ENTRANCE, DATA_LORD_MARROWGAR, DOOR_TYPE_ROOM, BOUNDARY_N }, + {GO_ICEWALL, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {GO_DOODAD_ICECROWN_ICEWALL02, DATA_LORD_MARROWGAR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {GO_ORATORY_OF_THE_DAMNED_ENTRANCE, DATA_LADY_DEATHWHISPER, DOOR_TYPE_ROOM, BOUNDARY_N }, + {GO_SAURFANG_S_DOOR, DATA_DEATHBRINGER_SAURFANG, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {GO_ORANGE_PLAGUE_MONSTER_ENTRANCE, DATA_FESTERGUT, DOOR_TYPE_ROOM, BOUNDARY_E }, + {GO_GREEN_PLAGUE_MONSTER_ENTRANCE, DATA_ROTFACE, DOOR_TYPE_ROOM, BOUNDARY_E }, + {GO_SCIENTIST_ENTRANCE, DATA_PROFESSOR_PUTRICIDE, DOOR_TYPE_ROOM, BOUNDARY_E }, + {GO_CRIMSON_HALL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_ROOM, BOUNDARY_S }, + {GO_BLOOD_ELF_COUNCIL_DOOR, DATA_BLOOD_PRINCE_COUNCIL, DOOR_TYPE_PASSAGE, BOUNDARY_W }, + {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_DOODAD_ICECROWN_ROOSTPORTCULLIS_01, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_N }, + {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_S }, + {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_N }, + {GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04, DATA_VALITHRIA_DREAMWALKER, DOOR_TYPE_SPAWN_HOLE, BOUNDARY_S }, + {GO_SINDRAGOSA_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_S }, + {GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_E }, + {GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR, DATA_SINDRAGOSA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE}, + {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SE }, + {GO_ICE_WALL, DATA_SINDRAGOSA, DOOR_TYPE_ROOM, BOUNDARY_SW }, + {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE},// END }; // this doesnt have to only store questgivers, also can be used for related quest spawns @@ -105,6 +109,9 @@ class instance_icecrown_citadel : public InstanceMapScript CrokScourgebaneGUID = 0; memset(CrokCaptainGUIDs, 0, 4 * sizeof(uint64)); SisterSvalnaGUID = 0; + ValithriaDreamwalkerGUID = 0; + ValithriaLichKingGUID = 0; + ValithriaTriggerGUID = 0; SindragosaGUID = 0; SpinestalkerGUID = 0; RimefangGUID = 0; @@ -238,6 +245,15 @@ class instance_icecrown_citadel : public InstanceMapScript case NPC_SISTER_SVALNA: SisterSvalnaGUID = creature->GetGUID(); break; + case NPC_VALITHRIA_DREAMWALKER: + ValithriaDreamwalkerGUID = creature->GetGUID(); + break; + case NPC_THE_LICH_KING_VALITHRIA: + ValithriaLichKingGUID = creature->GetGUID(); + break; + case NPC_GREEN_DRAGON_COMBAT_TRIGGER: + ValithriaTriggerGUID = creature->GetGUID(); + break; case NPC_SINDRAGOSA: SindragosaGUID = creature->GetGUID(); break; @@ -330,12 +346,20 @@ class instance_icecrown_citadel : public InstanceMapScript case GO_DOODAD_ICECROWN_GRATE_01: case GO_GREEN_DRAGON_BOSS_ENTRANCE: case GO_GREEN_DRAGON_BOSS_EXIT: + case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02: + case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03: case GO_SINDRAGOSA_ENTRANCE_DOOR: case GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR: case GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR: case GO_ICE_WALL: AddDoor(go, true); break; + // these 2 gates are functional only on 25man modes + case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01: + case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04: + if (instance->GetSpawnMode() & 1) + AddDoor(go, true); + break; case GO_LADY_DEATHWHISPER_ELEVATOR: LadyDeathwisperElevatorGUID = go->GetGUID(); if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE) @@ -428,6 +452,10 @@ class instance_icecrown_citadel : public InstanceMapScript case GO_DOODAD_ICECROWN_GRATE_01: case GO_GREEN_DRAGON_BOSS_ENTRANCE: case GO_GREEN_DRAGON_BOSS_EXIT: + case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_01: + case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_02: + case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_03: + case GO_DOODAD_ICECROWN_ROOSTPORTCULLIS_04: case GO_SINDRAGOSA_ENTRANCE_DOOR: case GO_SINDRAGOSA_SHORTCUT_ENTRANCE_DOOR: case GO_SINDRAGOSA_SHORTCUT_EXIT_DOOR: @@ -494,21 +522,27 @@ class instance_icecrown_citadel : public InstanceMapScript return BloodCouncilControllerGUID; case DATA_BLOOD_QUEEN_LANA_THEL: return BloodQueenLanaThelGUID; - case DATA_SINDRAGOSA: - return SindragosaGUID; - case DATA_SPINESTALKER: - 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]; + return CrokCaptainGUIDs[type - DATA_CAPTAIN_ARNATH]; case DATA_SISTER_SVALNA: return SisterSvalnaGUID; + case DATA_VALITHRIA_DREAMWALKER: + return ValithriaDreamwalkerGUID; + case DATA_VALITHRIA_LICH_KING: + return ValithriaLichKingGUID; + case DATA_VALITHRIA_TRIGGER: + return ValithriaTriggerGUID; + case DATA_SINDRAGOSA: + return SindragosaGUID; + case DATA_SPINESTALKER: + return SpinestalkerGUID; + case DATA_RIMEFANG: + return RimefangGUID; default: break; } @@ -611,6 +645,8 @@ class instance_icecrown_citadel : public InstanceMapScript } break; case DATA_VALITHRIA_DREAMWALKER: + if (state == DONE && sPoolMgr->IsSpawnedObject<Quest>(WeeklyQuestData[8].questId[instance->GetSpawnMode() & 1])) + instance->SummonCreature(NPC_VALITHRIA_DREAMWALKER_QUEST, ValithriaSpawnPos); break; case DATA_SINDRAGOSA: HandleGameObject(FrostwingSigilGUID, state != DONE); @@ -959,8 +995,8 @@ class instance_icecrown_citadel : public InstanceMapScript OUT_SAVE_INST_DATA; std::ostringstream saveStream; - saveStream << "I C " << GetBossSaveData() << ColdflameJetsState - << " " << BloodQuickeningState << " " << BloodQuickeningMinutes; + saveStream << "I C " << GetBossSaveData() << HeroicAttempts << " " + << ColdflameJetsState << " " << BloodQuickeningState << " " << BloodQuickeningMinutes; OUT_SAVE_INST_DATA_COMPLETE; return saveStream.str(); @@ -992,10 +1028,12 @@ class instance_icecrown_citadel : public InstanceMapScript SetBossState(i, EncounterState(tmpState)); } + loadStream >> HeroicAttempts; + uint32 temp = 0; loadStream >> temp; ColdflameJetsState = temp ? DONE : NOT_STARTED; - temp = 0; + loadStream >> temp; BloodQuickeningState = temp ? DONE : NOT_STARTED; // DONE means finished (not success/fail) loadStream >> BloodQuickeningMinutes; @@ -1057,6 +1095,9 @@ class instance_icecrown_citadel : public InstanceMapScript uint64 CrokScourgebaneGUID; uint64 CrokCaptainGUIDs[4]; uint64 SisterSvalnaGUID; + uint64 ValithriaDreamwalkerGUID; + uint64 ValithriaLichKingGUID; + uint64 ValithriaTriggerGUID; uint64 SindragosaGUID; uint64 SpinestalkerGUID; uint64 RimefangGUID; @@ -1067,7 +1108,7 @@ class instance_icecrown_citadel : public InstanceMapScript uint32 SpinestalkerTrashCount; uint32 RimefangTrashCount; uint32 BloodQuickeningState; - uint16 HeroicAttempts; + uint32 HeroicAttempts; uint16 BloodQuickeningMinutes; bool IsBonedEligible; bool IsOozeDanceEligible; |