diff options
author | Shauren <shauren.trinity@gmail.com> | 2014-03-23 02:01:13 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2014-03-23 02:01:13 +0100 |
commit | a4d8a26dc7eb8139190eae1e285dc629da50b950 (patch) | |
tree | d6be53f9c2976692bc5c0ee49ee1fa6156235697 | |
parent | d2925597f2ffdf88770a60c51734863caee0131f (diff) |
Scripts/Icecrown Citadel: Icecrown Gunship Battle
13 files changed, 3162 insertions, 78 deletions
diff --git a/sql/updates/world/2014_03_23_00_world_misc.sql b/sql/updates/world/2014_03_23_00_world_misc.sql new file mode 100644 index 00000000000..b57f6e09bb9 --- /dev/null +++ b/sql/updates/world/2014_03_23_00_world_misc.sql @@ -0,0 +1,397 @@ +UPDATE `creature_template` SET `ScriptName`='npc_gunship' WHERE `entry`=37215; -- Orgrim's Hammer +UPDATE `creature_template` SET `ScriptName`='npc_gunship' WHERE `entry`=37540; -- The Skybreaker +UPDATE `creature_template` SET `ScriptName`='npc_high_overlord_saurfang_igb' WHERE `entry`=36939; -- High Overlord Saurfang +UPDATE `creature_template` SET `ScriptName`='npc_muradin_bronzebeard_igb' WHERE `entry`=36948; -- Muradin Bronzebeard +UPDATE `creature_template` SET `ScriptName`='npc_zafod_boombox' WHERE `entry`=37184; -- Zafod Boombox +UPDATE `creature_template` SET `ScriptName`='npc_gunship_boarding_leader' WHERE `entry` IN (36961,36960); -- Skybreaker Sergeant, Kor'kron Sergeant +UPDATE `creature_template` SET `ScriptName`='npc_gunship_boarding_add' WHERE `entry` IN (36950,36957); -- Skybreaker Marine, Kor'kron Reaver +UPDATE `creature_template` SET `ScriptName`='npc_gunship_gunner' WHERE `entry` IN (36969,36968); -- Skybreaker Rifleman, Kor'kron Axethrower +UPDATE `creature_template` SET `ScriptName`='npc_gunship_rocketeer' WHERE `entry` IN (36978,36982); -- Skybreaker Mortar Soldier, Kor'kron Rocketeer +UPDATE `creature_template` SET `ScriptName`='npc_gunship_mage' WHERE `entry` IN (37116,37117); -- Skybreaker Sorcerer, Kor'kron Battle-Mage +UPDATE `creature_template` SET `ScriptName`='npc_gunship_cannon' WHERE `entry` IN (36838,36839); -- Alliance Gunship Cannon, Horde Gunship Cannon + +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_jokkum_eject_all'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_the_lich_king_eject_all_passengers'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_gen_eject_all_passengers'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_rocket_pack'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_rocket_pack_useable'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_on_gunship_deck'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_periodic_trigger_with_power_cost'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_cannon_blast'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_incinerating_blast'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_overheat'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_below_zero'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_teleport_to_enemy_ship'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_burning_pitch_selector'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_burning_pitch'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_rocket_artillery'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_rocket_artillery_explosion'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_gunship_fall_teleport'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_check_for_players'; +DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_igb_teleport_players_on_victory'; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(50630,'spell_gen_eject_all_passengers'), +(63109,'spell_gen_eject_all_passengers'), +(68576,'spell_gen_eject_all_passengers'), +(68721,'spell_igb_rocket_pack'), +(70348,'spell_igb_rocket_pack_useable'), +(70120,'spell_igb_on_gunship_deck'), +(70121,'spell_igb_on_gunship_deck'), +(69470,'spell_igb_periodic_trigger_with_power_cost'), +(69487,'spell_igb_periodic_trigger_with_power_cost'), +(69399,'spell_igb_cannon_blast'), +(70172,'spell_igb_cannon_blast'), +(69402,'spell_igb_incinerating_blast'), +(70175,'spell_igb_incinerating_blast'), +(69487,'spell_igb_overheat'), +(69705,'spell_igb_below_zero'), +(70104,'spell_igb_teleport_to_enemy_ship'), +(70397,'spell_igb_burning_pitch_selector'), +(70403,'spell_igb_burning_pitch_selector'), +(71335,'spell_igb_burning_pitch'), +(71339,'spell_igb_burning_pitch'), +(69678,'spell_igb_rocket_artillery'), +(70609,'spell_igb_rocket_artillery'), +(69679,'spell_igb_rocket_artillery_explosion'), +(67335,'spell_igb_gunship_fall_teleport'), +(70331,'spell_igb_check_for_players'), +(72340,'spell_igb_teleport_players_on_victory'); + +UPDATE `creature_template` SET `difficulty_entry_1`=0,`difficulty_entry_2`=0,`difficulty_entry_3`=0 WHERE `entry`=36838; -- Alliance Gunship Cannon +UPDATE `creature_template` SET `difficulty_entry_1`=0,`difficulty_entry_2`=0,`difficulty_entry_3`=0 WHERE `entry`=36839; -- Horde Gunship Cannon +UPDATE `creature_template` SET `difficulty_entry_1`=0,`difficulty_entry_2`=0,`difficulty_entry_3`=0 WHERE `entry`=36970; -- Skybreaker Deckhand +UPDATE `creature_template` SET `difficulty_entry_1`=0,`difficulty_entry_2`=0,`difficulty_entry_3`=0 WHERE `entry`=36971; -- Orgrim's Hammer Crew +UPDATE `creature_template` SET `difficulty_entry_1`=38157,`difficulty_entry_2`=38639,`difficulty_entry_3`=38640 WHERE `entry`=36948; -- Muradin Bronzebeard +UPDATE `creature_template` SET `difficulty_entry_1`=38156,`difficulty_entry_2`=38637,`difficulty_entry_3`=38638 WHERE `entry`=36939; -- High Overlord Saurfang +UPDATE `creature_template` SET `difficulty_entry_1`=38128,`difficulty_entry_2`=38699,`difficulty_entry_3`=38700 WHERE `entry`=37540; -- The Skybreaker +UPDATE `creature_template` SET `difficulty_entry_1`=38129,`difficulty_entry_2`=38701,`difficulty_entry_3`=38702 WHERE `entry`=37215; -- Orgrim's Hammer +UPDATE `creature_template` SET `difficulty_entry_1`=38256,`difficulty_entry_2`=38693,`difficulty_entry_3`=38694 WHERE `entry`=37116; -- Skybreaker Sorcerer +UPDATE `creature_template` SET `difficulty_entry_1`=38408,`difficulty_entry_2`=38689,`difficulty_entry_3`=38690 WHERE `entry`=36969; -- Skybreaker Rifleman +UPDATE `creature_template` SET `difficulty_entry_1`=38407,`difficulty_entry_2`=38687,`difficulty_entry_3`=38688 WHERE `entry`=36978; -- Skybreaker Mortar Soldier +UPDATE `creature_template` SET `difficulty_entry_1`=38406,`difficulty_entry_2`=38685,`difficulty_entry_3`=38686 WHERE `entry`=36950; -- Skybreaker Marine +UPDATE `creature_template` SET `difficulty_entry_1`=38261,`difficulty_entry_2`=38691,`difficulty_entry_3`=38692 WHERE `entry`=36961; -- Skybreaker Sergeant +UPDATE `creature_template` SET `difficulty_entry_1`=38257,`difficulty_entry_2`=38677,`difficulty_entry_3`=38678 WHERE `entry`=37117; -- Kor'kron Battle-Mage +UPDATE `creature_template` SET `difficulty_entry_1`=38403,`difficulty_entry_2`=38675,`difficulty_entry_3`=38676 WHERE `entry`=36968; -- Kor'kron Axethrower +UPDATE `creature_template` SET `difficulty_entry_1`=38405,`difficulty_entry_2`=38681,`difficulty_entry_3`=38682 WHERE `entry`=36982; -- Kor'kron Rocketeer +UPDATE `creature_template` SET `difficulty_entry_1`=38404,`difficulty_entry_2`=38679,`difficulty_entry_3`=38680 WHERE `entry`=36957; -- Kor'kron Reaver +UPDATE `creature_template` SET `difficulty_entry_1`=38262,`difficulty_entry_2`=38683,`difficulty_entry_3`=38684 WHERE `entry`=36960; -- Kor'kron Sergeant + +UPDATE `creature_template` SET `spell1`=0,`spell2`=0,`spell3`=0,`spell4`=0,`spell5`=0,`spell6`=0,`spell7`=0,`spell8`=0 WHERE `entry` IN (36838,36839,36970,36971,36948,38157,38639,38640,36939,38156,38638,38637,37540,38128,38699,38700,37215,38129,38701,38702, +37116,38256,38693,38694,36969,38408,38689,38690,36978,38407,38687,38688,36950,38406,38685,38686,36961,38261,38691,38692,37117,38257,38677,38678,36968,38403,38675,38676,36982,38405,38681,38682,36957,38404,38679,38680,36960,38262,38683,38684,37227,37488); + +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=0,`faction_A`=1665,`faction_H`=1665,`npcflag`=0x1000000,`speed_walk`=1,`speed_run`=1,`unit_class`=4,`unit_flags`=0x4000,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`spell1`=69399,`spell2`=70174,`VehicleId`=554,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry`=36838; -- Alliance Gunship Cannon +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=0,`faction_A`=1665,`faction_H`=1665,`npcflag`=0x1000000,`speed_walk`=1,`speed_run`=1,`unit_class`=4,`unit_flags`=0x4000,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`spell1`=70172,`spell2`=69401,`VehicleId`=555,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry`=36839; -- Horde Gunship Cannon +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=0,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.14286,`unit_flags`=0x300,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry`=36970; -- Skybreaker Deckhand +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=0,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.14286,`unit_flags`=0x300,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry`=36971; -- Orgrim's Hammer Crew +UPDATE `creature_template` SET `gossip_menu_id`=10875,`minlevel`=83,`maxlevel`=83,`exp`=2,`faction_A`=84,`faction_H`=84,`npcflag`=0x1,`speed_walk`=1,`speed_run`=1.71429,`unit_flags`=0x8000,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=1500,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36948,38157,38639,38640); -- Muradin Bronzebeard +UPDATE `creature_template` SET `gossip_menu_id`=10954,`minlevel`=83,`maxlevel`=83,`exp`=2,`faction_A`=83,`faction_H`=83,`npcflag`=0x1,`speed_walk`=1,`speed_run`=1.71429,`unit_flags`=0x8000,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=1500,`InhabitType`=1,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36939,38156,38638,38637); -- High Overlord Saurfang +UPDATE `creature_template` SET `minlevel`=83,`maxlevel`=83,`exp`=2,`faction_A`=35,`faction_H`=35,`speed_walk`=1,`speed_run`=1.42857,`unit_flags`=0,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=4,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (37540,38128,38699,38700); -- The Skybreaker +UPDATE `creature_template` SET `minlevel`=83,`maxlevel`=83,`exp`=2,`faction_A`=35,`faction_H`=35,`speed_walk`=1,`speed_run`=1.42857,`unit_flags`=0,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=4,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (37215,38129,38701,38702); -- Orgrim's Hammer +UPDATE `creature_template` SET `minlevel`=81,`maxlevel`=81,`exp`=0,`faction_A`=35,`faction_H`=35,`npcflag`=0x1000000,`speed_walk`=1,`speed_run`=1,`unit_class`=1,`unit_flags`=0,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry`=37227; -- Teleport Portal +UPDATE `creature_template` SET `minlevel`=81,`maxlevel`=81,`exp`=0,`faction_A`=35,`faction_H`=35,`npcflag`=0,`speed_walk`=1,`speed_run`=1,`unit_class`=1,`unit_flags`=0x2000000,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry`=37488; -- Teleport Exit +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.71429,`unit_class`=2,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (37116,38256,38693,38694); -- Skybreaker Sorcerer +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36969,38408,38689,38690); -- Skybreaker Rifleman +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36978,38407,38687,38688); -- Skybreaker Mortar Soldier +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36950,38406,38685,38686); -- Skybreaker Marine +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36961,38261,38691,38692); -- Skybreaker Sergeant +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=2,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (37117,38257,38677,38678); -- Kor'kron Battle-Mage +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36968,38403,38675,38676); -- Kor'kron Axethrower +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36982,38405,38681,38682); -- Kor'kron Rocketeer +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36957,38404,38679,38680); -- Kor'kron Reaver +UPDATE `creature_template` SET `minlevel`=82,`maxlevel`=82,`exp`=2,`faction_A`=83,`faction_H`=83,`speed_walk`=1,`speed_run`=1.42857,`unit_class`=1,`unit_flags`=0x8040,`unit_flags2`=0x800,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry` IN (36960,38262,38683,38684); -- Kor'kron Sergeant +UPDATE `creature_template` SET `npcflag`=1,`gossip_menu_id`=10885,`mechanic_immune_mask`=650854267 WHERE `entry`=37184; -- Zafod Boombox +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.14286,`unit_class`=1,`unit_flags`=0x300,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry`=37182; -- High Captain Justin Bartlett +UPDATE `creature_template` SET `minlevel`=80,`maxlevel`=80,`exp`=2,`faction_A`=84,`faction_H`=84,`speed_walk`=1,`speed_run`=1.14286,`unit_class`=1,`unit_flags`=0x300,`unit_flags2`=0,`dynamicflags`=0,`baseattacktime`=2000,`InhabitType`=1,`flags_extra`=0,`mechanic_immune_mask`=650854267 WHERE `entry`=37833; -- Sky-Reaver Korm Blackscar + +UPDATE `gameobject_template` SET `faction`=94,`flags`=16 WHERE `entry` IN (202178,202180,202177,202179); -- Gunship Armory +UPDATE `gameobject_template` SET `faction`=94,`flags`=16 WHERE `entry` IN (201873,201874,201872,201875); -- Gunship Armory + +DELETE FROM `creature_text` WHERE `entry`=36939 AND `groupid` BETWEEN 0 AND 13; +DELETE FROM `creature_text` WHERE `entry`=36948 AND `groupid` BETWEEN 0 AND 14; +DELETE FROM `creature_text` WHERE `entry` IN (37184,36838,36839); +INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`language`,`probability`,`emote`,`duration`,`sound`,`comment`) VALUES +(36939, 0,0,'Rise up, sons and daughters of the Horde! Today we battle a hated enemy of the Horde! LOK''TAR OGAR!',14,0,100,0,0,17087,'High Overlord Saurfang - SAY_SAURFANG_INTRO_1'), +(36939, 1,0,'Kor''kron, take us out!',14,0,100,0,0,17088,'High Overlord Saurfang - SAY_SAURFANG_INTRO_2'), +(36939, 2,0,'What is that? Something approaching in the distance.',14,0,100,0,0,17089,'High Overlord Saurfang - SAY_SAURFANG_INTRO_3'), +(36939, 3,0,'ALLIANCE GUNSHIP! ALL HANDS ON DECK!',14,0,100,0,0,17090,'High Overlord Saurfang - SAY_SAURFANG_INTRO_4'), +(36939, 4,0,'You answer to Saurfang now!',14,0,100,0,0,17091,'High Overlord Saurfang - SAY_SAURFANG_INTRO_5'), +(36939, 5,0,'You will know our business soon. Kor''kron, ANNIHILATE THEM!',14,0,100,0,0,17092,'High Overlord Saurfang - SAY_SAURFANG_INTRO_6'), +(36939, 6,0,'This is not your battle, dwarf. Back down or we will be forced to destroy your ship.',14,0,100,0,0,17083,'High Overlord Saurfang - SAY_SAURFANG_INTRO_A'), +(36939, 7,0,'You DARE board my ship? Your death will come swiftly.',14,0,100,0,0,17083,'High Overlord Saurfang - SAY_SAURFANG_BOARD'), +(36939, 8,0,'Reavers, Sergeants, attack!',14,0,100,0,0,17081,'High Overlord Saurfang - SAY_SAURFANG_ENTER_SKYBREAKER'), +(36939, 9,0,'Axethrowers, hurl faster!',14,0,100,0,0,17079,'High Overlord Saurfang - SAY_SAURFANG_AXETHROWERS'), +(36939,10,0,'Rocketeers, reload!',14,0,100,0,0,17080,'High Overlord Saurfang - SAY_SAURFANG_ROCKETEERS'), +(36939,11,0,'We''re taking hull damage, get a battle-mage out here to shut down those cannons!',14,0,100,0,0,17082,'High Overlord Saurfang - SAY_SAURFANG_MAGES'), +(36939,12,0,'The Alliance falter. Onward to the Lich King!',14,0,100,0,0,17084,'High Overlord Saurfang - SAY_SAURFANG_VICTORY'), +(36939,13,0,'Damage control! Put those fires out. You haven''t seen the last of the Horde!',14,0,100,0,0,17085,'High Overlord Saurfang - SAY_SAURFANG_WIPE'), +(36948, 0,0,'Fire up the engines! We got a meetin'' with destiny, lads!',14,0,100,0,0,16962,'Muradin Bronzebeard - SAY_MURADIN_INTRO_1'), +(36948, 1,0,'Hold on to yer hats!',14,0,100,0,0,16963,'Muradin Bronzebeard - SAY_MURADIN_INTRO_2'), +(36948, 2,0,'What in the world is that? Grab me spyglass, crewman!',14,0,100,0,0,16964,'Muradin Bronzebeard - SAY_MURADIN_INTRO_3'), +(36948, 3,0,'By me own beard! HORDE SAILIN'' IN FAST ''N HOT!',14,0,100,0,0,16965,'Muradin Bronzebeard - SAY_MURADIN_INTRO_4'), +(36948, 4,0,'EVASIVE ACTION! MAN THE GUNS!',14,0,100,0,0,16966,'Muradin Bronzebeard - SAY_MURADIN_INTRO_5'), +(36948, 5,0,'Cowardly dogs! Ye blindsided us!',14,0,100,0,0,16967,'Muradin Bronzebeard - SAY_MURADIN_INTRO_6'), +(36948, 6,0,'Not me battle? I dunnae who ye think ye are, mister, but I got a score to settle with Arthas and yer not gettin'' in me way! FIRE ALL GUNS! FIRE! FIRE!',14,0,100,0,0,16968,'Muradin Bronzebeard - SAY_MURADIN_INTRO_7'), +(36948, 7,0,'Move yer jalopy or we''ll blow it out of the sky, orc! The Horde''s got no business here.',14,0,100,0,0,16969,'Muradin Bronzebeard - SAY_MURADIN_INTRO_H'), +(36948, 8,0,'What''s this then?! Ye won''t be takin'' this son o'' Ironforge''s vessel without a fight!',14,0,100,0,0,16958,'Muradin Bronzebeard - SAY_MURADIN_BOARD'), +(36948, 9,0,'Marines, Sergeants, attack!',14,0,100,0,0,16956,'Muradin Bronzebeard - SAY_MURADIN_ENTER_ORGRIMMS_HAMMER'), +(36948,10,0,'Riflemen, shoot faster!',14,0,100,0,0,16954,'Muradin Bronzebeard - SAY_MURADIN_RIFLEMAN'), +(36948,11,0,'Mortar team, reload!',14,0,100,0,0,16955,'Muradin Bronzebeard - SAY_MURADIN_MORTAR'), +(36948,12,0,'We''re taking hull damage, get a sorcerer out here to shut down those cannons!',14,0,100,0,0,16957,'Muradin Bronzebeard - SAY_MURADIN_SORCERERS'), +(36948,13,0,'Don''t say I didn''t warn ya, scoundrels! Onward, brothers and sisters!',14,0,100,0,0,16959,'Muradin Bronzebeard - SAY_MURADIN_VICTORY'), +(36948,14,0,'Captain Bartlett, get us out of here! We''re taken too much damage to stay afloat!',14,0,100,0,0,16960,'Muradin Bronzebeard - SAY_MURADIN_WIPE'), +(37184,0,0,'Rocket Pack Active!',15,0,100,0,0,0,'Zafod Boombox - SAY_ZAFOD_ROCKET_PACK_ACTIVE'), +(37184,1,0,'Rocket Pack Disabled. Move closer to Zafod Boombox to re-activate.',15,0,100,0,0,0,'Zafod Boombox - SAY_ZAFOD_ROCKET_PACK_DISABLED'), +(36838,0,0,'|TInterface\\Icons\\Spell_Fire_Flameshock.blp:20|t|cFFBC0000 OVERHEAT |r|TInterface\\Icons\\Spell_Fire_Flameshock.blp:20|t',42,0,100,0,0,0,'Alliance Gunship Cannon - SAY_OVERHEAT'), +(36839,0,0,'|TInterface\\Icons\\Spell_Fire_Flameshock.blp:20|t|cFFBC0000 OVERHEAT |r|TInterface\\Icons\\Spell_Fire_Flameshock.blp:20|t',42,0,100,0,0,0,'Horde Gunship Cannon - SAY_OVERHEAT'); + +DELETE FROM `gossip_menu` WHERE `entry` IN (10875,10954,10885); +INSERT INTO `gossip_menu` (`entry`,`text_id`) VALUES +(10875,15101), +(10954,15219), +(10885,15134), +(10885,15123); + +DELETE FROM `gossip_menu_option` WHERE `menu_id` IN (10875,10885,10954); +INSERT INTO `gossip_menu_option` (`menu_id`,`id`,`option_icon`,`option_text`,`option_id`,`npc_option_npcflag`,`action_menu_id`,`action_poi_id`,`box_coded`,`box_money`,`box_text`) VALUES +(10875,0,0,'My companions are all accounted for, Muradin. Let''s go!',1,1,0,0,0,0,''), +(10954,0,0,'My companions are all accounted for, Saurfang. Let''s go!',1,1,0,0,0,0,''), +(10885,0,0,'Yeah, I''m sure safety is your top priority. Give me a rocket pack.',1,1,0,0,0,0,''); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=10885; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=14 AND `SourceGroup`=10885; +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry` IN (72347,70104,70173,69400,69402,70175,69705,70403,70397,70383,70374,70444,67335); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`Comment`) VALUES +(15,10885,0,0,2,49278,1,0,1,'Gossip Option - Show Option if player does not have item 49278'), +(14,10885,15134,0,2,49278,1,0,1,'Gossip Option - Show text 15134 if player does not have item 49278'), +(14,10885,15123,0,2,49278,1,0,0,'Gossip Option - Show text 15123 if player has item 49278'), +(13,1,72347,0,31,3,38569,0,0,'Lock Players and Tap Chest - target Martyr Stalker (IGB/Saurfang)'), +(13,1,70104,0,31,3,37488,0,0,'Teleport to Enemy Ship - target Teleport Exit'), +(13,2,70173,0,31,3,37540,0,0,'Cannon Blast - target The Skybreaker'), +(13,2,69400,0,31,3,37215,0,0,'Cannon Blast - target Orgrim''s Hammer'), +(13,2,69402,0,31,3,37540,0,0,'Incinerating Blast - target The Skybreaker'), +(13,2,70175,0,31,3,37215,0,0,'Incinerating Blast - target Orgrim''s Hammer'), +(13,1,69705,0,31,3,36839,0,0,'Below Zero - target Horde Gunship Cannon'), +(13,1,69705,1,31,3,36838,0,0,'Below Zero - target Alliance Gunship Cannon'), +(13,1,70403,0,31,3,37547,0,0,'Burning Pitch - target Gunship Hull'), +(13,1,70397,0,31,3,37547,0,0,'Burning Pitch - target Gunship Hull'), +(13,1,70383,0,31,3,37215,0,0,'Burning Pitch - target Orgrim''s Hammer'), +(13,1,70374,0,31,3,37540,0,0,'Burning Pitch - target The Skybreaker'), +(13,1,70444,0,31,3,37116,0,0,'Explosion - target Skybreaker Sorcerer'), +(13,1,70444,1,31,3,36969,0,0,'Explosion - target Skybreaker Rifleman'), +(13,1,70444,2,31,3,36978,0,0,'Explosion - target Skybreaker Mortar Soldier'), +(13,1,70444,3,31,3,37117,0,0,'Explosion - target Kor''kron Battle-Mage'), +(13,1,70444,4,31,3,36968,0,0,'Explosion - target Kor''kron Axethrower'), +(13,1,70444,5,31,3,36982,0,0,'Explosion - target Kor''kron Rocketeer'), +(13,1,67335,0,31,3,37540,0,0,'Gunship Fall Teleport - target The Skybreaker'), +(13,1,67335,1,31,3,37215,0,0,'Gunship Fall Teleport - target Orgrim''s Hammer'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceEntry`=68645; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`Comment`) VALUES +(17,0,68645,0,1,70348,0,0,0,173,'Rocket Pack - require Rocket Pack Useable'); + + +DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` IN (37227,36838,36839); +INSERT INTO `npc_spellclick_spells` (`npc_entry`,`spell_id`,`cast_flags`,`user_type`) VALUES +(37227,70104,3,0), +(36838,70510,1,0), +(36839,70510,1,0); + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (68645,73077); +INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES +(68645,68721,1,'Rocket Pack - additional aura'), +(73077,69188,2,'Rocket Pack - linked aura'); + +DELETE FROM `creature_template_addon` WHERE `entry` IN (36838,36839,37184,37488); +INSERT INTO `creature_template_addon` (`entry`,`mount`,`bytes1`,`bytes2`,`auras`) VALUES +(36838,0,0x0,0x1,'69470'), -- Alliance Gunship Cannon - Heat Drain +(36839,0,0x0,0x1,'69470'), -- Horde Gunship Cannon - Heat Drain +(37184,0,0x0,0x1,'69188 70348'), -- Zafod Boombox - Rocket Pack, Rocket Pack Useable +(37488,0,0x2000000,0x1,''); -- Teleport Exit + +DELETE FROM `creature` WHERE `guid` IN (201047,201030); +SET @CGUID := 133934; +DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID AND @CGUID+58; +INSERT INTO `creature` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`modelid`,`equipment_id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`,`spawndist`,`currentwaypoint`,`curhealth`,`curmana`,`MovementType`,`npcflag`,`unit_flags`,`dynamicflags`) VALUES +(@CGUID+0,37540,672,15,1,31043,0,-13.1429,-0.36969,12.8909,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+1,37547,672,15,1,0,0,-50.1652,9.71624,23.5871,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+2,37547,672,15,1,0,0,-34.2702,-26.1897,21.3748,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+3,37547,672,15,1,0,0,-41.4456,-7.6475,20.4975,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+4,37519,672,15,1,0,0,-28.275,15.5946,20.5379,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+5,37547,672,15,1,0,0,-11.6446,-19.8518,20.8843,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+6,37547,672,15,1,0,0,-19.8822,-6.57876,20.5744,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+7,36948,672,15,1,0,0,1.34481,-0.077413,20.8492,3.15905,604800,0,0,1,0,0,0,0,0), +(@CGUID+8,32780,672,15,1,0,0,1.29247,-0.006242,20.8767,3.12414,604800,0,0,1,0,0,0,0,0), +(@CGUID+9,37547,672,15,1,0,0,0.554884,-1.2329,20.5371,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+10,37547,672,15,1,0,0,19.7229,-2.19379,33.0698,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+11,37547,672,15,1,0,0,8.5994,-28.5585,24.7992,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+12,37547,672,15,1,0,0,11.4584,16.3662,20.5419,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+13,37547,672,15,1,0,0,38.9434,-33.808,25.3962,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+14,37519,672,15,1,0,0,39.4475,0.136515,25.2321,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+15,37547,673,15,1,0,0,53.1563,29.0877,44.7302,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+16,37547,673,15,1,0,0,-58.1547,0.748094,41.8766,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+17,37547,673,15,1,0,0,-39.4953,16.6872,34.3943,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+18,37547,673,15,1,0,0,-27.097,27.9929,34.3631,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+19,37547,673,15,1,0,0,-15.0316,12.0216,33.8629,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+20,37547,673,15,1,0,0,9.46182,16.1523,35.1091,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+21,37547,673,15,1,0,0,27.6276,27.103,36.8003,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+22,36939,673,15,1,0,0,36.4055,0.184604,36.7153,3.10669,604800,0,0,1,0,0,0,0,0), +(@CGUID+23,37184,673,15,1,0,0,38.5985,18.0196,36.6939,3.94444,604800,0,0,1,0,0,0,0,0), +(@CGUID+24,37833,673,15,1,0,0,60.4547,0.021568,38.7034,3.12414,604800,0,0,1,0,0,0,0,0), +(@CGUID+25,37547,673,15,1,0,0,4.7803,-29.0523,35.0963,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+26,37547,673,15,1,0,0,23.4778,-7.53715,35.8162,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+27,37547,673,15,1,0,0,-5.60755,-6.35065,34.0036,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+28,37519,673,15,1,0,0,-19.9011,-11.1976,33.4849,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+29,37519,673,15,1,0,0,22.1763,-11.4125,34.9973,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+30,36971,673,15,1,0,0,-56.4357,12.2929,34.6332,2.51327,604800,0,0,1,0,0,0,0,0), +(@CGUID+31,36971,673,15,1,0,0,30.8803,22.7656,36.3547,1.69297,604800,0,0,1,0,0,0,0,0), +(@CGUID+32,36971,673,15,1,0,0,-26.8348,13.4803,34.6954,5.3058,604800,0,0,1,0,0,0,0,0), +(@CGUID+33,36971,673,15,1,0,0,-29.3313,-23.2348,33.9633,2.80988,604800,0,0,1,0,0,0,0,0), +(@CGUID+34,36971,673,15,1,0,0,-26.1657,-13.3904,34.679,0.890118,604800,0,0,1,0,0,0,0,0), +(@CGUID+35,36971,673,15,1,0,0,60.0911,-6.35005,38.9569,2.54818,604800,0,0,1,0,0,0,0,0), +(@CGUID+36,36971,673,15,1,0,0,59.6708,6.21392,39.0067,3.735,604800,0,0,1,0,0,0,0,0), +(@CGUID+37,36971,673,15,1,0,0,30.9602,-22.9078,36.363,4.46804,604800,0,0,1,0,0,0,0,0), +(@CGUID+38,36839,673,15,1,0,0,-15.6908,31.1423,34.391,1.5708,604800,0,0,1,0,0,0,0,0), +(@CGUID+39,37215,673,15,1,31044,0,3.8386,0.183334,24.1005,0,604800,0,0,1,0,0,0,0,0), +(@CGUID+40,36839,673,15,1,0,0,18.1923,29.8694,36.3265,1.55334,604800,0,0,1,0,0,0,0,0), +(@CGUID+41,36971,673,15,1,0,0,-54.3389,-14.5897,34.4998,3.9619,604800,0,0,1,0,0,0,0,0), +(@CGUID+42,37184,672,15,1,0,0,18.8226,9.700101,20.41841,3.106686,604800,0,0,1,0,0,0,0,0), -- Zafod Boombox (A) +(@CGUID+43,37182,672,15,1,0,0,42.78902,-0.010491,25.24052,3.124139,604800,0,0,1,0,0,0,0,0), -- High Captain Justin Bartlett +(@CGUID+44,36970,672,15,1,0,0,42.80151,25.06216,31.84073,4.756748,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+45,36970,672,15,1,0,0,35.651,20.29211,25.11613,1.58825,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+46,36970,672,15,1,0,0,29.25061,-6.920386,23.37144,3.455752,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+47,36970,672,15,1,0,0,35.57132,-20.18365,25.1162,4.712389,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+48,36970,672,15,1,0,0,9.26111,-22.73216,21.84549,5.864306,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+49,36970,672,15,1,0,0,-36.38065,2.928953,20.5322,1.570796,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+50,36970,672,15,1,0,0,-36.22218,-2.960294,20.53312,4.694936,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+51,36970,672,15,1,0,0,-64.70975,4.575944,23.52326,2.094395,604800,0,0,1,0,0,0,0,0), -- Skybreaker Deckhand +(@CGUID+52,36948,672,15,1,0,0,13.51547,-0.160213,20.87252,3.106686,604800,0,0,1,0,0,0,0,0), -- Muradin Bronzebeard (A) +(@CGUID+53,36838,672,15,1,0,0,-6.155821,-25.23873,21.70498,4.712389,604800,0,0,1,0,0,0,0,0), -- Alliance Gunship Cannon +(@CGUID+54,36838,672,15,1,0,0,-33.6443,-24.06576,21.68014,4.712389,604800,0,0,1,0,0,0,0,0), -- Alliance Gunship Cannon +(@CGUID+55,36838,672,10,1,0,0,-24.66251,-24.52669,21.64428,4.712389,604800,0,0,1,0,0,0,0,0), -- Alliance Gunship Cannon +(@CGUID+56,36838,672,10,1,0,0,-15.35026,-24.90373,21.62014,4.712389,604800,0,0,1,0,0,0,0,0), -- Alliance Gunship Cannon +(@CGUID+57,36839,673,10,1,0,0,11.17875,30.73435,35.95937,1.553343,604800,0,0,1,0,0,0,0,0), -- Horde Gunship Cannon +(@CGUID+58,36839,673,10,1,0,0,-8.200627,31.49327,34.52401,1.553343,604800,0,0,1,0,0,0,0,0); -- Horde Gunship Cannon + +DELETE FROM `creature_addon` WHERE `guid` IN (@CGUID+04,@CGUID+14,@CGUID+28,@CGUID+29,200879); +INSERT INTO `creature_addon` (`guid`,`mount`,`bytes1`,`bytes2`,`auras`) VALUES +(@CGUID+04,0,0x3000000,0x1,'70120'), -- Safe Area (IGB) - On Skybreaker Deck +(@CGUID+14,0,0x3000000,0x1,'70120'), -- Safe Area (IGB) - On Skybreaker Deck +(@CGUID+28,0,0x3000000,0x1,'70121'), -- Safe Area (IGB) - On Orgrim's Hammer Deck +(@CGUID+29,0,0x3000000,0x1,'70121'), -- Safe Area (IGB) - On Orgrim's Hammer Deck +( 200879,0,0x0000000,0x1,'69942'); -- Invisible Stalker (All Phases) - Phase Normal + Dungeon Encounter 1 + +SET @OGUID := 14732; +DELETE FROM `gameobject` WHERE `id`=202211; +DELETE FROM `gameobject` WHERE `guid` BETWEEN @OGUID AND @OGUID+7; +INSERT INTO `gameobject` (`guid`,`id`,`map`,`spawnMask`,`phaseMask`,`position_x`,`position_y`,`position_z`,`orientation`,`rotation0`,`rotation1`,`rotation2`,`rotation3`,`spawntimesecs`,`animprogress`,`state`) VALUES +(@OGUID+0,202178,673,1,1,-19.87256,-14.17484,33.63771,4.71239,0,0,0,1,604800,255,1), -- Gunship Armory +(@OGUID+1,202180,673,2,1,-19.87256,-14.17484,33.63771,4.71239,0,0,0,1,604800,255,1), -- Gunship Armory +(@OGUID+2,202177,673,4,1,-19.87256,-14.17484,33.63771,4.71239,0,0,0,1,604800,255,1), -- Gunship Armory +(@OGUID+3,202179,673,8,1,-19.87256,-14.17484,33.63771,4.71239,0,0,0,1,604800,255,1), -- Gunship Armory +(@OGUID+4,201873,672,1,1,-45.44891,-0.062003,20.56404,0.2697698,0,0,0,1,604800,255,1), +(@OGUID+5,201874,672,2,1,-45.44891,-0.062003,20.56404,0.2697698,0,0,0,1,604800,255,1), +(@OGUID+6,201872,672,4,1,-45.44891,-0.062003,20.56404,0.2697698,0,0,0,1,604800,255,1), +(@OGUID+7,201875,672,8,1,-45.44891,-0.062003,20.56404,0.2697698,0,0,0,1,604800,255,1); + +DELETE FROM `spell_custom_attr` WHERE `entry` IN (72347); +INSERT INTO `spell_custom_attr` (`entry`,`attributes`) VALUES +(72347,4096); + +UPDATE `creature_model_info` SET `bounding_radius`=0.520500,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30508; -- Muradin Bronzebeard +UPDATE `creature_model_info` SET `bounding_radius`=0.558000,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30416; -- High Overlord Saurfang +UPDATE `creature_model_info` SET `bounding_radius`=0.500000,`combat_reach`=1.00000,`gender`=2 WHERE `modelid`=31043; -- The Skybreaker +UPDATE `creature_model_info` SET `bounding_radius`=0.500000,`combat_reach`=1.00000,`gender`=2 WHERE `modelid`=31044; -- Orgrim's Hammer +UPDATE `creature_model_info` SET `bounding_radius`=1.250000,`combat_reach`=1.25000,`gender`=2 WHERE `modelid`=30615; -- Teleport Portal, Teleport Exit +UPDATE `creature_model_info` SET `bounding_radius`=0.364000,`combat_reach`=2.62500,`gender`=1 WHERE `modelid`=30609; -- Skybreaker Sorcerer +UPDATE `creature_model_info` SET `bounding_radius`=0.615825,`combat_reach`=3.01875,`gender`=1 WHERE `modelid`=30610; -- Skybreaker Sorcerer +UPDATE `creature_model_info` SET `bounding_radius`=0.615825,`combat_reach`=3.01875,`gender`=0 WHERE `modelid`=30611; -- Skybreaker Sorcerer +UPDATE `creature_model_info` SET `bounding_radius`=0.347000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30603; -- Skybreaker Rifleman +UPDATE `creature_model_info` SET `bounding_radius`=0.381700,`combat_reach`=1.65000,`gender`=0 WHERE `modelid`=30604; -- Skybreaker Rifleman +UPDATE `creature_model_info` SET `bounding_radius`=0.347000,`combat_reach`=1.50000,`gender`=1 WHERE `modelid`=30605; -- Skybreaker Rifleman +UPDATE `creature_model_info` SET `bounding_radius`=0.416400,`combat_reach`=1.80000,`gender`=0 WHERE `modelid`=30602; -- Skybreaker Mortar Soldier +UPDATE `creature_model_info` SET `bounding_radius`=0.306000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30598; -- Skybreaker Marine +UPDATE `creature_model_info` SET `bounding_radius`=0.306000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30599; -- Skybreaker Marine +UPDATE `creature_model_info` SET `bounding_radius`=1.000000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30600; -- Skybreaker Marine +UPDATE `creature_model_info` SET `bounding_radius`=0.208000,`combat_reach`=1.50000,`gender`=1 WHERE `modelid`=30601; -- Skybreaker Marine +UPDATE `creature_model_info` SET `bounding_radius`=0.397800,`combat_reach`=1.95000,`gender`=0 WHERE `modelid`=30606; -- Skybreaker Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.367200,`combat_reach`=1.80000,`gender`=0 WHERE `modelid`=30607; -- Skybreaker Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.382500,`combat_reach`=1.87500,`gender`=0 WHERE `modelid`=30608; -- Skybreaker Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.670250,`combat_reach`=2.62500,`gender`=0 WHERE `modelid`=30741; -- Kor'kron Battle-Mage +UPDATE `creature_model_info` SET `bounding_radius`=0.670250,`combat_reach`=2.62500,`gender`=0 WHERE `modelid`=30742; -- Kor'kron Battle-Mage +UPDATE `creature_model_info` SET `bounding_radius`=0.670250,`combat_reach`=2.62500,`gender`=1 WHERE `modelid`=30743; -- Kor'kron Battle-Mage +UPDATE `creature_model_info` SET `bounding_radius`=0.670250,`combat_reach`=2.62500,`gender`=1 WHERE `modelid`=30744; -- Kor'kron Battle-Mage +UPDATE `creature_model_info` SET `bounding_radius`=0.306000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30739; -- Kor'kron Axethrower +UPDATE `creature_model_info` SET `bounding_radius`=0.306000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30740; -- Kor'kron Axethrower +UPDATE `creature_model_info` SET `bounding_radius`=0.459000,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30748; -- Kor'kron Rocketeer +UPDATE `creature_model_info` SET `bounding_radius`=0.459000,`combat_reach`=2.25000,`gender`=1 WHERE `modelid`=30749; -- Kor'kron Rocketeer +UPDATE `creature_model_info` SET `bounding_radius`=0.372000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30750; -- Kor'kron Reaver +UPDATE `creature_model_info` SET `bounding_radius`=0.372000,`combat_reach`=1.50000,`gender`=0 WHERE `modelid`=30751; -- Kor'kron Reaver +UPDATE `creature_model_info` SET `bounding_radius`=0.236000,`combat_reach`=1.50000,`gender`=1 WHERE `modelid`=30752; -- Kor'kron Reaver +UPDATE `creature_model_info` SET `bounding_radius`=0.520833,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30745; -- Kor'kron Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.520833,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30746; -- Kor'kron Sergeant +UPDATE `creature_model_info` SET `bounding_radius`=0.520833,`combat_reach`=2.25000,`gender`=0 WHERE `modelid`=30747; -- Kor'kron Sergeant + +DELETE FROM `creature_equip_template` WHERE `entry` IN (36948,36939,37116,36969,36950,36961,37117,36968,36957,36960,36970,36971,37182,37833); +INSERT INTO `creature_equip_template` (`entry`,`id`,`itemEntry1`,`itemEntry2`,`itemEntry3`) VALUES +(36948,1,49775,49774,0), -- Muradin Bronzebeard +(36939,1,49773,0,0), -- High Overlord Saurfang +(37116,1,39746,0,0), -- Skybreaker Sorcerer +(36969,1,0,0,12523), -- Skybreaker Rifleman +(36950,1,49687,0,0), -- Skybreaker Marine +(36961,1,49637,0,0), -- Skybreaker Sergeant +(37117,1,39746,0,0), -- Kor'kron Battle-Mage +(36968,1,49691,0,49873), -- Kor'kron Axethrower +(36957,1,49689,0,0), -- Kor'kron Reaver +(36960,1,34638,0,0), -- Kor'kron Sergeant +(36970,1,1493,0,0), -- Skybreaker Deckhand +(36971,1,11019,0,0), -- Orgrim's Hammer Crew +(37182,1,42757,0,2552), -- High Captain Justin Bartlett +(37833,1,43175,0,21554); -- Sky-Reaver Korm Blackscar + +DELETE FROM `spell_target_position` WHERE `id` IN (70446,71284,72340); +INSERT INTO `spell_target_position` (`id`,`effIndex`,`target_map`,`target_position_x`,`target_position_y`,`target_position_z`,`target_orientation`) VALUES +(70446,1,631,-437.078,2390.10,191.233,1.57080), +(71284,1,631,-437.447,2032.51,191.234,4.73831), +(72340,1,631,-548.983,2211.24,539.290,0.00576); + +DELETE FROM `spell_scripts` WHERE `id`=50630; + +DELETE FROM `gameobject_loot_template` WHERE `entry` IN (28045,28072,28057,28090); +INSERT INTO `gameobject_loot_template` (`entry`, `item`, `ChanceOrQuestChance`, `lootmode`, `groupid`, `mincountOrRef`, `maxcount`) VALUES +(28045,1,100,1,0,-12036,2), +(28045,49426,100,1,0,2,2), -- 10N, Emblem of Frost +(28072,1,100,1,0,-34251,2), +(28072,49426,100,1,0,2,2), -- 25N, Emblem of Frost +(28072,49908,38,1,0,1,1), -- 25N, Primordial Saronite +(28072,50274,-35,1,0,1,1), -- 25N, Shadowfrost Shard +(28057,1,100,1,0,-34263,2), +(28057,49426,100,1,0,2,2), -- 10H, Emblem of Frost +(28057,49908,38,1,0,1,1), -- 10H, Primordial Saronite +(28090,1,100,1,0,-34275,2), +(28090,49426,100,1,0,2,2), -- 25H, Emblem of Frost +(28090,49908,50,1,0,1,1), -- 25H, Primordial Saronite +(28090,50274,-75,1,0,1,1); -- 25H, Shadowfrost Shard + +DELETE FROM `disables` WHERE `sourceType`=4 AND `entry` IN (12771,12777,12947,13041,13052,13079,13080,13081,13094,13109,13110,13111,13187,13198,13333,13353); +DELETE FROM `achievement_criteria_data` WHERE `criteria_id` IN (12771,12777,12947,13041,13052,13079,13080,13081,13094,13109,13110,13111,13187,13198,13333,13353); +INSERT INTO `achievement_criteria_data` (`criteria_id`,`type`,`value1`,`value2`,`ScriptName`) VALUES +(13333,12,0,0,''), -- Lich King 10-player bosses defeated +(13353,12,1,0,''), -- Lich King 25-player bosses defeated +(12771,12,0,0,''), -- Storming the Citadel (10 player) +(13041,12,2,0,''), -- Heroic: Storming the Citadel (10 player) +(12947,12,0,0,''), -- Storming the Citadel (25 player) +(13052,12,3,0,''), -- Heroic: Storming the Citadel (25 player) +(12777,12,0,0,''), -- I'm on a Boat (10 player) +(13080,12,1,0,''), -- I'm on a Boat (25 player) +(13079,12,2,0,''), -- I'm on a Boat (10 player, Heroic) +(13081,12,3,0,''), -- I'm on a Boat (25 player, Heroic) +(12777,11,0,0,'achievement_im_on_a_boat'), -- I'm on a Boat (10 player) +(13080,11,0,0,'achievement_im_on_a_boat'), -- I'm on a Boat (25 player) +(13079,11,0,0,'achievement_im_on_a_boat'), -- I'm on a Boat (10 player, Heroic) +(13081,11,0,0,'achievement_im_on_a_boat'), -- I'm on a Boat (25 player, Heroic) +(13094,12,0,0,''), -- Gunship Battle victories (Icecrown 10 player) +(13110,12,2,0,''), -- Gunship Battle victories (Heroic Icecrown 10 player) +(13109,12,1,0,''), -- Gunship Battle victories (Icecrown 25 player) +(13111,12,3,0,''), -- Gunship Battle victories (Heroic Icecrown 25 player) +(13187,12,3,0,''), +(13198,12,2,0,''); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 9e05ade2a21..cf7cadadbfd 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -31,6 +31,7 @@ #include "Player.h" #include "Cell.h" #include "CellImpl.h" +#include "Totem.h" Transport::Transport() : GameObject(), _transportInfo(NULL), _isMoving(true), _pendingStop(false), @@ -328,6 +329,129 @@ GameObject* Transport::CreateGOPassenger(uint32 guid, GameObjectData const* data return go; } +TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/) +{ + Map* map = FindMap(); + if (!map) + return NULL; + + uint32 mask = UNIT_MASK_SUMMON; + if (properties) + { + switch (properties->Category) + { + case SUMMON_CATEGORY_PET: + mask = UNIT_MASK_GUARDIAN; + break; + case SUMMON_CATEGORY_PUPPET: + mask = UNIT_MASK_PUPPET; + break; + case SUMMON_CATEGORY_VEHICLE: + mask = UNIT_MASK_MINION; + break; + case SUMMON_CATEGORY_WILD: + case SUMMON_CATEGORY_ALLY: + case SUMMON_CATEGORY_UNK: + { + switch (properties->Type) + { + case SUMMON_TYPE_MINION: + case SUMMON_TYPE_GUARDIAN: + case SUMMON_TYPE_GUARDIAN2: + mask = UNIT_MASK_GUARDIAN; + break; + case SUMMON_TYPE_TOTEM: + case SUMMON_TYPE_LIGHTWELL: + mask = UNIT_MASK_TOTEM; + break; + case SUMMON_TYPE_VEHICLE: + case SUMMON_TYPE_VEHICLE2: + mask = UNIT_MASK_SUMMON; + break; + case SUMMON_TYPE_MINIPET: + mask = UNIT_MASK_MINION; + break; + default: + if (properties->Flags & 512) // Mirror Image, Summon Gargoyle + mask = UNIT_MASK_GUARDIAN; + break; + } + break; + } + default: + return NULL; + } + } + + uint32 phase = PHASEMASK_NORMAL; + uint32 team = 0; + if (summoner) + { + phase = summoner->GetPhaseMask(); + if (summoner->GetTypeId() == TYPEID_PLAYER) + team = summoner->ToPlayer()->GetTeam(); + } + + TempSummon* summon = NULL; + switch (mask) + { + case UNIT_MASK_SUMMON: + summon = new TempSummon(properties, summoner, false); + break; + case UNIT_MASK_GUARDIAN: + summon = new Guardian(properties, summoner, false); + break; + case UNIT_MASK_PUPPET: + summon = new Puppet(properties, summoner); + break; + case UNIT_MASK_TOTEM: + summon = new Totem(properties, summoner); + break; + case UNIT_MASK_MINION: + summon = new Minion(properties, summoner, false); + break; + } + + float x, y, z, o; + pos.GetPosition(x, y, z, o); + CalculatePassengerPosition(x, y, z, &o); + + if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, phase, entry, vehId, team, x, y, z, o)) + { + delete summon; + return NULL; + } + + summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); + + summon->SetTransport(this); + summon->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); + summon->m_movementInfo.transport.guid = GetGUID(); + summon->m_movementInfo.transport.pos.Relocate(pos); + summon->Relocate(x, y, z, o); + summon->SetHomePosition(x, y, z, o); + summon->SetTransportHomePosition(pos); + + /// @HACK - transport models are not added to map's dynamic LoS calculations + /// because the current GameObjectModel cannot be moved without recreating + summon->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); + + summon->InitStats(duration); + + if (!map->AddToMap<Creature>(summon)) + { + delete summon; + return NULL; + } + + _staticPassengers.insert(summon); + + summon->InitSummon(); + summon->SetTempSummonType(summonType); + + return summon; +} + void Transport::UpdatePosition(float x, float y, float z, float o) { bool newActive = GetMap()->IsGridLoaded(x, y); diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index f429d938429..398356c4980 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -47,6 +47,24 @@ class Transport : public GameObject, public TransportBase Creature* CreateNPCPassenger(uint32 guid, CreatureData const* data); GameObject* CreateGOPassenger(uint32 guid, GameObjectData const* data); + /** + * @fn bool Transport::SummonPassenger(uint64, Position const&, TempSummonType, SummonPropertiesEntry const*, uint32, Unit*, uint32, uint32) + * + * @brief Temporarily summons a creature as passenger on this transport. + * + * @param entry Id of the creature from creature_template table + * @param pos Initial position of the creature (transport offsets) + * @param summonType + * @param properties + * @param duration Determines how long the creauture will exist in world depending on @summonType (in milliseconds) + * @param summoner Summoner of the creature (for AI purposes) + * @param spellId + * @param vehId If set, this value overrides vehicle id from creature_template that the creature will use + * + * @return Summoned creature. + */ + TempSummon* SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0); + /// This method transforms supplied transport offsets into global coordinates void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const OVERRIDE { diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 8da94ef2852..7365d592a62 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -522,6 +522,7 @@ void AddSC_boss_falric(); void AddSC_boss_marwyn(); void AddSC_boss_lord_marrowgar(); // Icecrown Citadel void AddSC_boss_lady_deathwhisper(); +void AddSC_boss_icecrown_gunship_battle(); void AddSC_boss_deathbringer_saurfang(); void AddSC_boss_festergut(); void AddSC_boss_rotface(); @@ -1361,6 +1362,7 @@ void AddNorthrendScripts() AddSC_boss_marwyn(); AddSC_boss_lord_marrowgar(); // Icecrown Citadel AddSC_boss_lady_deathwhisper(); + AddSC_boss_icecrown_gunship_battle(); AddSC_boss_deathbringer_saurfang(); AddSC_boss_festergut(); AddSC_boss_rotface(); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 93f264d2d61..009b9861eb6 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3384,6 +3384,15 @@ void SpellMgr::LoadSpellInfoCorrections() case 71169: // Shadow's Fate spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS; break; + case 72347: // Lock Players and Tap Chest + spellInfo->AttributesEx3 &= ~SPELL_ATTR3_NO_INITIAL_AGGRO; + break; + case 73843: // Award Reputation - Boss Kill + case 73844: // Award Reputation - Boss Kill + case 73845: // Award Reputation - Boss Kill + case 73846: // Award Reputation - Boss Kill + spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd + break; case 72378: // Blood Nova (Deathbringer Saurfang) case 73058: // Blood Nova (Deathbringer Saurfang) spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); diff --git a/src/server/scripts/Northrend/CMakeLists.txt b/src/server/scripts/Northrend/CMakeLists.txt index 42a7ee15bb6..aff3c0a9528 100644 --- a/src/server/scripts/Northrend/CMakeLists.txt +++ b/src/server/scripts/Northrend/CMakeLists.txt @@ -168,6 +168,7 @@ set(scripts_STAT_SRCS Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp + Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp Northrend/IcecrownCitadel/boss_festergut.cpp Northrend/IcecrownCitadel/boss_rotface.cpp diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp new file mode 100644 index 00000000000..3e18213b745 --- /dev/null +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp @@ -0,0 +1,2389 @@ +/* + * Copyright (C) 2008-2014 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 "CreatureTextMgr.h" +#include "MoveSpline.h" +#include "MoveSplineInit.h" +#include "SpellScript.h" +#include "ScriptMgr.h" +#include "Transport.h" +#include "TransportMgr.h" +#include "Vehicle.h" +#include "icecrown_citadel.h" + +enum Texts +{ + // High Overlord Saurfang + SAY_SAURFANG_INTRO_1 = 0, + SAY_SAURFANG_INTRO_2 = 1, + SAY_SAURFANG_INTRO_3 = 2, + SAY_SAURFANG_INTRO_4 = 3, + SAY_SAURFANG_INTRO_5 = 4, + SAY_SAURFANG_INTRO_6 = 5, + SAY_SAURFANG_INTRO_A = 6, + SAY_SAURFANG_BOARD = 7, + SAY_SAURFANG_ENTER_SKYBREAKER = 8, + SAY_SAURFANG_AXETHROWERS = 9, + SAY_SAURFANG_ROCKETEERS = 10, + SAY_SAURFANG_MAGES = 11, + SAY_SAURFANG_VICTORY = 12, + SAY_SAURFANG_WIPE = 13, + + // Muradin Bronzebeard + SAY_MURADIN_INTRO_1 = 0, + SAY_MURADIN_INTRO_2 = 1, + SAY_MURADIN_INTRO_3 = 2, + SAY_MURADIN_INTRO_4 = 3, + SAY_MURADIN_INTRO_5 = 4, + SAY_MURADIN_INTRO_6 = 5, + SAY_MURADIN_INTRO_7 = 6, + SAY_MURADIN_INTRO_H = 7, + SAY_MURADIN_BOARD = 8, + SAY_MURADIN_ENTER_ORGRIMMS_HAMMER = 9, + SAY_MURADIN_RIFLEMAN = 10, + SAY_MURADIN_MORTAR = 11, + SAY_MURADIN_SORCERERS = 12, + SAY_MURADIN_VICTORY = 13, + SAY_MURADIN_WIPE = 14, + + SAY_ZAFOD_ROCKET_PACK_ACTIVE = 0, + SAY_ZAFOD_ROCKET_PACK_DISABLED = 1, + + SAY_OVERHEAT = 0 +}; + +enum Events +{ + // High Overlord Saurfang + EVENT_INTRO_H_1 = 1, + EVENT_INTRO_H_2 = 2, + EVENT_INTRO_SUMMON_SKYBREAKER = 3, + EVENT_INTRO_H_3 = 4, + EVENT_INTRO_H_4 = 5, + EVENT_INTRO_H_5 = 6, + EVENT_INTRO_H_6 = 7, + + // Muradin Bronzebeard + EVENT_INTRO_A_1 = 1, + EVENT_INTRO_A_2 = 2, + EVENT_INTRO_SUMMON_ORGRIMS_HAMMER = 3, + EVENT_INTRO_A_3 = 4, + EVENT_INTRO_A_4 = 5, + EVENT_INTRO_A_5 = 6, + EVENT_INTRO_A_6 = 7, + EVENT_INTRO_A_7 = 8, + + EVENT_KEEP_PLAYER_IN_COMBAT = 9, + EVENT_SUMMON_MAGE = 10, + EVENT_ADDS = 11, + EVENT_ADDS_BOARD_YELL = 12, + EVENT_CHECK_RIFLEMAN = 13, + EVENT_CHECK_MORTAR = 14, + EVENT_CLEAVE = 15, + + EVENT_BLADESTORM = 16, + EVENT_WOUNDING_STRIKE = 17 +}; + +enum Spells +{ + // Applied on friendly transport NPCs + SPELL_FRIENDLY_BOSS_DAMAGE_MOD = 70339, + SPELL_CHECK_FOR_PLAYERS = 70332, + SPELL_GUNSHIP_FALL_TELEPORT = 67335, + SPELL_TELEPORT_PLAYERS_ON_RESET_A = 70446, + SPELL_TELEPORT_PLAYERS_ON_RESET_H = 71284, + SPELL_TELEPORT_PLAYERS_ON_VICTORY = 72340, + SPELL_ACHIEVEMENT = 72959, + SPELL_AWARD_REPUTATION_BOSS_KILL = 73843, + + // Murading Bronzebeard + // High Overlord Saurfang + SPELL_BATTLE_FURY = 69637, + SPELL_RENDING_THROW = 70309, + SPELL_CLEAVE = 15284, + SPELL_TASTE_OF_BLOOD = 69634, + + // Applied on enemy NPCs + SPELL_MELEE_TARGETING_ON_SKYBREAKER = 70219, + SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER = 70294, + + // Gunship Hull + SPELL_EXPLOSION_WIPE = 72134, + SPELL_EXPLOSION_VICTORY = 72137, + + // Hostile NPCs + SPELL_TELEPORT_TO_ENEMY_SHIP = 70104, + SPELL_BATTLE_EXPERIENCE = 71201, + SPELL_EXPERIENCED = 71188, + SPELL_VETERAN = 71193, + SPELL_ELITE = 71195, + SPELL_ADDS_BERSERK = 72525, + + // Skybreaker Sorcerer + // Kor'kron Battle-Mage + SPELL_SHADOW_CHANNELING = 43897, + SPELL_BELOW_ZERO = 69705, + + // Skybreaker Rifleman + // Kor'kron Axethrower + SPELL_SHOOT = 70162, + SPELL_HURL_AXE = 70161, + SPELL_BURNING_PITCH_A = 70403, + SPELL_BURNING_PITCH_H = 70397, + SPELL_BURNING_PITCH = 69660, + + // Skybreaker Mortar Soldier + // Kor'kron Rocketeer + SPELL_ROCKET_ARTILLERY_A = 70609, + SPELL_ROCKET_ARTILLERY_H = 69678, + SPELL_BURNING_PITCH_DAMAGE_A = 70383, + SPELL_BURNING_PITCH_DAMAGE_H = 70374, + + // Skybreaker Marine + // Kor'kron Reaver + SPELL_DESPERATE_RESOLVE = 69647, + + // Skybreaker Sergeant + // Kor'kron Sergeant + SPELL_BLADESTORM = 69652, + SPELL_WOUNDING_STRIKE = 69651, + + // + SPELL_LOCK_PLAYERS_AND_TAP_CHEST = 72347, + SPELL_ON_SKYBREAKER_DECK = 70120, + SPELL_ON_ORGRIMS_HAMMER_DECK = 70121, + + // Rocket Pack + SPELL_ROCKET_PACK_DAMAGE = 69193, + SPELL_ROCKET_BURST = 69192, + SPELL_ROCKET_PACK_USEABLE = 70348, + + // Alliance Gunship Cannon + // Horde Gunship Cannon + SPELL_OVERHEAT = 69487, + SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO = 68576, + SPELL_EJECT_ALL_PASSENGERS_WIPE = 50630 +}; + +enum MiscData +{ + ITEM_GOBLIN_ROCKET_PACK = 49278, + + PHASE_COMBAT = 0, + PHASE_INTRO = 1, + + MUSIC_ENCOUNTER = 17289 +}; + +enum EncounterActions +{ + ACTION_SPAWN_MAGE = 1, + ACTION_SPAWN_ALL_ADDS = 2, + ACTION_CLEAR_SLOT = 3, + ACTION_SET_SLOT = 4, + ACTION_SHIP_VISITS = 5 +}; + +Position const SkybreakerAddsSpawnPos = { 15.91131f, 0.0f, 20.4628f, M_PI }; +Position const OrgrimsHammerAddsSpawnPos = { 60.728395f, 0.0f, 38.93467f, M_PI }; + +// Horde encounter +Position const SkybreakerTeleportPortal = { 6.666975f, 0.013001f, 20.87888f, 0.0f }; +Position const OrgrimsHammerTeleportExit = { 7.461699f, 0.158853f, 35.72989f, 0.0f }; + +// Alliance encounter +Position const OrgrimsHammerTeleportPortal = { 47.550990f, -0.101778f, 37.61111f, 0.0f }; +Position const SkybreakerTeleportExit = { -17.55738f, -0.090421f, 21.18366f, 0.0f }; + +enum PassengerSlots +{ + // Freezing the cannons + SLOT_FREEZE_MAGE = 0, + + // Channeling the portal, refilled with adds that board player's ship + SLOT_MAGE_1 = 1, + SLOT_MAGE_2 = 2, + + // Rifleman + SLOT_RIFLEMAN_1 = 3, + SLOT_RIFLEMAN_2 = 4, + SLOT_RIFLEMAN_3 = 5, + SLOT_RIFLEMAN_4 = 6, + + // Additional Rifleman on 25 man + SLOT_RIFLEMAN_5 = 7, + SLOT_RIFLEMAN_6 = 8, + SLOT_RIFLEMAN_7 = 9, + SLOT_RIFLEMAN_8 = 10, + + // Mortar + SLOT_MORTAR_1 = 11, + SLOT_MORTAR_2 = 12, + + // Additional spawns on 25 man + SLOT_MORTAR_3 = 13, + SLOT_MORTAR_4 = 14, + + // Marines + SLOT_MARINE_1 = 15, + SLOT_MARINE_2 = 16, + + // Additional spawns on 25 man + SLOT_MARINE_3 = 17, + SLOT_MARINE_4 = 18, + + // Sergeants + SLOT_SERGEANT_1 = 19, + + // Additional spawns on 25 man + SLOT_SERGEANT_2 = 20, + + MAX_SLOTS +}; + +struct SlotInfo +{ + uint32 Entry; + Position TargetPosition; + uint32 Cooldown; +}; + +SlotInfo const SkybreakerSlotInfo[MAX_SLOTS] = +{ + { NPC_SKYBREAKER_SORCERER, { -9.479858f, 0.05663967f, 20.77026f, 4.729842f }, 0 }, + + { NPC_SKYBREAKER_SORCERER, { 6.385986f, 4.978760f, 20.55417f, 4.694936f }, 0 }, + { NPC_SKYBREAKER_SORCERER, { 6.579102f, -4.674561f, 20.55060f, 1.553343f }, 0 }, + + { NPC_SKYBREAKER_RIFLEMAN, { -29.563900f, -17.95801f, 20.73837f, 4.747295f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -18.017210f, -18.82056f, 20.79150f, 4.747295f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -9.1193850f, -18.79102f, 20.58887f, 4.712389f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -0.3364258f, -18.87183f, 20.56824f, 4.712389f }, 30 }, + + { NPC_SKYBREAKER_RIFLEMAN, { -34.705810f, -17.67261f, 20.51523f, 4.729842f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -23.562010f, -18.28564f, 20.67859f, 4.729842f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -13.602780f, -18.74268f, 20.59622f, 4.712389f }, 30 }, + { NPC_SKYBREAKER_RIFLEMAN, { -4.3350220f, -18.84619f, 20.58234f, 4.712389f }, 30 }, + + { NPC_SKYBREAKER_MORTAR_SOLDIER, { -31.70142f, 18.02783f, 20.77197f, 4.712389f }, 30 }, + { NPC_SKYBREAKER_MORTAR_SOLDIER, { -9.368652f, 18.75806f, 20.65335f, 4.712389f }, 30 }, + + { NPC_SKYBREAKER_MORTAR_SOLDIER, { -20.40851f, 18.40381f, 20.50647f, 4.694936f }, 30 }, + { NPC_SKYBREAKER_MORTAR_SOLDIER, { 0.1585693f, 18.11523f, 20.41949f, 4.729842f }, 30 }, + + { NPC_SKYBREAKER_MARINE, SkybreakerTeleportPortal, 0 }, + { NPC_SKYBREAKER_MARINE, SkybreakerTeleportPortal, 0 }, + + { NPC_SKYBREAKER_MARINE, SkybreakerTeleportPortal, 0 }, + { NPC_SKYBREAKER_MARINE, SkybreakerTeleportPortal, 0 }, + + { NPC_SKYBREAKER_SERGEANT, SkybreakerTeleportPortal, 0 }, + + { NPC_SKYBREAKER_SERGEANT, SkybreakerTeleportPortal, 0 } +}; + +SlotInfo const OrgrimsHammerSlotInfo[MAX_SLOTS] = +{ + { NPC_KOR_KRON_BATTLE_MAGE, { 13.58548f, 0.3867192f, 34.99243f, 1.53589f }, 0 }, + + { NPC_KOR_KRON_BATTLE_MAGE, { 47.29290f, -4.308941f, 37.55550f, 1.570796f }, 0 }, + { NPC_KOR_KRON_BATTLE_MAGE, { 47.34621f, 4.032004f, 37.70952f, 4.817109f }, 0 }, + + { NPC_KOR_KRON_AXETHROWER, { -12.09280f, 27.65942f, 33.58557f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { -3.170555f, 28.30652f, 34.21082f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { 14.928040f, 26.18018f, 35.47803f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { 24.703310f, 25.36584f, 35.97845f, 1.53589f }, 30 }, + + { NPC_KOR_KRON_AXETHROWER, { -16.65302f, 27.59668f, 33.18726f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { -8.084572f, 28.21448f, 33.93805f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { 7.594765f, 27.41968f, 35.00775f, 1.53589f }, 30 }, + { NPC_KOR_KRON_AXETHROWER, { 20.763390f, 25.58215f, 35.75287f, 1.53589f }, 30 }, + + { NPC_KOR_KRON_ROCKETEER, { -11.44849f, -25.71838f, 33.64343f, 1.518436f }, 30 }, + { NPC_KOR_KRON_ROCKETEER, { 12.30336f, -25.69653f, 35.32373f, 1.518436f }, 30 }, + + { NPC_KOR_KRON_ROCKETEER, { -0.05931854f, -25.46399f, 34.50592f, 1.518436f }, 30 }, + { NPC_KOR_KRON_ROCKETEER, { 27.62149000f, -23.48108f, 36.12708f, 1.518436f }, 30 }, + + { NPC_KOR_KRON_REAVER, OrgrimsHammerTeleportPortal, 0 }, + { NPC_KOR_KRON_REAVER, OrgrimsHammerTeleportPortal, 0 }, + + { NPC_KOR_KRON_REAVER, OrgrimsHammerTeleportPortal, 0 }, + { NPC_KOR_KRON_REAVER, OrgrimsHammerTeleportPortal, 0 }, + + { NPC_KOR_KRON_SERGEANT, OrgrimsHammerTeleportPortal, 0 }, + + { NPC_KOR_KRON_SERGEANT, OrgrimsHammerTeleportPortal, 0 } +}; + +class PassengerController +{ +public: + PassengerController() + { + ResetSlots(HORDE); + } + + void SetTransport(Transport* transport) { _transport = transport; } + + void ResetSlots(uint32 team) + { + _transport = NULL; + memset(_controlledSlots, 0, sizeof(uint64)* MAX_SLOTS); + memset(_respawnCooldowns, 0, sizeof(time_t)* MAX_SLOTS); + _spawnPoint = team == HORDE ? &OrgrimsHammerAddsSpawnPos : &SkybreakerAddsSpawnPos; + _slotInfo = team == HORDE ? OrgrimsHammerSlotInfo : SkybreakerSlotInfo; + } + + bool SummonCreatures(PassengerSlots first, PassengerSlots last) + { + if (!_transport) + return false; + + bool summoned = false; + time_t now = time(NULL); + for (int32 i = first; i <= last; ++i) + { + if (_respawnCooldowns[i] > now) + continue; + + if (_controlledSlots[i]) + { + Creature* current = ObjectAccessor::GetCreature(*_transport, _controlledSlots[i]); + if (current && current->IsAlive()) + continue; + } + + if (Creature* passenger = _transport->SummonPassenger(_slotInfo[i].Entry, SelectSpawnPoint(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, NULL, 15000)) + { + _controlledSlots[i] = passenger->GetGUID(); + _respawnCooldowns[i] = time_t(0); + passenger->AI()->SetData(ACTION_SET_SLOT, i); + summoned = true; + } + } + + return summoned; + } + + void ClearSlot(PassengerSlots slot) + { + _controlledSlots[slot] = 0; + _respawnCooldowns[slot] = time(NULL) + _slotInfo[slot].Cooldown; + } + + bool SlotsNeedRefill(PassengerSlots first, PassengerSlots last) const + { + for (int32 i = first; i <= last; ++i) + if (!_controlledSlots[i]) + return true; + + return false; + } + +private: + Position SelectSpawnPoint() const + { + Position newPos; + float angle = frand(-M_PI * 0.5f, M_PI * 0.5f); + newPos.m_positionX = _spawnPoint->GetPositionX() + 2.0f * std::cos(angle); + newPos.m_positionY = _spawnPoint->GetPositionY() + 2.0f * std::sin(angle); + newPos.m_positionZ = _spawnPoint->GetPositionZ(); + newPos.SetOrientation(_spawnPoint->GetOrientation()); + return newPos; + } + + Transport* _transport; + uint64 _controlledSlots[MAX_SLOTS]; + time_t _respawnCooldowns[MAX_SLOTS]; + Position const* _spawnPoint; + SlotInfo const* _slotInfo; +}; + +class DelayedMovementEvent : public BasicEvent +{ +public: + DelayedMovementEvent(Creature* owner, Position const& dest) : _owner(owner), _dest(dest) { } + + bool Execute(uint64, uint32) OVERRIDE + { + if (!_owner->IsAlive()) + return true; + + _owner->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, *_owner, false); + + Movement::MoveSplineInit init(_owner); + init.DisableTransportPathTransformations(); + init.MoveTo(_dest.GetPositionX(), _dest.GetPositionY(), _dest.GetPositionZ(), false); + init.Launch(); + + return true; + } + +private: + Creature* _owner; + Position const& _dest; +}; + +class ResetEncounterEvent : public BasicEvent +{ +public: + ResetEncounterEvent(Unit* caster, uint32 spellId, uint64 otherTransport) : _caster(caster), _spellId(spellId), _otherTransport(otherTransport) { } + + bool Execute(uint64, uint32) OVERRIDE + { + _caster->CastSpell(_caster, _spellId, true); + _caster->GetTransport()->AddObjectToRemoveList(); + + if (GameObject* go = HashMapHolder<GameObject>::Find(_otherTransport)) + go->AddObjectToRemoveList(); + + return true; + } + +private: + Unit* _caster; + uint32 _spellId; + uint64 _otherTransport; +}; + +class BattleExperienceEvent : public BasicEvent +{ +public: + static uint32 const ExperiencedSpells[5]; + static uint32 const ExperiencedTimes[5]; + + BattleExperienceEvent(Creature* creature) : _creature(creature), _level(0) { } + + bool Execute(uint64 timer, uint32 /*diff*/) OVERRIDE + { + if (!_creature->IsAlive()) + return true; + + _creature->RemoveAurasDueToSpell(ExperiencedSpells[_level]); + ++_level; + + _creature->CastSpell(_creature, ExperiencedSpells[_level], TRIGGERED_FULL_MASK); + if (_level < (_creature->GetMap()->IsHeroic() ? 4 : 3)) + { + _creature->m_Events.AddEvent(this, timer + ExperiencedTimes[_level]); + return false; + } + + return true; + } + +private: + Creature* _creature; + int32 _level; +}; + +uint32 const BattleExperienceEvent::ExperiencedSpells[5] = { 0, SPELL_EXPERIENCED, SPELL_VETERAN, SPELL_ELITE, SPELL_ADDS_BERSERK }; +uint32 const BattleExperienceEvent::ExperiencedTimes[5] = { 100000, 70000, 60000, 90000, 0 }; + +struct gunship_npc_AI : public ScriptedAI +{ + gunship_npc_AI(Creature* creature) : ScriptedAI(creature), + Instance(creature->GetInstanceScript()), Slot(NULL), Index(uint32(-1)) + { + BurningPitchId = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_BURNING_PITCH_A : SPELL_BURNING_PITCH_H; + me->setRegeneratingHealth(false); + } + + void SetData(uint32 type, uint32 data) OVERRIDE + { + if (type == ACTION_SET_SLOT && data < MAX_SLOTS) + { + SetSlotInfo(data); + + me->SetReactState(REACT_PASSIVE); + + float x, y, z, o; + Slot->TargetPosition.GetPosition(x, y, z, o); + + me->SetTransportHomePosition(Slot->TargetPosition); + float hx = x, hy = y, hz = z, ho = o; + me->GetTransport()->CalculatePassengerPosition(hx, hy, hz, &ho); + me->SetHomePosition(hx, hy, hz, ho); + + me->GetMotionMaster()->MovePoint(EVENT_CHARGE_PREPATH, Slot->TargetPosition, false); + + Movement::MoveSplineInit init(me); + init.DisableTransportPathTransformations(); + init.MoveTo(x, y, z, false); + init.Launch(); + } + } + + void EnterEvadeMode() OVERRIDE + { + if (!me->IsAlive() || !me->IsInCombat()) + return; + + me->DeleteThreatList(); + me->CombatStop(true); + me->GetMotionMaster()->MoveTargetedHome(); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + if (Slot) + if (Creature* captain = me->FindNearestCreature(Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? NPC_IGB_MURADIN_BRONZEBEARD : NPC_IGB_HIGH_OVERLORD_SAURFANG, 200.0f)) + captain->AI()->SetData(ACTION_CLEAR_SLOT, Index); + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == EVENT_CHARGE_PREPATH && Slot) + { + me->SetFacingTo(Slot->TargetPosition.GetOrientation()); + me->m_Events.AddEvent(new BattleExperienceEvent(me), me->m_Events.CalculateTime(BattleExperienceEvent::ExperiencedTimes[0])); + DoCast(me, SPELL_BATTLE_EXPERIENCE, true); + me->SetReactState(REACT_AGGRESSIVE); + } + } + + bool CanAIAttack(Unit const* target) const OVERRIDE + { + return target->HasAura(Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_ON_ORGRIMS_HAMMER_DECK : SPELL_ON_SKYBREAKER_DECK); + } + +protected: + void SetSlotInfo(uint32 index) + { + Index = index; + Slot = &((Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SkybreakerSlotInfo : OrgrimsHammerSlotInfo)[Index]); + } + + bool SelectVictim() + { + if (Instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return false; + + if (!me->HasReactState(REACT_PASSIVE)) + { + if (Unit* victim = me->SelectVictim()) + AttackStart(victim); + return me->GetVictim(); + } + else if (me->getThreatManager().isThreatListEmpty()) + { + EnterEvadeMode(); + return false; + } + + return true; + } + + void TriggerBurningPitch() + { + if (Instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS && + !me->HasUnitState(UNIT_STATE_CASTING) && !me->HasReactState(REACT_PASSIVE) && + !me->HasSpellCooldown(BurningPitchId)) + { + DoCastAOE(BurningPitchId, true); + me->_AddCreatureSpellCooldown(BurningPitchId, time(NULL) + urand(3000, 4000) / IN_MILLISECONDS); + } + } + + InstanceScript* Instance; + SlotInfo const* Slot; + uint32 Index; + uint32 BurningPitchId; +}; + +class npc_gunship : public CreatureScript +{ + public: + npc_gunship() : CreatureScript("npc_gunship") { } + + struct npc_gunshipAI : public NullCreatureAI + { + npc_gunshipAI(Creature* creature) : NullCreatureAI(creature), + _teamInInstance(creature->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE)), + _summonedFirstMage(false), _died(false) + { + me->setRegeneratingHealth(false); + } + + void DamageTaken(Unit* /*source*/, uint32& damage) OVERRIDE + { + if (damage > me->GetHealth()) + { + JustDied(NULL); + damage = me->GetHealth() - 1; + return; + } + + if (_summonedFirstMage) + return; + + if (me->GetTransport()->GetEntry() != uint32(_teamInInstance == HORDE ? GO_THE_SKYBREAKER_H : GO_ORGRIMS_HAMMER_A)) + return; + + if (!me->HealthBelowPctDamaged(90, damage)) + return; + + _summonedFirstMage = true; + if (Creature* captain = me->FindNearestCreature(_teamInInstance == HORDE ? NPC_IGB_MURADIN_BRONZEBEARD : NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) + captain->AI()->DoAction(ACTION_SPAWN_MAGE); + } + + void JustDied(Unit* /*killer*/) OVERRIDE + { + if (_died) + return; + + _died = true; + + bool isVictory = me->GetTransport()->GetEntry() == GO_THE_SKYBREAKER_H || me->GetTransport()->GetEntry() == GO_ORGRIMS_HAMMER_A; + InstanceScript* instance = me->GetInstanceScript(); + if (Creature* creature = me->FindNearestCreature(me->GetEntry() == NPC_ORGRIMS_HAMMER ? NPC_THE_SKYBREAKER : NPC_ORGRIMS_HAMMER, 200.0f)) + { + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, creature); + creature->RemoveAurasDueToSpell(SPELL_CHECK_FOR_PLAYERS); + } + + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + me->RemoveAurasDueToSpell(SPELL_CHECK_FOR_PLAYERS); + + me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, 0); + std::list<Creature*> creatures; + GetCreatureListWithEntryInGrid(creatures, me, NPC_MARTYR_STALKER_IGB_SAURFANG, SIZE_OF_GRIDS); + for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + (*itr)->AI()->EnterEvadeMode(); + + + uint32 explosionSpell = isVictory ? SPELL_EXPLOSION_VICTORY : SPELL_EXPLOSION_WIPE; + creatures.clear(); + GetCreatureListWithEntryInGrid(creatures, me, NPC_GUNSHIP_HULL, 200.0f); + for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + Creature* hull = *itr; + if (hull->GetTransport() != me->GetTransport()) + continue; + + hull->CastSpell(hull, explosionSpell, TRIGGERED_FULL_MASK); + } + + creatures.clear(); + GetCreatureListWithEntryInGrid(creatures, me, _teamInInstance == HORDE ? NPC_HORDE_GUNSHIP_CANNON : NPC_ALLIANCE_GUNSHIP_CANNON, 200.0f); + for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr) + { + Creature* cannon = *itr; + if (isVictory) + { + cannon->CastSpell(cannon, SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO, TRIGGERED_FULL_MASK); + + WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, cannon->GetPackGUID().size() + 4); + data.append(cannon->GetPackGUID()); + data << uint32(0); + cannon->SendMessageToSet(&data, true); + + cannon->RemoveVehicleKit(); + } + else + cannon->CastSpell(cannon, SPELL_EJECT_ALL_PASSENGERS_WIPE, TRIGGERED_FULL_MASK); + } + + uint32 creatureEntry = NPC_IGB_MURADIN_BRONZEBEARD; + uint8 textId = isVictory ? SAY_MURADIN_VICTORY : SAY_MURADIN_WIPE; + if (_teamInInstance == HORDE) + { + creatureEntry = NPC_IGB_HIGH_OVERLORD_SAURFANG; + textId = isVictory ? SAY_SAURFANG_VICTORY : SAY_SAURFANG_WIPE; + } + + if (Creature* creature = me->FindNearestCreature(creatureEntry, 100.0f)) + creature->AI()->Talk(textId); + + if (isVictory) + { + if (GameObject* go = HashMapHolder<GameObject>::Find(instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE))) + if (Transport* otherTransport = go->ToTransport()) + otherTransport->EnableMovement(true); + + me->GetTransport()->EnableMovement(true); + + if (Creature* ship = me->FindNearestCreature(_teamInInstance == HORDE ? NPC_ORGRIMS_HAMMER : NPC_THE_SKYBREAKER, 200.0f)) + { + ship->CastSpell(ship, SPELL_TELEPORT_PLAYERS_ON_VICTORY, TRIGGERED_FULL_MASK); + ship->CastSpell(ship, SPELL_ACHIEVEMENT, TRIGGERED_FULL_MASK); + ship->CastSpell(ship, SPELL_AWARD_REPUTATION_BOSS_KILL, TRIGGERED_FULL_MASK); + } + } + else + { + uint32 teleportSpellId = _teamInInstance == HORDE ? SPELL_TELEPORT_PLAYERS_ON_RESET_H : SPELL_TELEPORT_PLAYERS_ON_RESET_A; + me->m_Events.AddEvent(new ResetEncounterEvent(me, teleportSpellId, me->GetInstanceScript()->GetData64(DATA_ENEMY_GUNSHIP)), + me->m_Events.CalculateTime(8000)); + } + + instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, isVictory ? DONE : FAIL); + } + + void SetGUID(uint64 guid, int32 id/* = 0*/) OVERRIDE + { + if (id != ACTION_SHIP_VISITS) + return; + + std::map<uint64, uint32>::iterator itr = _shipVisits.find(guid); + if (itr == _shipVisits.end()) + _shipVisits[guid] = 1; + else + ++itr->second; + } + + uint32 GetData(uint32 id) const OVERRIDE + { + if (id != ACTION_SHIP_VISITS) + return 0; + + uint32 max = 0; + for (std::map<uint64, uint32>::const_iterator itr = _shipVisits.begin(); itr != _shipVisits.end(); ++itr) + max = std::max(max, itr->second); + + return max; + } + + private: + uint32 _teamInInstance; + std::map<uint64, uint32> _shipVisits; + bool _summonedFirstMage; + bool _died; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + if (!creature->GetTransport()) + return NULL; + + return GetIcecrownCitadelAI<npc_gunshipAI>(creature); + } +}; + +class npc_high_overlord_saurfang_igb : public CreatureScript +{ + public: + npc_high_overlord_saurfang_igb() : CreatureScript("npc_high_overlord_saurfang_igb") { } + + struct npc_high_overlord_saurfang_igbAI : public ScriptedAI + { + npc_high_overlord_saurfang_igbAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + _controller.ResetSlots(HORDE); + _controller.SetTransport(creature->GetTransport()); + me->setRegeneratingHealth(false); + me->m_CombatDistance = 70.0f; + } + + void InitializeAI() OVERRIDE + { + ScriptedAI::InitializeAI(); + + _events.Reset(); + _firstMageCooldown = time(NULL) + 60; + _axethrowersYellCooldown = time_t(0); + _rocketeersYellCooldown = time_t(0); + } + + void EnterCombat(Unit* /*target*/) OVERRIDE + { + _events.SetPhase(PHASE_COMBAT); + DoCast(me, _instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_FRIENDLY_BOSS_DAMAGE_MOD : SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER, true); + DoCast(me, SPELL_BATTLE_FURY, true); + _events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000)); + } + + void EnterEvadeMode() OVERRIDE + { + if (!me->IsAlive()) + return; + + me->DeleteThreatList(); + me->CombatStop(true); + me->GetMotionMaster()->MoveTargetedHome(); + + Reset(); + } + + void DoAction(int32 action) OVERRIDE + { + if (action == ACTION_ENEMY_GUNSHIP_TALK) + { + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS); + + Talk(SAY_SAURFANG_INTRO_5); + _events.ScheduleEvent(EVENT_INTRO_H_5, 4000); + _events.ScheduleEvent(EVENT_INTRO_H_6, 11000); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 1); + + _instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, IN_PROGRESS); + // Combat starts now + if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f)) + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, skybreaker, 1); + + if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f)) + { + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, orgrimsHammer, 2); + orgrimsHammer->CastSpell(orgrimsHammer, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK); + } + + me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_ENCOUNTER); + } + else if (action == ACTION_SPAWN_MAGE) + { + time_t now = time(NULL); + if (_firstMageCooldown < now) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, (now - _firstMageCooldown) * IN_MILLISECONDS); + else + _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1); + } + else if (action == ACTION_SPAWN_ALL_ADDS) + { + _events.ScheduleEvent(EVENT_ADDS, 12000); + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 13000); + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 13000); + if (Is25ManRaid()) + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MORTAR_4); + else + { + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MORTAR_1, SLOT_MORTAR_2); + _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); + } + } + } + + void SetData(uint32 type, uint32 data) OVERRIDE + { + if (type == ACTION_CLEAR_SLOT) + { + _controller.ClearSlot(PassengerSlots(data)); + if (data == SLOT_FREEZE_MAGE) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, urand(30000, 33500)); + } + } + + void sGossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) OVERRIDE + { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->GetTransport()->EnableMovement(true); + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_1, 5000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_2, 16000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_SUMMON_SKYBREAKER, 24600, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_3, 29600, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_H_4, 39200, 0, PHASE_INTRO); + } + + void DamageTaken(Unit* , uint32& damage) OVERRIDE + { + if (me->HealthBelowPctDamaged(65, damage) && !me->HasAura(SPELL_TASTE_OF_BLOOD)) + DoCast(me, SPELL_TASTE_OF_BLOOD, true); + + if (damage > me->GetHealth()) + damage = me->GetHealth() - 1; + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO) && _instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_H_1: + Talk(SAY_SAURFANG_INTRO_1); + break; + case EVENT_INTRO_H_2: + Talk(SAY_SAURFANG_INTRO_2); + break; + case EVENT_INTRO_SUMMON_SKYBREAKER: + sTransportMgr->CreateTransport(GO_THE_SKYBREAKER_H, 0, me->GetMap()); + break; + case EVENT_INTRO_H_3: + Talk(SAY_SAURFANG_INTRO_3); + break; + case EVENT_INTRO_H_4: + Talk(SAY_SAURFANG_INTRO_4); + break; + case EVENT_INTRO_H_5: + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + muradin->AI()->Talk(SAY_MURADIN_INTRO_H); + break; + case EVENT_INTRO_H_6: + Talk(SAY_SAURFANG_INTRO_6); + break; + case EVENT_KEEP_PLAYER_IN_COMBAT: + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS) + { + _instance->DoCastSpellOnPlayers(SPELL_LOCK_PLAYERS_AND_TAP_CHEST); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, urand(5000, 8000)); + } + break; + case EVENT_SUMMON_MAGE: + Talk(SAY_SAURFANG_MAGES); + _controller.SummonCreatures(SLOT_FREEZE_MAGE, SLOT_FREEZE_MAGE); + break; + case EVENT_ADDS: + Talk(SAY_SAURFANG_ENTER_SKYBREAKER); + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2); + _controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1); + if (Transport* orgrimsHammer = me->GetTransport()) + orgrimsHammer->SummonPassenger(NPC_TELEPORT_PORTAL, OrgrimsHammerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, NULL, 21000); + + if (GameObject* go = HashMapHolder<GameObject>::Find(_instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE))) + if (Transport* skybreaker = go->ToTransport()) + skybreaker->SummonPassenger(NPC_TELEPORT_EXIT, SkybreakerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, NULL, 23000); + + _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6000); + _events.ScheduleEvent(EVENT_ADDS, 60000); + break; + case EVENT_ADDS_BOARD_YELL: + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_MURADIN_BRONZEBEARD, 200.0f)) + muradin->AI()->Talk(SAY_MURADIN_BOARD); + break; + case EVENT_CHECK_RIFLEMAN: + if (_controller.SummonCreatures(SLOT_RIFLEMAN_1, Is25ManRaid() ? SLOT_RIFLEMAN_8 : SLOT_RIFLEMAN_4)) + { + if (_axethrowersYellCooldown < time(NULL)) + { + Talk(SAY_SAURFANG_AXETHROWERS); + _axethrowersYellCooldown = time(NULL) + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 1000); + break; + case EVENT_CHECK_MORTAR: + if (_controller.SummonCreatures(SLOT_MORTAR_1, Is25ManRaid() ? SLOT_MORTAR_4 : SLOT_MORTAR_2)) + { + if (_rocketeersYellCooldown < time(NULL)) + { + Talk(SAY_SAURFANG_ROCKETEERS); + _rocketeersYellCooldown = time(NULL) + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 1000); + break; + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000)); + break; + default: + break; + } + } + + if (me->IsWithinMeleeRange(me->GetVictim())) + DoMeleeAttackIfReady(); + else if (me->isAttackReady()) + { + DoCastVictim(SPELL_RENDING_THROW); + me->resetAttackTimer(); + } + } + + bool CanAIAttack(Unit const* target) const OVERRIDE + { + return target->HasAura(SPELL_ON_ORGRIMS_HAMMER_DECK) || !target->IsControlledByPlayer(); + } + + private: + EventMap _events; + PassengerController _controller; + InstanceScript* _instance; + time_t _firstMageCooldown; + time_t _axethrowersYellCooldown; + time_t _rocketeersYellCooldown; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI<npc_high_overlord_saurfang_igbAI>(creature); + } +}; + +class npc_muradin_bronzebeard_igb : public CreatureScript +{ + public: + npc_muradin_bronzebeard_igb() : CreatureScript("npc_muradin_bronzebeard_igb") { } + + struct npc_muradin_bronzebeard_igbAI : public ScriptedAI + { + npc_muradin_bronzebeard_igbAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + _controller.ResetSlots(ALLIANCE); + _controller.SetTransport(creature->GetTransport()); + me->setRegeneratingHealth(false); + me->m_CombatDistance = 70.0f; + } + + void InitializeAI() OVERRIDE + { + ScriptedAI::InitializeAI(); + + _events.Reset(); + _firstMageCooldown = time(NULL) + 60; + _riflemanYellCooldown = time_t(0); + _mortarYellCooldown = time_t(0); + } + + void EnterCombat(Unit* /*target*/) OVERRIDE + { + _events.SetPhase(PHASE_COMBAT); + DoCast(me, _instance->GetData(DATA_TEAM_IN_INSTANCE) == ALLIANCE ? SPELL_FRIENDLY_BOSS_DAMAGE_MOD : SPELL_MELEE_TARGETING_ON_SKYBREAKER, true); + DoCast(me, SPELL_BATTLE_FURY, true); + _events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000)); + } + + void EnterEvadeMode() OVERRIDE + { + if (!me->IsAlive()) + return; + + me->DeleteThreatList(); + me->CombatStop(true); + me->GetMotionMaster()->MoveTargetedHome(); + + Reset(); + } + + void DoAction(int32 action) OVERRIDE + { + if (action == ACTION_ENEMY_GUNSHIP_TALK) + { + if (Creature* muradin = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) + muradin->AI()->DoAction(ACTION_SPAWN_ALL_ADDS); + + Talk(SAY_MURADIN_INTRO_6); + _events.ScheduleEvent(EVENT_INTRO_A_6, 5000); + _events.ScheduleEvent(EVENT_INTRO_A_7, 11000); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, 1); + + _instance->SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, IN_PROGRESS); + // Combat starts now + if (Creature* orgrimsHammer = me->FindNearestCreature(NPC_ORGRIMS_HAMMER, 100.0f)) + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, orgrimsHammer, 1); + + if (Creature* skybreaker = me->FindNearestCreature(NPC_THE_SKYBREAKER, 100.0f)) + { + _instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, skybreaker, 2); + skybreaker->CastSpell(skybreaker, SPELL_CHECK_FOR_PLAYERS, TRIGGERED_FULL_MASK); + } + + me->GetMap()->SetZoneMusic(AREA_ICECROWN_CITADEL, MUSIC_ENCOUNTER); + } + else if (action == ACTION_SPAWN_MAGE) + { + time_t now = time(NULL); + if (_firstMageCooldown < now) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, (now - _firstMageCooldown) * IN_MILLISECONDS); + else + _events.ScheduleEvent(EVENT_SUMMON_MAGE, 1); + } + else if (action == ACTION_SPAWN_ALL_ADDS) + { + _events.ScheduleEvent(EVENT_ADDS, 12000); + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 13000); + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 13000); + if (Is25ManRaid()) + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MORTAR_4); + else + { + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MORTAR_1, SLOT_MORTAR_2); + _controller.SummonCreatures(SLOT_RIFLEMAN_1, SLOT_RIFLEMAN_4); + } + } + } + + void SetData(uint32 type, uint32 data) OVERRIDE + { + if (type == ACTION_CLEAR_SLOT) + { + _controller.ClearSlot(PassengerSlots(data)); + if (data == SLOT_FREEZE_MAGE) + _events.ScheduleEvent(EVENT_SUMMON_MAGE, urand(30000, 33500)); + } + } + + void sGossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) OVERRIDE + { + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->GetTransport()->EnableMovement(true); + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_1, 5000); + _events.ScheduleEvent(EVENT_INTRO_A_2, 10000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_SUMMON_ORGRIMS_HAMMER, 28000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_3, 33000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_4, 39000, 0, PHASE_INTRO); + _events.ScheduleEvent(EVENT_INTRO_A_5, 45000, 0, PHASE_INTRO); + } + + void DamageTaken(Unit* , uint32& damage) OVERRIDE + { + if (me->HealthBelowPctDamaged(65, damage) && me->HasAura(SPELL_TASTE_OF_BLOOD)) + DoCast(me, SPELL_TASTE_OF_BLOOD, true); + + if (damage > me->GetHealth()) + damage = me->GetHealth() - 1; + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO) && _instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != IN_PROGRESS) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INTRO_A_1: + Talk(SAY_MURADIN_INTRO_1); + break; + case EVENT_INTRO_A_2: + Talk(SAY_MURADIN_INTRO_2); + break; + case EVENT_INTRO_SUMMON_ORGRIMS_HAMMER: + sTransportMgr->CreateTransport(GO_ORGRIMS_HAMMER_A, 0, me->GetMap()); + break; + case EVENT_INTRO_A_3: + Talk(SAY_MURADIN_INTRO_3); + break; + case EVENT_INTRO_A_4: + Talk(SAY_MURADIN_INTRO_4); + break; + case EVENT_INTRO_A_5: + Talk(SAY_MURADIN_INTRO_5); + break; + case EVENT_INTRO_A_6: + if (Creature* saurfang = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 100.0f)) + saurfang->AI()->Talk(SAY_SAURFANG_INTRO_A); + break; + case EVENT_INTRO_A_7: + Talk(SAY_MURADIN_INTRO_7); + break; + case EVENT_KEEP_PLAYER_IN_COMBAT: + if (_instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == IN_PROGRESS) + { + _instance->DoCastSpellOnPlayers(SPELL_LOCK_PLAYERS_AND_TAP_CHEST); + _events.ScheduleEvent(EVENT_KEEP_PLAYER_IN_COMBAT, urand(5000, 8000)); + } + break; + case EVENT_SUMMON_MAGE: + Talk(SAY_MURADIN_SORCERERS); + _controller.SummonCreatures(SLOT_FREEZE_MAGE, SLOT_FREEZE_MAGE); + break; + case EVENT_ADDS: + Talk(SAY_MURADIN_ENTER_ORGRIMMS_HAMMER); + _controller.SummonCreatures(SLOT_MAGE_1, SLOT_MAGE_2); + _controller.SummonCreatures(SLOT_MARINE_1, Is25ManRaid() ? SLOT_MARINE_4 : SLOT_MARINE_2); + _controller.SummonCreatures(SLOT_SERGEANT_1, Is25ManRaid() ? SLOT_SERGEANT_2 : SLOT_SERGEANT_1); + if (Transport* skybreaker = me->GetTransport()) + skybreaker->SummonPassenger(NPC_TELEPORT_PORTAL, SkybreakerTeleportPortal, TEMPSUMMON_TIMED_DESPAWN, NULL, 21000); + + if (GameObject* go = HashMapHolder<GameObject>::Find(_instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE))) + if (Transport* orgrimsHammer = go->ToTransport()) + orgrimsHammer->SummonPassenger(NPC_TELEPORT_EXIT, OrgrimsHammerTeleportExit, TEMPSUMMON_TIMED_DESPAWN, NULL, 23000); + + _events.ScheduleEvent(EVENT_ADDS_BOARD_YELL, 6000); + _events.ScheduleEvent(EVENT_ADDS, 60000); + break; + case EVENT_ADDS_BOARD_YELL: + if (Creature* saurfang = me->FindNearestCreature(NPC_IGB_HIGH_OVERLORD_SAURFANG, 200.0f)) + saurfang->AI()->Talk(SAY_SAURFANG_BOARD); + break; + case EVENT_CHECK_RIFLEMAN: + if (_controller.SummonCreatures(SLOT_RIFLEMAN_1, Is25ManRaid() ? SLOT_RIFLEMAN_8 : SLOT_RIFLEMAN_4)) + { + if (_riflemanYellCooldown < time(NULL)) + { + Talk(SAY_MURADIN_RIFLEMAN); + _riflemanYellCooldown = time(NULL) + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_RIFLEMAN, 1000); + break; + case EVENT_CHECK_MORTAR: + if (_controller.SummonCreatures(SLOT_MORTAR_1, Is25ManRaid() ? SLOT_MORTAR_4 : SLOT_MORTAR_2)) + { + if (_mortarYellCooldown < time(NULL)) + { + Talk(SAY_MURADIN_MORTAR); + _mortarYellCooldown = time(NULL) + 5; + } + } + _events.ScheduleEvent(EVENT_CHECK_MORTAR, 1000); + break; + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 10000)); + break; + default: + break; + } + } + + if (me->IsWithinMeleeRange(me->GetVictim())) + DoMeleeAttackIfReady(); + else if (me->isAttackReady()) + { + DoCastVictim(SPELL_RENDING_THROW); + me->resetAttackTimer(); + } + } + + bool CanAIAttack(Unit const* target) const OVERRIDE + { + return target->HasAura(SPELL_ON_SKYBREAKER_DECK) || !target->IsControlledByPlayer(); + } + + private: + EventMap _events; + PassengerController _controller; + InstanceScript* _instance; + time_t _firstMageCooldown; + time_t _riflemanYellCooldown; + time_t _mortarYellCooldown; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI<npc_muradin_bronzebeard_igbAI>(creature); + } +}; + +class npc_zafod_boombox : public CreatureScript +{ + public: + npc_zafod_boombox() : CreatureScript("npc_zafod_boombox") { } + + struct npc_zafod_boomboxAI : public gunship_npc_AI + { + npc_zafod_boomboxAI(Creature* creature) : gunship_npc_AI(creature) + { + } + + void Reset() OVERRIDE + { + me->SetReactState(REACT_PASSIVE); + } + + void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) OVERRIDE + { + player->AddItem(ITEM_GOBLIN_ROCKET_PACK, 1); + player->PlayerTalkClass->SendCloseGossip(); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + UpdateVictim(); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI<npc_zafod_boomboxAI>(creature); + } +}; + +struct npc_gunship_boarding_addAI : public gunship_npc_AI +{ + npc_gunship_boarding_addAI(Creature* creature) : gunship_npc_AI(creature) + { + me->m_CombatDistance = 80.0f; + _usedDesperateResolve = false; + } + + void SetData(uint32 type, uint32 data) OVERRIDE + { + // detach from captain + if (type == ACTION_SET_SLOT) + { + SetSlotInfo(data); + + me->SetReactState(REACT_PASSIVE); + + me->m_Events.AddEvent(new DelayedMovementEvent(me, Slot->TargetPosition), me->m_Events.CalculateTime(3000 * (Index - SLOT_MARINE_1))); + + if (Creature* captain = me->FindNearestCreature(Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? NPC_IGB_MURADIN_BRONZEBEARD : NPC_IGB_HIGH_OVERLORD_SAURFANG, 200.0f)) + captain->AI()->SetData(ACTION_CLEAR_SLOT, Index); + } + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == EVENT_CHARGE_PREPATH && Slot) + { + Position const& otherTransportPos = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? OrgrimsHammerTeleportExit : SkybreakerTeleportExit; + float x, y, z, o; + otherTransportPos.GetPosition(x, y, z, o); + + Transport* myTransport = me->GetTransport(); + if (!myTransport) + return; + + if (GameObject* go = HashMapHolder<GameObject>::Find(Instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE))) + if (Transport* destTransport = go->ToTransport()) + destTransport->CalculatePassengerPosition(x, y, z, &o); + + float angle = frand(0, M_PI * 2.0f); + x += 2.0f * std::cos(angle); + y += 2.0f * std::sin(angle); + + me->SetHomePosition(x, y, z, o); + myTransport->CalculatePassengerOffset(x, y, z, &o); + me->SetTransportHomePosition(x, y, z, o); + + me->m_Events.AddEvent(new BattleExperienceEvent(me), me->m_Events.CalculateTime(BattleExperienceEvent::ExperiencedTimes[0])); + DoCast(me, SPELL_BATTLE_EXPERIENCE, true); + DoCast(me, SPELL_TELEPORT_TO_ENEMY_SHIP, true); + DoCast(me, Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_MELEE_TARGETING_ON_ORGRIMS_HAMMER : SPELL_MELEE_TARGETING_ON_SKYBREAKER, true); + me->_AddCreatureSpellCooldown(BurningPitchId, time(NULL) + 3); + + std::list<Player*> players; + Trinity::UnitAuraCheck check(true, Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_ON_ORGRIMS_HAMMER_DECK : SPELL_ON_SKYBREAKER_DECK); + Trinity::PlayerListSearcher<Trinity::UnitAuraCheck> searcher(me, players, check); + me->VisitNearbyWorldObject(200.0f, searcher); + + players.remove_if([this](Player* player) + { + return !me->_IsTargetAcceptable(player) || !me->CanStartAttack(player, true); + }); + + if (!players.empty()) + { + players.sort(Trinity::ObjectDistanceOrderPred(me)); + for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr) + me->AddThreat(*itr, 1.0f); + + AttackStart(players.front()); + } + + me->SetReactState(REACT_AGGRESSIVE); + } + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE + { + if (_usedDesperateResolve) + return; + + if (!me->HealthBelowPctDamaged(25, damage)) + return; + + _usedDesperateResolve = true; + DoCast(me, SPELL_DESPERATE_RESOLVE, true); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + if (!SelectVictim()) + { + TriggerBurningPitch(); + return; + } + + if (!HasAttackablePlayerNearby()) + TriggerBurningPitch(); + + DoMeleeAttackIfReady(); + } + + bool CanAIAttack(Unit const* target) const OVERRIDE + { + uint32 spellId = SPELL_ON_SKYBREAKER_DECK; + uint32 creatureEntry = NPC_IGB_MURADIN_BRONZEBEARD; + if (Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) + { + spellId = SPELL_ON_ORGRIMS_HAMMER_DECK; + creatureEntry = NPC_IGB_HIGH_OVERLORD_SAURFANG; + } + + return target->HasAura(spellId) || target->GetEntry() == creatureEntry; + } + + bool HasAttackablePlayerNearby() + { + std::list<Player*> players; + Trinity::UnitAuraCheck check(true, Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_ON_ORGRIMS_HAMMER_DECK : SPELL_ON_SKYBREAKER_DECK); + Trinity::PlayerListSearcher<Trinity::UnitAuraCheck> searcher(me, players, check); + me->VisitNearbyWorldObject(200.0f, searcher); + + players.remove_if([this](Player* player) + { + return !me->_IsTargetAcceptable(player) || !me->CanStartAttack(player, true); + }); + + return !players.empty(); + } + +private: + bool _usedDesperateResolve; +}; + +class npc_gunship_boarding_leader : public CreatureScript +{ + public: + npc_gunship_boarding_leader() : CreatureScript("npc_gunship_boarding_leader") { } + + struct npc_gunship_boarding_leaderAI : public npc_gunship_boarding_addAI + { + npc_gunship_boarding_leaderAI(Creature* creature) : npc_gunship_boarding_addAI(creature) + { + } + + void EnterCombat(Unit* target) OVERRIDE + { + npc_gunship_boarding_addAI::EnterCombat(target); + _events.ScheduleEvent(EVENT_BLADESTORM, urand(13000, 18000)); + _events.ScheduleEvent(EVENT_WOUNDING_STRIKE, urand(8000, 10000)); + } + + void UpdateAI(uint32 diff) OVERRIDE + { + if (!SelectVictim()) + { + TriggerBurningPitch(); + return; + } + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_BLADESTORM)) + return; + + if (!HasAttackablePlayerNearby()) + TriggerBurningPitch(); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BLADESTORM: + DoCastAOE(SPELL_BLADESTORM); + _events.ScheduleEvent(EVENT_BLADESTORM, urand(25000, 30000)); + break; + case EVENT_WOUNDING_STRIKE: + DoCastVictim(SPELL_WOUNDING_STRIKE); + _events.ScheduleEvent(EVENT_WOUNDING_STRIKE, urand(9000, 13000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap _events; + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI<npc_gunship_boarding_leaderAI>(creature); + } +}; + +class npc_gunship_boarding_add : public CreatureScript +{ + public: + npc_gunship_boarding_add() : CreatureScript("npc_gunship_boarding_add") { } + + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI<npc_gunship_boarding_addAI>(creature); + } +}; + +class npc_gunship_gunner : public CreatureScript +{ + public: + npc_gunship_gunner() : CreatureScript("npc_gunship_gunner") { } + + struct npc_gunship_gunnerAI : public gunship_npc_AI + { + npc_gunship_gunnerAI(Creature* creature) : gunship_npc_AI(creature) + { + creature->m_CombatDistance = 200.0f; + } + + void AttackStart(Unit* target) OVERRIDE + { + me->Attack(target, false); + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + gunship_npc_AI::MovementInform(type, pointId); + if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH) + me->SetControlled(true, UNIT_STATE_ROOT); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + if (!SelectVictim()) + { + TriggerBurningPitch(); + return; + } + + DoSpellAttackIfReady(me->GetEntry() == NPC_SKYBREAKER_RIFLEMAN ? SPELL_SHOOT : SPELL_HURL_AXE); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI<npc_gunship_gunnerAI>(creature); + } +}; + +class npc_gunship_rocketeer : public CreatureScript +{ + public: + npc_gunship_rocketeer() : CreatureScript("npc_gunship_rocketeer") { } + + struct npc_gunship_rocketeerAI : public gunship_npc_AI + { + npc_gunship_rocketeerAI(Creature* creature) : gunship_npc_AI(creature) + { + creature->m_CombatDistance = 200.0f; + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + gunship_npc_AI::MovementInform(type, pointId); + if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH) + me->SetControlled(true, UNIT_STATE_ROOT); + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + if (!SelectVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + uint32 spellId = me->GetEntry() == NPC_SKYBREAKER_MORTAR_SOLDIER ? SPELL_ROCKET_ARTILLERY_A : SPELL_ROCKET_ARTILLERY_H; + if (me->HasSpellCooldown(spellId)) + return; + + DoCastAOE(spellId, true); + me->_AddCreatureSpellCooldown(spellId, time(NULL) + 9); + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI<npc_gunship_rocketeerAI>(creature); + } +}; + +class npc_gunship_mage : public CreatureScript +{ + public: + npc_gunship_mage() : CreatureScript("npc_gunship_mage") { } + + struct npc_gunship_mageAI : public gunship_npc_AI + { + npc_gunship_mageAI(Creature* creature) : gunship_npc_AI(creature) + { + me->SetReactState(REACT_PASSIVE); + } + + void EnterEvadeMode() OVERRIDE + { + ScriptedAI::EnterEvadeMode(); + } + + void MovementInform(uint32 type, uint32 pointId) OVERRIDE + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId == EVENT_CHARGE_PREPATH && Slot) + { + SlotInfo const* slots = Instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SkybreakerSlotInfo : OrgrimsHammerSlotInfo; + me->SetFacingTo(slots[Index].TargetPosition.GetOrientation()); + switch (Index) + { + case SLOT_FREEZE_MAGE: + DoCastAOE(SPELL_BELOW_ZERO); + break; + case SLOT_MAGE_1: + case SLOT_MAGE_2: + DoCastAOE(SPELL_SHADOW_CHANNELING); + break; + default: + break; + } + + me->SetControlled(true, UNIT_STATE_ROOT); + } + } + + void UpdateAI(uint32 /*diff*/) OVERRIDE + { + UpdateVictim(); + } + + bool CanAIAttack(Unit const* /*target*/) const OVERRIDE + { + return true; + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return GetIcecrownCitadelAI<npc_gunship_mageAI>(creature); + } +}; + +/** @HACK This AI only resets MOVEMENTFLAG_ROOT on the vehicle. + Currently the core always removes MOVEMENTFLAG_ROOT sent from client packets to prevent cheaters from freezing clients of other players + but it actually is a valid flag - needs more research to fix both freezes and keep the flag as is (see WorldSession::ReadMovementInfo) + +Example packet: +ClientToServer: CMSG_FORCE_MOVE_ROOT_ACK (0x00E9) Length: 67 ConnectionIndex: 0 Time: 03/04/2010 03:57:55.000 Number: 471326 +Guid: +Movement Counter: 80 +Movement Flags: OnTransport, Root (2560) +Extra Movement Flags: None (0) +Time: 52291611 +Position: X: -396.0302 Y: 2482.906 Z: 249.86 +Orientation: 1.468665 +Transport GUID: Full: 0x1FC0000000000460 Type: MOTransport Low: 1120 +Transport Position: X: -6.152398 Y: -23.49037 Z: 21.64464 O: 4.827727 +Transport Time: 9926 +Transport Seat: 255 +Fall Time: 824 +*/ +class npc_gunship_cannon : public CreatureScript +{ + public: + npc_gunship_cannon() : CreatureScript("npc_gunship_cannon") { } + + struct npc_gunship_cannonAI : public PassiveAI + { + npc_gunship_cannonAI(Creature* creature) : PassiveAI(creature) + { + } + + void OnCharmed(bool /*apply*/) OVERRIDE { } + + void PassengerBoarded(Unit* /*passenger*/, int8 /*seat*/, bool apply) OVERRIDE + { + if (!apply) + { + me->SetControlled(false, UNIT_STATE_ROOT); + me->SetControlled(true, UNIT_STATE_ROOT); + } + } + }; + + CreatureAI* GetAI(Creature* creature) const OVERRIDE + { + return new npc_gunship_cannonAI(creature); + } +}; + +class spell_igb_rocket_pack : public SpellScriptLoader +{ + public: + spell_igb_rocket_pack() : SpellScriptLoader("spell_igb_rocket_pack") { } + + class spell_igb_rocket_pack_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_rocket_pack_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE + { + if (!sSpellMgr->GetSpellInfo(SPELL_ROCKET_PACK_DAMAGE) || + !sSpellMgr->GetSpellInfo(SPELL_ROCKET_BURST)) + return false; + + return true; + } + + void HandlePeriodic(AuraEffect const* /*aurEff*/) + { + if (GetTarget()->movespline->Finalized()) + Remove(AURA_REMOVE_BY_EXPIRE); + } + + void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + SpellInfo const* damageInfo = sSpellMgr->GetSpellInfo(SPELL_ROCKET_PACK_DAMAGE); + GetTarget()->CastCustomSpell(SPELL_ROCKET_PACK_DAMAGE, SPELLVALUE_BASE_POINT0, 2 * (damageInfo->Effects[EFFECT_0].CalcValue() + aurEff->GetTickNumber() * aurEff->GetAmplitude()), NULL, TRIGGERED_FULL_MASK); + GetTarget()->CastSpell(NULL, SPELL_ROCKET_BURST, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_igb_rocket_pack_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + OnEffectRemove += AuraEffectRemoveFn(spell_igb_rocket_pack_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_rocket_pack_AuraScript(); + } +}; + +class spell_igb_rocket_pack_useable : public SpellScriptLoader +{ + public: + spell_igb_rocket_pack_useable() : SpellScriptLoader("spell_igb_rocket_pack_useable") { } + + class spell_igb_rocket_pack_useable_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_rocket_pack_useable_AuraScript); + + bool Load() + { + return GetOwner()->GetInstanceScript(); + } + + bool CheckAreaTarget(Unit* target) + { + return target->GetTypeId() == TYPEID_PLAYER && GetOwner()->GetInstanceScript()->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* owner = GetOwner()->ToCreature()) + if (Player* target = GetTarget()->ToPlayer()) + if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1)) + sCreatureTextMgr->SendChat(owner, SAY_ZAFOD_ROCKET_PACK_ACTIVE, target, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, target); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* owner = GetOwner()->ToCreature()) + if (Player* target = GetTarget()->ToPlayer()) + if (target->HasItemCount(ITEM_GOBLIN_ROCKET_PACK, 1)) + sCreatureTextMgr->SendChat(owner, SAY_ZAFOD_ROCKET_PACK_DISABLED, target, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, target); + } + + void Register() OVERRIDE + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_igb_rocket_pack_useable_AuraScript::CheckAreaTarget); + AfterEffectApply += AuraEffectApplyFn(spell_igb_rocket_pack_useable_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_igb_rocket_pack_useable_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_rocket_pack_useable_AuraScript(); + } +}; + +class spell_igb_on_gunship_deck : public SpellScriptLoader +{ + public: + spell_igb_on_gunship_deck() : SpellScriptLoader("spell_igb_on_gunship_deck") { } + + class spell_igb_on_gunship_deck_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_on_gunship_deck_AuraScript); + + bool Load() OVERRIDE + { + if (InstanceScript* instance = GetOwner()->GetInstanceScript()) + _teamInInstance = instance->GetData(DATA_TEAM_IN_INSTANCE); + else + _teamInInstance = 0; + return true; + } + + bool CheckAreaTarget(Unit* unit) + { + return unit->GetTypeId() == TYPEID_PLAYER; + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetSpellInfo()->Id == uint32(_teamInInstance == HORDE ? SPELL_ON_SKYBREAKER_DECK : SPELL_ON_ORGRIMS_HAMMER_DECK)) + if (Creature* gunship = GetOwner()->FindNearestCreature(_teamInInstance == HORDE ? NPC_ORGRIMS_HAMMER : NPC_THE_SKYBREAKER, 200.0f)) + gunship->AI()->SetGUID(GetTarget()->GetGUID(), ACTION_SHIP_VISITS); + } + + void Register() OVERRIDE + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_igb_on_gunship_deck_AuraScript::CheckAreaTarget); + AfterEffectApply += AuraEffectApplyFn(spell_igb_on_gunship_deck_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } + + uint32 _teamInInstance; + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_on_gunship_deck_AuraScript(); + } +}; + +class spell_igb_periodic_trigger_with_power_cost : public SpellScriptLoader +{ + public: + spell_igb_periodic_trigger_with_power_cost() : SpellScriptLoader("spell_igb_periodic_trigger_with_power_cost") { } + + class spell_igb_periodic_trigger_with_power_cost_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_periodic_trigger_with_power_cost_AuraScript); + + void HandlePeriodicTick(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST)); + } + + void Register() OVERRIDE + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_igb_periodic_trigger_with_power_cost_AuraScript::HandlePeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_periodic_trigger_with_power_cost_AuraScript(); + } +}; + +class spell_igb_cannon_blast : public SpellScriptLoader +{ + public: + spell_igb_cannon_blast() : SpellScriptLoader("spell_igb_cannon_blast") { } + + class spell_igb_cannon_blast_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_cannon_blast_SpellScript); + + bool Load() + { + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void CheckEnergy() + { + if (GetCaster()->GetPower(POWER_ENERGY) >= 100) + { + GetCaster()->CastSpell(GetCaster(), SPELL_OVERHEAT, TRIGGERED_FULL_MASK); + if (Vehicle* vehicle = GetCaster()->GetVehicleKit()) + if (Unit* passenger = vehicle->GetPassenger(0)) + sCreatureTextMgr->SendChat(GetCaster()->ToCreature(), SAY_OVERHEAT, passenger); + } + } + + void Register() OVERRIDE + { + AfterHit += SpellHitFn(spell_igb_cannon_blast_SpellScript::CheckEnergy); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_cannon_blast_SpellScript(); + } +}; + +class spell_igb_incinerating_blast : public SpellScriptLoader +{ + public: + spell_igb_incinerating_blast() : SpellScriptLoader("spell_igb_incinerating_blast") { } + + class spell_igb_incinerating_blast_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_incinerating_blast_SpellScript); + + void StoreEnergy() + { + _energyLeft = GetCaster()->GetPower(POWER_ENERGY) - 10; + } + + void RemoveEnergy() + { + GetCaster()->SetPower(POWER_ENERGY, 0); + } + + void CalculateDamage(SpellEffIndex /*effIndex*/) + { + SetEffectValue(GetEffectValue() + _energyLeft * _energyLeft * 8); + } + + void Register() OVERRIDE + { + OnCast += SpellCastFn(spell_igb_incinerating_blast_SpellScript::StoreEnergy); + AfterCast += SpellCastFn(spell_igb_incinerating_blast_SpellScript::RemoveEnergy); + OnEffectLaunchTarget += SpellEffectFn(spell_igb_incinerating_blast_SpellScript::CalculateDamage, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE); + } + + uint32 _energyLeft; + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_incinerating_blast_SpellScript(); + } +}; + +class spell_igb_overheat : public SpellScriptLoader +{ + public: + spell_igb_overheat() : SpellScriptLoader("spell_igb_overheat") { } + + class spell_igb_overheat_AuraScript : public AuraScript + { + PrepareAuraScript(spell_igb_overheat_AuraScript); + + bool Load() OVERRIDE + { + if (GetAura()->GetType() != UNIT_AURA_TYPE) + return false; + return GetUnitOwner()->IsVehicle(); + } + + void SendClientControl(uint8 value) + { + if (Vehicle* vehicle = GetUnitOwner()->GetVehicleKit()) + { + if (Unit* passenger = vehicle->GetPassenger(0)) + { + if (Player* player = passenger->ToPlayer()) + { + WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, GetUnitOwner()->GetPackGUID().size() + 1); + data.append(GetUnitOwner()->GetPackGUID()); + data << uint8(value); + player->GetSession()->SendPacket(&data); + } + } + } + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + SendClientControl(0); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + SendClientControl(1); + } + + void Register() OVERRIDE + { + AfterEffectApply += AuraEffectApplyFn(spell_igb_overheat_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_igb_overheat_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const OVERRIDE + { + return new spell_igb_overheat_AuraScript(); + } +}; + +class spell_igb_below_zero : public SpellScriptLoader +{ + public: + spell_igb_below_zero() : SpellScriptLoader("spell_igb_below_zero") { } + + class spell_igb_below_zero_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_below_zero_SpellScript); + + void RemovePassengers() + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_EJECT_ALL_PASSENGERS_BELOW_ZERO, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + BeforeHit += SpellHitFn(spell_igb_below_zero_SpellScript::RemovePassengers); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_below_zero_SpellScript(); + } +}; + +class spell_igb_teleport_to_enemy_ship : public SpellScriptLoader +{ + public: + spell_igb_teleport_to_enemy_ship() : SpellScriptLoader("spell_igb_teleport_to_enemy_ship") { } + + class spell_igb_teleport_to_enemy_ship_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_teleport_to_enemy_ship_SpellScript); + + void RelocateTransportOffset(SpellEffIndex /*effIndex*/) + { + WorldLocation const* dest = GetHitDest(); + Unit* target = GetHitUnit(); + if (!dest || !target || !target->GetTransport()) + return; + + float x, y, z, o; + dest->GetPosition(x, y, z, o); + target->GetTransport()->CalculatePassengerOffset(x, y, z, &o); + target->m_movementInfo.transport.pos.Relocate(x, y, z, o); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_igb_teleport_to_enemy_ship_SpellScript::RelocateTransportOffset, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_teleport_to_enemy_ship_SpellScript(); + } +}; + +class spell_igb_burning_pitch_selector : public SpellScriptLoader +{ + public: + spell_igb_burning_pitch_selector() : SpellScriptLoader("spell_igb_burning_pitch_selector") { } + + class spell_igb_burning_pitch_selector_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_burning_pitch_selector_SpellScript); + + void FilterTargets(std::list<WorldObject*>& targets) + { + uint32 team = HORDE; + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + team = instance->GetData(DATA_TEAM_IN_INSTANCE); + + targets.remove_if([team](WorldObject* target) -> bool + { + if (Transport* transport = target->GetTransport()) + return transport->GetEntry() != uint32(team == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A); + return true; + }); + + if (!targets.empty()) + { + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + } + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_NONE); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_burning_pitch_selector_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_igb_burning_pitch_selector_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_burning_pitch_selector_SpellScript(); + } +}; + +class spell_igb_burning_pitch : public SpellScriptLoader +{ + public: + spell_igb_burning_pitch() : SpellScriptLoader("spell_igb_burning_pitch") { } + + class spell_igb_burning_pitch_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_burning_pitch_SpellScript); + + void HandleDummy(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastCustomSpell(uint32(GetEffectValue()), SPELLVALUE_BASE_POINT0, 8000, NULL, TRIGGERED_FULL_MASK); + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_BURNING_PITCH, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + OnEffectHitTarget += SpellEffectFn(spell_igb_burning_pitch_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_burning_pitch_SpellScript(); + } +}; + +class spell_igb_rocket_artillery : public SpellScriptLoader +{ + public: + spell_igb_rocket_artillery() : SpellScriptLoader("spell_igb_rocket_artillery") { } + + class spell_igb_rocket_artillery_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_rocket_artillery_SpellScript); + + void SelectRandomTarget(std::list<WorldObject*>& targets) + { + if (!targets.empty()) + { + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()), TRIGGERED_NONE); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_rocket_artillery_SpellScript::SelectRandomTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_igb_rocket_artillery_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_rocket_artillery_SpellScript(); + } +}; + +class spell_igb_rocket_artillery_explosion : public SpellScriptLoader +{ + public: + spell_igb_rocket_artillery_explosion() : SpellScriptLoader("spell_igb_rocket_artillery_explosion") { } + + class spell_igb_rocket_artillery_explosion_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_rocket_artillery_explosion_SpellScript); + + void DamageGunship(SpellEffIndex /*effIndex*/) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + GetCaster()->CastCustomSpell(instance->GetData(DATA_TEAM_IN_INSTANCE) == HORDE ? SPELL_BURNING_PITCH_DAMAGE_A : SPELL_BURNING_PITCH_DAMAGE_H, SPELLVALUE_BASE_POINT0, 5000, NULL, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + OnEffectHit += SpellEffectFn(spell_igb_rocket_artillery_explosion_SpellScript::DamageGunship, EFFECT_0, SPELL_EFFECT_TRIGGER_MISSILE); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_rocket_artillery_explosion_SpellScript(); + } +}; + +class spell_igb_gunship_fall_teleport : public SpellScriptLoader +{ + public: + spell_igb_gunship_fall_teleport() : SpellScriptLoader("spell_igb_gunship_fall_teleport") { } + + class spell_igb_gunship_fall_teleport_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_gunship_fall_teleport_SpellScript); + + bool Load() + { + return GetCaster()->GetInstanceScript(); + } + + void SelectTransport(WorldObject*& target) + { + if (InstanceScript* instance = target->GetInstanceScript()) + target = HashMapHolder<GameObject>::Find(instance->GetData64(DATA_ICECROWN_GUNSHIP_BATTLE)); + } + + void RelocateDest(SpellEffIndex /*effIndex*/) + { + if (GetCaster()->GetInstanceScript()->GetData(DATA_TEAM_IN_INSTANCE) == HORDE) + GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 36.0f, 0.0f }); + else + GetHitDest()->RelocateOffset({ 0.0f, 0.0f, 21.0f, 0.0f }); + } + + void Register() OVERRIDE + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_igb_gunship_fall_teleport_SpellScript::SelectTransport, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); + OnEffectLaunch += SpellEffectFn(spell_igb_gunship_fall_teleport_SpellScript::RelocateDest, EFFECT_0, SPELL_EFFECT_TELEPORT_UNITS); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_gunship_fall_teleport_SpellScript(); + } +}; + +class spell_igb_check_for_players : public SpellScriptLoader +{ + public: + spell_igb_check_for_players() : SpellScriptLoader("spell_igb_check_for_players") { } + + class spell_igb_check_for_players_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_check_for_players_SpellScript); + + bool Load() OVERRIDE + { + _playerCount = 0; + return GetCaster()->GetTypeId() == TYPEID_UNIT; + } + + void CountTargets(std::list<WorldObject*>& targets) + { + _playerCount = targets.size(); + } + + void TriggerWipe() + { + if (!_playerCount) + GetCaster()->ToCreature()->AI()->JustDied(NULL); + } + + void TeleportPlayer(SpellEffIndex /*effIndex*/) + { + if (GetHitUnit()->GetPositionZ() < GetCaster()->GetPositionZ() - 10.0f) + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_GUNSHIP_FALL_TELEPORT, TRIGGERED_FULL_MASK); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_check_for_players_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + AfterCast += SpellCastFn(spell_igb_check_for_players_SpellScript::TriggerWipe); + OnEffectHitTarget += SpellEffectFn(spell_igb_check_for_players_SpellScript::TeleportPlayer, EFFECT_0, SPELL_EFFECT_DUMMY); + } + + uint32 _playerCount; + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_check_for_players_SpellScript(); + } +}; + +class spell_igb_teleport_players_on_victory : public SpellScriptLoader +{ + public: + spell_igb_teleport_players_on_victory() : SpellScriptLoader("spell_igb_teleport_players_on_victory") { } + + class spell_igb_teleport_players_on_victory_SpellScript : public SpellScript + { + PrepareSpellScript(spell_igb_teleport_players_on_victory_SpellScript); + + bool Load() OVERRIDE + { + return GetCaster()->GetInstanceScript(); + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + InstanceScript* instance = GetCaster()->GetInstanceScript(); + targets.remove_if([instance](WorldObject* target) -> bool + { + return target->GetTransGUID() != instance->GetData64(DATA_ENEMY_GUNSHIP); + }); + } + + void Register() OVERRIDE + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_igb_teleport_players_on_victory_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_igb_teleport_players_on_victory_SpellScript(); + } +}; + +class achievement_im_on_a_boat : public AchievementCriteriaScript +{ + public: + achievement_im_on_a_boat() : AchievementCriteriaScript("achievement_im_on_a_boat") { } + + bool OnCheck(Player* /*source*/, Unit* target) OVERRIDE + { + return target->GetAI() && target->GetAI()->GetData(ACTION_SHIP_VISITS) <= 2; + } +}; + +void AddSC_boss_icecrown_gunship_battle() +{ + new npc_gunship(); + new npc_high_overlord_saurfang_igb(); + new npc_muradin_bronzebeard_igb(); + new npc_zafod_boombox(); + new npc_gunship_boarding_leader(); + new npc_gunship_boarding_add(); + new npc_gunship_gunner(); + new npc_gunship_rocketeer(); + new npc_gunship_mage(); + new npc_gunship_cannon(); + new spell_igb_rocket_pack(); + new spell_igb_rocket_pack_useable(); + new spell_igb_on_gunship_deck(); + new spell_igb_periodic_trigger_with_power_cost(); + new spell_igb_cannon_blast(); + new spell_igb_incinerating_blast(); + new spell_igb_overheat(); + new spell_igb_below_zero(); + new spell_igb_teleport_to_enemy_ship(); + new spell_igb_burning_pitch_selector(); + new spell_igb_burning_pitch(); + new spell_igb_rocket_artillery(); + new spell_igb_rocket_artillery_explosion(); + new spell_igb_gunship_fall_teleport(); + new spell_igb_check_for_players(); + new spell_igb_teleport_players_on_victory(); + new achievement_im_on_a_boat(); +} diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index b76e217fbf5..0d262110b5f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -2570,38 +2570,6 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader } }; -class spell_the_lich_king_eject_all_passengers : public SpellScriptLoader -{ - public: - spell_the_lich_king_eject_all_passengers() : SpellScriptLoader("spell_the_lich_king_eject_all_passengers") { } - - class spell_the_lich_king_eject_all_passengers_SpellScript : public SpellScript - { - PrepareSpellScript(spell_the_lich_king_eject_all_passengers_SpellScript); - - bool Load() OVERRIDE - { - return GetCaster()->IsVehicle(); - } - - void HandleDummy(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetCaster()->GetVehicleKit()->RemoveAllPassengers(); - } - - void Register() OVERRIDE - { - OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_eject_all_passengers_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; - - SpellScript* GetSpellScript() const OVERRIDE - { - return new spell_the_lich_king_eject_all_passengers_SpellScript(); - } -}; - class spell_the_lich_king_cast_back_to_caster : public SpellScriptLoader { public: @@ -3234,7 +3202,6 @@ void AddSC_boss_the_lich_king() new spell_the_lich_king_summon_into_air(); new spell_the_lich_king_soul_reaper(); new spell_the_lich_king_valkyr_target_search(); - new spell_the_lich_king_eject_all_passengers(); new spell_the_lich_king_cast_back_to_caster(); new spell_the_lich_king_life_siphon(); new spell_the_lich_king_vile_spirits(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h index 56a8a46811c..ba64107e618 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h @@ -76,7 +76,7 @@ enum DataTypes // Encounter States/Boss GUIDs DATA_LORD_MARROWGAR = 0, DATA_LADY_DEATHWHISPER = 1, - DATA_GUNSHIP_EVENT = 2, + DATA_ICECROWN_GUNSHIP_BATTLE = 2, DATA_DEATHBRINGER_SAURFANG = 3, DATA_FESTERGUT = 4, DATA_ROTFACE = 5, @@ -116,6 +116,7 @@ enum DataTypes DATA_HIGHLORD_TIRION_FORDRING = 37, DATA_ARTHAS_PLATFORM = 38, DATA_TERENAS_MENETHIL = 39, + DATA_ENEMY_GUNSHIP = 40 }; enum CreaturesIds @@ -169,6 +170,33 @@ enum CreaturesIds NPC_REANIMATED_ADHERENT = 38010, NPC_VENGEFUL_SHADE = 38222, + // Icecrown Gunship Battle + NPC_MARTYR_STALKER_IGB_SAURFANG = 38569, + NPC_ALLIANCE_GUNSHIP_CANNON = 36838, + NPC_HORDE_GUNSHIP_CANNON = 36839, + NPC_SKYBREAKER_DECKHAND = 36970, + NPC_ORGRIMS_HAMMER_CREW = 36971, + NPC_IGB_HIGH_OVERLORD_SAURFANG = 36939, + NPC_IGB_MURADIN_BRONZEBEARD = 36948, + NPC_THE_SKYBREAKER = 37540, + NPC_ORGRIMS_HAMMER = 37215, + NPC_GUNSHIP_HULL = 37547, + NPC_TELEPORT_PORTAL = 37227, + NPC_TELEPORT_EXIT = 37488, + NPC_SKYBREAKER_SORCERER = 37116, + NPC_SKYBREAKER_RIFLEMAN = 36969, + NPC_SKYBREAKER_MORTAR_SOLDIER = 36978, + NPC_SKYBREAKER_MARINE = 36950, + NPC_SKYBREAKER_SERGEANT = 36961, + NPC_KOR_KRON_BATTLE_MAGE = 37117, + NPC_KOR_KRON_AXETHROWER = 36968, + NPC_KOR_KRON_ROCKETEER = 36982, + NPC_KOR_KRON_REAVER = 36957, + NPC_KOR_KRON_SERGEANT = 36960, + NPC_ZAFOD_BOOMBOX = 37184, + NPC_HIGH_CAPTAIN_JUSTIN_BARTLETT = 37182, + NPC_SKY_REAVER_KORM_BLACKSCAR = 37833, + // Deathbringer Saurfang NPC_DEATHBRINGER_SAURFANG = 37813, NPC_BLOOD_BEAST = 38508, @@ -305,6 +333,22 @@ enum GameObjectsIds GO_ORATORY_OF_THE_DAMNED_ENTRANCE = 201563, GO_LADY_DEATHWHISPER_ELEVATOR = 202220, + // Icecrown Gunship Battle - Horde raid + GO_ORGRIMS_HAMMER_H = 201812, + GO_THE_SKYBREAKER_H = 201811, + GO_GUNSHIP_ARMORY_H_10N = 202178, + GO_GUNSHIP_ARMORY_H_25N = 202180, + GO_GUNSHIP_ARMORY_H_10H = 202177, + GO_GUNSHIP_ARMORY_H_25H = 202179, + + // Icecrown Gunship Battle - Alliance raid + GO_ORGRIMS_HAMMER_A = 201581, + GO_THE_SKYBREAKER_A = 201580, + GO_GUNSHIP_ARMORY_A_10N = 201873, + GO_GUNSHIP_ARMORY_A_25N = 201874, + GO_GUNSHIP_ARMORY_A_10H = 201872, + GO_GUNSHIP_ARMORY_A_25H = 201875, + // Deathbringer Saurfang GO_SAURFANG_S_DOOR = 201825, GO_DEATHBRINGER_S_CACHE_10N = 202239, @@ -408,6 +452,9 @@ enum AchievementCriteriaIds enum SharedActions { + // Icecrown Gunship Battle + ACTION_ENEMY_GUNSHIP_TALK = -369390, + // Festergut ACTION_FESTERGUT_COMBAT = -366260, ACTION_FESTERGUT_GAS = -366261, @@ -459,6 +506,7 @@ enum WorldStatesICC enum AreaIds { + AREA_ICECROWN_CITADEL = 4812, AREA_THE_FROZEN_THRONE = 4859 }; diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp index ad06bc1c485..b56e0dd6360 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel_teleport.cpp @@ -38,7 +38,7 @@ class icecrown_citadel_teleport : public GameObjectScript player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Oratory of the Damned.", GOSSIP_SENDER_ICC_PORT, ORATORY_OF_THE_DAMNED_TELEPORT); if (instance->GetBossState(DATA_LADY_DEATHWHISPER) == DONE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Rampart of Skulls.", GOSSIP_SENDER_ICC_PORT, RAMPART_OF_SKULLS_TELEPORT); - if (instance->GetBossState(DATA_GUNSHIP_EVENT) == DONE) + if (instance->GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Deathbringer's Rise.", GOSSIP_SENDER_ICC_PORT, DEATHBRINGER_S_RISE_TELEPORT); if (instance->GetData(DATA_COLDFLAME_JETS) == DONE) player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Teleport to the Upper Spire.", GOSSIP_SENDER_ICC_PORT, UPPER_SPIRE_TELEPORT); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index e2234fa5a20..bfacd6fafcc 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -15,20 +15,27 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ObjectMgr.h" -#include "ScriptMgr.h" +#include "AccountMgr.h" #include "InstanceScript.h" -#include "ScriptedCreature.h" #include "Map.h" -#include "PoolMgr.h" -#include "AccountMgr.h" -#include "icecrown_citadel.h" +#include "ObjectMgr.h" #include "Player.h" +#include "PoolMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Transport.h" +#include "TransportMgr.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "icecrown_citadel.h" enum EventIds { + EVENT_PLAYERS_GUNSHIP_SPAWN = 22663, + EVENT_PLAYERS_GUNSHIP_COMBAT = 22664, + EVENT_PLAYERS_GUNSHIP_SAURFANG = 22665, + EVENT_ENEMY_GUNSHIP_COMBAT = 22860, + EVENT_ENEMY_GUNSHIP_DESPAWN = 22861, EVENT_QUAKE = 23437, EVENT_SECOND_REMORSELESS_WINTER = 23507, EVENT_TELEPORT_TO_FROSTMOURNE = 23617 @@ -39,6 +46,7 @@ enum TimedEvents EVENT_UPDATE_EXECUTION_TIME = 1, EVENT_QUAKE_SHATTER = 2, EVENT_REBUILD_PLATFORM = 3, + EVENT_RESPAWN_GUNSHIP = 4 }; DoorData const doorData[] = @@ -106,6 +114,9 @@ class instance_icecrown_citadel : public InstanceMapScript TeamInInstance = 0; HeroicAttempts = MaxHeroicAttempts; LadyDeathwisperElevatorGUID = 0; + GunshipGUID = 0; + EnemyGunshipGUID = 0; + GunshipArmoryGUID = 0; DeathbringerSaurfangGUID = 0; DeathbringerSaurfangDoorGUID = 0; DeathbringerSaurfangEventGUID = 0; @@ -164,6 +175,9 @@ class instance_icecrown_citadel : public InstanceMapScript { if (!TeamInInstance) TeamInInstance = player->GetTeam(); + + if (GetBossState(DATA_LADY_DEATHWHISPER) == DONE && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE) + SpawnGunship(); } void OnCreatureCreate(Creature* creature) OVERRIDE @@ -217,6 +231,10 @@ class instance_icecrown_citadel : public InstanceMapScript case NPC_DEATHBRINGER_SAURFANG: DeathbringerSaurfangGUID = creature->GetGUID(); break; + case NPC_ALLIANCE_GUNSHIP_CANNON: + case NPC_HORDE_GUNSHIP_CANNON: + creature->SetControlled(true, UNIT_STATE_ROOT); + break; case NPC_SE_HIGH_OVERLORD_SAURFANG: if (TeamInInstance == ALLIANCE) creature->UpdateEntry(NPC_SE_MURADIN_BRONZEBEARD, ALLIANCE, creature->GetCreatureData()); @@ -341,6 +359,54 @@ class instance_icecrown_citadel : public InstanceMapScript } break; } + case NPC_HORDE_GUNSHIP_CANNON: + case NPC_ORGRIMS_HAMMER_CREW: + case NPC_SKY_REAVER_KORM_BLACKSCAR: + if (TeamInInstance == ALLIANCE) + return 0; + break; + case NPC_ALLIANCE_GUNSHIP_CANNON: + case NPC_SKYBREAKER_DECKHAND: + case NPC_HIGH_CAPTAIN_JUSTIN_BARTLETT: + if (TeamInInstance == HORDE) + return 0; + break; + case NPC_ZAFOD_BOOMBOX: + if (GameObjectTemplate const* go = sObjectMgr->GetGameObjectTemplate(GO_THE_SKYBREAKER_A)) + if ((TeamInInstance == ALLIANCE && data->mapid == go->moTransport.mapID) || + (TeamInInstance == HORDE && data->mapid != go->moTransport.mapID)) + return entry; + return 0; + case NPC_IGB_MURADIN_BRONZEBEARD: + if ((TeamInInstance == ALLIANCE && data->posX > 10.0f) || + (TeamInInstance == HORDE && data->posX < 10.0f)) + return entry; + return 0; + default: + break; + } + + return entry; + } + + uint32 GetGameObjectEntry(uint32 /*guidLow*/, uint32 entry) OVERRIDE + { + switch (entry) + { + case GO_GUNSHIP_ARMORY_H_10N: + case GO_GUNSHIP_ARMORY_H_25N: + case GO_GUNSHIP_ARMORY_H_10H: + case GO_GUNSHIP_ARMORY_H_25H: + if (TeamInInstance == ALLIANCE) + return 0; + break; + case GO_GUNSHIP_ARMORY_A_10N: + case GO_GUNSHIP_ARMORY_A_25N: + case GO_GUNSHIP_ARMORY_A_10H: + case GO_GUNSHIP_ARMORY_A_25H: + if (TeamInInstance == HORDE) + return 0; + break; default: break; } @@ -446,6 +512,20 @@ class instance_icecrown_citadel : public InstanceMapScript go->SetGoState(GO_STATE_READY); } break; + case GO_THE_SKYBREAKER_H: + case GO_ORGRIMS_HAMMER_A: + EnemyGunshipGUID = go->GetGUID(); + break; + case GO_GUNSHIP_ARMORY_H_10N: + case GO_GUNSHIP_ARMORY_H_25N: + case GO_GUNSHIP_ARMORY_H_10H: + case GO_GUNSHIP_ARMORY_H_25H: + case GO_GUNSHIP_ARMORY_A_10N: + case GO_GUNSHIP_ARMORY_A_25N: + case GO_GUNSHIP_ARMORY_A_10H: + case GO_GUNSHIP_ARMORY_A_25H: + GunshipArmoryGUID = go->GetGUID(); + break; case GO_SAURFANG_S_DOOR: DeathbringerSaurfangDoorGUID = go->GetGUID(); AddDoor(go, true); @@ -587,6 +667,10 @@ class instance_icecrown_citadel : public InstanceMapScript case GO_ICE_WALL: AddDoor(go, false); break; + case GO_THE_SKYBREAKER_A: + case GO_ORGRIMS_HAMMER_H: + GunshipGUID = 0; + break; default: break; } @@ -621,6 +705,10 @@ class instance_icecrown_citadel : public InstanceMapScript { switch (type) { + case DATA_ICECROWN_GUNSHIP_BATTLE: + return GunshipGUID; + case DATA_ENEMY_GUNSHIP: + return EnemyGunshipGUID; case DATA_DEATHBRINGER_SAURFANG: return DeathbringerSaurfangGUID; case DATA_SAURFANG_EVENT_NPC: @@ -691,7 +779,7 @@ class instance_icecrown_citadel : public InstanceMapScript switch (type) { case DATA_LADY_DEATHWHISPER: - SetBossState(DATA_GUNSHIP_EVENT, state); // TEMP HACK UNTIL GUNSHIP SCRIPTED + { if (state == DONE) { if (GameObject* elevator = instance->GetGameObject(LadyDeathwisperElevatorGUID)) @@ -699,8 +787,20 @@ class instance_icecrown_citadel : public InstanceMapScript elevator->SetUInt32Value(GAMEOBJECT_LEVEL, 0); elevator->SetGoState(GO_STATE_READY); } + + SpawnGunship(); } break; + } + case DATA_ICECROWN_GUNSHIP_BATTLE: + if (state == DONE) + { + if (GameObject* loot = instance->GetGameObject(GunshipArmoryGUID)) + loot->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN); + } + else if (state == FAIL) + Events.ScheduleEvent(EVENT_RESPAWN_GUNSHIP, 30000); + break; case DATA_DEATHBRINGER_SAURFANG: switch (state) { @@ -846,6 +946,17 @@ class instance_icecrown_citadel : public InstanceMapScript return true; } + void SpawnGunship() + { + if (!GunshipGUID) + { + SetBossState(DATA_ICECROWN_GUNSHIP_BATTLE, NOT_STARTED); + uint32 gunshipEntry = TeamInInstance == HORDE ? GO_ORGRIMS_HAMMER_H : GO_THE_SKYBREAKER_A; + if (Transport* gunship = sTransportMgr->CreateTransport(gunshipEntry, 0, instance)) + GunshipGUID = gunship->GetGUID(); + } + } + void SetData(uint32 type, uint32 data) OVERRIDE { switch (type) @@ -1066,10 +1177,10 @@ class instance_icecrown_citadel : public InstanceMapScript return false; // no break case DATA_DEATHBRINGER_SAURFANG: - if (GetBossState(DATA_GUNSHIP_EVENT) != DONE) + if (GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != DONE) return false; // no break - case DATA_GUNSHIP_EVENT: + case DATA_ICECROWN_GUNSHIP_BATTLE: if (GetBossState(DATA_LADY_DEATHWHISPER) != DONE) return false; // no break @@ -1163,7 +1274,7 @@ class instance_icecrown_citadel : public InstanceMapScript void Update(uint32 diff) OVERRIDE { - if (BloodQuickeningState != IN_PROGRESS && GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS) + if (BloodQuickeningState != IN_PROGRESS && GetBossState(DATA_THE_LICH_KING) != IN_PROGRESS && GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) != FAIL) return; Events.Update(diff); @@ -1213,16 +1324,34 @@ class instance_icecrown_citadel : public InstanceMapScript if (GameObject* wind = instance->GetGameObject(FrozenThroneWindGUID)) wind->SetGoState(GO_STATE_ACTIVE); break; + case EVENT_RESPAWN_GUNSHIP: + SpawnGunship(); + break; default: break; } } } - void ProcessEvent(WorldObject* /*source*/, uint32 eventId) OVERRIDE + void ProcessEvent(WorldObject* source, uint32 eventId) OVERRIDE { switch (eventId) { + case EVENT_ENEMY_GUNSHIP_DESPAWN: + if (GetBossState(DATA_ICECROWN_GUNSHIP_BATTLE) == DONE) + source->AddObjectToRemoveList(); + break; + case EVENT_ENEMY_GUNSHIP_COMBAT: + if (Creature* captain = source->FindNearestCreature(TeamInInstance == HORDE ? NPC_IGB_HIGH_OVERLORD_SAURFANG : NPC_IGB_MURADIN_BRONZEBEARD, 100.0f)) + captain->AI()->DoAction(ACTION_ENEMY_GUNSHIP_TALK); + // no break; + case EVENT_PLAYERS_GUNSHIP_SPAWN: + case EVENT_PLAYERS_GUNSHIP_COMBAT: + case EVENT_PLAYERS_GUNSHIP_SAURFANG: + if (GameObject* go = source->ToGameObject()) + if (Transport* transport = go->ToTransport()) + transport->EnableMovement(false); + break; case EVENT_QUAKE: if (GameObject* warning = instance->GetGameObject(FrozenThroneWarningGUID)) warning->SetGoState(GO_STATE_ACTIVE); @@ -1261,6 +1390,9 @@ class instance_icecrown_citadel : public InstanceMapScript protected: EventMap Events; uint64 LadyDeathwisperElevatorGUID; + uint64 GunshipGUID; + uint64 EnemyGunshipGUID; + uint64 GunshipArmoryGUID; uint64 DeathbringerSaurfangGUID; uint64 DeathbringerSaurfangDoorGUID; uint64 DeathbringerSaurfangEventGUID; // Muradin Bronzebeard or High Overlord Saurfang diff --git a/src/server/scripts/Northrend/zone_storm_peaks.cpp b/src/server/scripts/Northrend/zone_storm_peaks.cpp index 84cf02cfe13..bd80de627a8 100644 --- a/src/server/scripts/Northrend/zone_storm_peaks.cpp +++ b/src/server/scripts/Northrend/zone_storm_peaks.cpp @@ -792,37 +792,6 @@ class spell_veranus_summon : public SpellScriptLoader } }; -/*##### -# spell_jokkum_eject_all -#####*/ - -class spell_jokkum_eject_all : public SpellScriptLoader -{ - public: spell_jokkum_eject_all() : SpellScriptLoader("spell_jokkum_eject_all") { } - - class spell_jokkum_eject_all_SpellScript : public SpellScript - { - PrepareSpellScript(spell_jokkum_eject_all_SpellScript); - - void HandleScriptEffect(SpellEffIndex /* effIndex */) - { - if (Unit* caster = GetCaster()) - if (caster->IsVehicle()) - caster->GetVehicleKit()->RemoveAllPassengers(); - } - - void Register() OVERRIDE - { - OnEffectHitTarget += SpellEffectFn(spell_jokkum_eject_all_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; - - SpellScript* GetSpellScript() const OVERRIDE - { - return new spell_jokkum_eject_all_SpellScript(); - } -}; - enum CloseRift { SPELL_DESPAWN_RIFT = 61665 @@ -882,6 +851,5 @@ void AddSC_storm_peaks() new npc_king_jokkum_vehicle(); new spell_jokkum_scriptcast(); new spell_veranus_summon(); - new spell_jokkum_eject_all(); new spell_close_rift(); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index 1e9a8713019..9a81582b0b9 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -36,6 +36,7 @@ #include "SkillDiscovery.h" #include "SpellScript.h" #include "SpellAuraEffects.h" +#include "Vehicle.h" class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader { @@ -3673,6 +3674,33 @@ class spell_gen_whisper_gulch_yogg_saron_whisper : public SpellScriptLoader } }; +class spell_gen_eject_all_passengers : public SpellScriptLoader +{ + public: + spell_gen_eject_all_passengers() : SpellScriptLoader("spell_gen_eject_all_passengers") { } + + class spell_gen_eject_all_passengers_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_eject_all_passengers_SpellScript); + + void RemoveVehicleAuras() + { + if (Vehicle* vehicle = GetHitUnit()->GetVehicleKit()) + vehicle->RemoveAllPassengers(); + } + + void Register() OVERRIDE + { + AfterHit += SpellHitFn(spell_gen_eject_all_passengers_SpellScript::RemoveVehicleAuras); + } + }; + + SpellScript* GetSpellScript() const OVERRIDE + { + return new spell_gen_eject_all_passengers_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -3754,4 +3782,5 @@ void AddSC_generic_spell_scripts() new spell_gen_vendor_bark_trigger(); new spell_gen_wg_water(); new spell_gen_whisper_gulch_yogg_saron_whisper(); + new spell_gen_eject_all_passengers(); } |