From d025a90a69a22cc20817adda5351739567a89f47 Mon Sep 17 00:00:00 2001 From: Stoabrogga <38475780+Stoabrogga@users.noreply.github.com> Date: Tue, 23 Jul 2019 00:21:24 +0200 Subject: [PATCH] fix(DB/CreatureScript): Deathblow to the Legion (#2080) * fix(DB/CreatureScript): Deathblow to the Legion * Implement the event which takes place during the "Deathblow to the Legion" quest. This is based on PR #1834 but had to be heavily modified as the original scripts contained many bugs and inconsistencies. --- .../rev_1562779174835710547.sql | 157 +++ .../scripts/Outland/zone_netherstorm.cpp | 1039 +++++++++++++++++ .../scripts/Outland/zone_shattrath_city.cpp | 78 ++ 3 files changed, 1274 insertions(+) create mode 100644 data/sql/updates/pending_db_world/rev_1562779174835710547.sql diff --git a/data/sql/updates/pending_db_world/rev_1562779174835710547.sql b/data/sql/updates/pending_db_world/rev_1562779174835710547.sql new file mode 100644 index 000000000..46b2f60b2 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1562779174835710547.sql @@ -0,0 +1,157 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1562779174835710547'); + +-- Remove Socrethar SAI Script for credit +DELETE FROM `smart_scripts` WHERE `entryorguid` = 20132 AND `source_type` = 0; + +-- Kaylaan 'kaylaan_the_lost' +DELETE FROM `creature` WHERE `id` = 20794; +DELETE FROM `creature_template` WHERE `entry` = 20794; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) +VALUES +(20794, 0, 0, 0, 0, 0, 19978, 0, 0, 0, 'Kaylaan the Lost', '', NULL, 0, 71, 71, 1, 35, 0, 1.2, 1.14286, 1, 1, 299, 426, 0, 308, 7.5, 2000, 2000, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 262, 389, 48, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 20, 6, 1, 0, 0, 1, 0, 0, 'kaylaan_the_lost', 0); + +-- Adyen 'adyen_the_lightbringer' +DELETE FROM `creature_template` WHERE `entry` = 61021; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) +VALUES +(61021, 0, 0, 0, 0, 0, 17881, 0, 0, 0, 'Adyen the Lightwarden', NULL, NULL, 61021, 71, 71, 1, 1806, 1, 1, 1.14286, 1, 1, 296, 424, 0, 290, 4.6, 2000, 2000, 2, 32768, 2048, 0, 0, 0, 0, 0, 0, 260, 387, 37, 7, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14518, 13005, 13952, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 1, 3, 1, 4, 1, 1, 0, 0, 1, 0, 0, 'adyen_the_lightbringer', 0); +DELETE FROM `creature_equip_template` WHERE `CreatureID` = 61021 AND `ID` = 1; +INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES (61021, 1, 24014, 0, 0, 18019); + +-- Orelis 'exarch_orelis' +DELETE FROM `creature_template` WHERE `entry` = 50002; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) +VALUES +(50002, 0, 0, 0, 0, 0, 20518, 0, 0, 0, 'Exarch Orelis', '', NULL, 8074, 69, 69, 1, 1806, 3, 1, 1.14286, 1, 0, 245, 346, 0, 298, 1, 2000, 2000, 1, 32768, 2048, 0, 0, 0, 0, 0, 0, 206, 302, 43, 10, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29426, 16509, 13730, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 1, 3, 1, 1, 1, 1, 0, 0, 1, 0, 0, 'exarch_orelis', 0); +DELETE FROM `creature_equip_template` WHERE `CreatureID` = 50002 AND `ID` = 1; +INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES (50002, 1, 28488, 0, 0, 18019); + +-- Karja 'anchorite_karja' +DELETE FROM `creature_template` WHERE `entry` = 50001; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) +VALUES +(50001, 0, 0, 0, 0, 0, 18903, 0, 0, 0, 'Anchorite Karja', NULL, NULL, 8112, 69, 69, 1, 1806, 3, 1, 1.14286, 1, 0, 224, 316, 0, 282, 1, 2000, 2000, 2, 32768, 2048, 0, 0, 0, 0, 0, 0, 188, 280, 32, 10, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 1, 3, 1, 1, 1, 1, 0, 0, 1, 0, 0, 'anchorite_karja', 0); +DELETE FROM `creature_equip_template` WHERE `CreatureID` = 50001 AND `ID` = 1; +INSERT INTO `creature_equip_template` (`CreatureID`, `ID`, `ItemID1`, `ItemID2`, `ItemID3`, `VerifiedBuild`) VALUES (50001, 1, 14873, 0, 0, 18019); + +-- trigger +DELETE FROM `creature_template` WHERE `entry` = 50004; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) +VALUES +(50004, 0, 0, 0, 0, 0, 17881, 0, 0, 0, 'Adyen Trigger', NULL, NULL, 0, 1, 1, 0, 1806, 1, 1, 1.14286, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 1, 1, 0, 0, 1, 0, 128, 'deathblow_to_the_legion_trigger', 0); +DELETE FROM `creature` WHERE `id` = 50004; +INSERT INTO `creature` (`id`, `map`, `modelid`, `position_x`, `position_y`, `position_z`, `orientation`) VALUES ('50004', '530', '17881', '4802.629883', '3775.419922', '210.529999', '5.490000'); + +-- Socrethar 'socrethar' +UPDATE `creature_template` SET `ScriptName` = 'socrethar', `faction` = 90, `flags_extra` = 2097152 WHERE `entry` = 20132; + +-- Ishanah 'npc_ishanah' +UPDATE `creature_template` SET `ScriptName` = 'npc_ishanah' WHERE `entry` = 18538; + +-- Orelis gossip text +DELETE FROM `gossip_menu` WHERE `MenuID` = 61021 AND `TextID` = 10210; +INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES (61021, 10210); +DELETE FROM `gossip_menu_option` WHERE `MenuID` = 61021 AND `OptionID` = 0; +INSERT INTO `gossip_menu_option` (`MenuID`, `OptionIcon`, `OptionText`, `BoxBroadcastTextID`) VALUES ('61021', '1', 'I''m ready, Adyen', 18591); + +-- Adyen waypath +DELETE FROM `waypoint_data` WHERE `id` = 610210; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(610210, 0, 4814.52, 3767.18, 210.535, 5.72712, 0, 0, 0, 100, 0), +(610210, 1, 4836.75, 3774.64, 207.521, 0.31875, 0, 0, 0, 100, 0), +(610210, 2, 4849.92, 3780.49, 203.479, 0.464049, 0, 0, 0, 100, 0), +(610210, 3, 4860.43, 3791.42, 199.593, 0.808459, 0, 0, 0, 100, 0), +(610210, 4, 4865.64, 3799.13, 199.073, 0.981247, 0, 0, 0, 100, 0), +(610210, 5, 4884.83, 3808.67, 198.972, 0.451103, 0, 0, 0, 100, 0), +(610210, 6, 4889.64, 3811.75, 202.37, 0.568913, 0, 0, 0, 100, 0), +(610210, 7, 4898.13, 3817.17, 208.018, 0.568913, 0, 0, 0, 100, 0), +(610210, 8, 4907.47, 3823.15, 211.487, 0.568913, 0, 0, 0, 100, 0), +(610210, 9, 4925.36, 3834.58, 211.494, 0.568913, 0, 0, 0, 100, 0); + +-- Karja waypath +DELETE FROM `waypoint_data` WHERE `id` = 500020; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(500020, 0, 4808.67, 3776.1, 210.545, 0.185895, 0, 0, 0, 100, 0), +(500020, 1, 4808.06, 3770.48, 210.535, 5.71456, 0, 0, 0, 100, 0), +(500020, 2, 4816.65, 3772.83, 210.533, 6.09434, 0, 0, 0, 100, 0), +(500020, 3, 4834.06, 3775.74, 207.883, 0.27454, 0, 0, 0, 100, 0), +(500020, 4, 4846.48, 3781.56, 204.363, 0.570994, 0, 0, 0, 100, 0), +(500020, 5, 4860.04, 3793.51, 199.55, 0.726503, 0, 0, 0, 100, 0), +(500020, 6, 4863.97, 3800.26, 199.238, 1.0438, 0, 0, 0, 100, 0), +(500020, 7, 4884.2, 3811.66, 198.972, 0.512874, 0, 0, 0, 100, 0), +(500020, 8, 4888.17, 3814.1, 202.375, 0.552144, 0, 0, 0, 100, 0), +(500020, 9, 4896.61, 3819.3, 207.936, 0.552144, 0, 0, 0, 100, 0), +(500020, 10, 4905.55, 3824.81, 211.406, 0.552144, 0, 0, 0, 100, 0), +(500020, 11, 4920.23, 3834.34, 211.51, 0.575706, 0, 0, 0, 100, 0); + +-- Orelis Waypath +DELETE FROM `waypoint_data` WHERE `id` = 500010; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(500010, 0, 4806.57, 3769.34, 210.538, 5.66707, 0, 0, 0, 100, 0), +(500010, 1, 4821.37, 3766.19, 210.374, 6.15008, 0, 0, 0, 100, 0), +(500010, 2, 4839.46, 3771.1, 207.53, 0.372697, 0, 0, 0, 100, 0), +(500010, 3, 4846.95, 3774.03, 206.033, 0.372697, 0, 0, 0, 100, 0), +(500010, 4, 4860.74, 3785.41, 200.083, 0.689998, 0, 0, 0, 100, 0), +(500010, 5, 4865.44, 3792.8, 199.435, 0.689998, 0, 0, 0, 100, 0), +(500010, 6, 4866.07, 3796.41, 199.129, 0.689998, 0, 0, 0, 100, 0), +(500010, 7, 4881.95, 3802.56, 198.972, 0.689998, 0, 0, 0, 100, 0), +(500010, 8, 4887.37, 3807.19, 198.972, 0.689998, 0, 0, 0, 100, 0), +(500010, 9, 4891.19, 3809.42, 202.444, 0.689998, 0, 0, 0, 100, 0), +(500010, 10, 4899.87, 3814.46, 208.038, 0.689998, 0, 0, 0, 100, 0), +(500010, 11, 4909.45, 3820.04, 211.488, 0.689998, 0, 0, 0, 100, 0), +(500010, 12, 4924.99, 3829.07, 211.494, 0.689998, 0, 0, 0, 100, 0); + +-- Kaylaan Waypath +DELETE FROM `waypoint_data` WHERE `id` = 207940 OR `id` = 207941 OR `id` = 207942; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(207940, 0, 4955.27, 3896.54, 211.923, 4.59521, 0, 0, 0, 100, 0), +(207940, 1, 4951.58, 3879.44, 212.116, 2.49311, 0, 0, 0, 100, 0), +(207940, 2, 4943.43, 3862.68, 211.598, 4.18681, 0, 0, 0, 100, 0), +(207940, 3, 4941.09, 3856.62, 211.498, 4.63841, 0, 0, 0, 100, 0), +(207940, 4, 4942.28, 3852.59, 211.464, 4.99969, 0, 0, 0, 100, 0), +(207941, 0, 4939.37, 3848.5, 211.503, 4.09257, 0, 0, 0, 100, 0), +(207942, 1, 4943.81, 3840.37, 211.511, 4.97614, 0, 0, 0, 100, 0), +(207942, 0, 4943.32, 3842.17, 211.505, 5.27066, 0, 0, 0, 100, 0); + +-- Ishanah Waypath +DELETE FROM `waypoint_data` WHERE `id` = 500050; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES +(500050, 0, 4937.61, 3832.38, 211.461, 0.534084, 0, 1, 0, 100, 0), +(500050, 1, 4941.01, 3835.17, 211.478, 0.687237, 0, 0, 0, 100, 0), +(500050, 2, 4941.84, 3836.43, 211.483, 0.993542, 0, 0, 0, 100, 0); + +-- Kaylaan Text +DELETE FROM `creature_text` WHERE `CreatureID` = 20794; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextID`, `TextRange`, `comment`) VALUES +(20794, 0, 0, 'My heart has been filled with hate since our sworn enemies were allowed into our city. I knew the one known as Voren''thal before he was called a Seer. It was by his hand that my brother was slain.', 12, 0, 100, 0, 0, 0, 18394, 0, ''), +(20794, 1, 0, 'I turned that hate on the Illidari and the Burning Legion... but they weren''t the ones who betrayed us. We were the naaru''s chosen! We lived and died for them!', 12, 0, 100, 0, 0, 0, 18395, 0, ''), +(20794, 2, 0, 'Once the hatred in my heart became focused, everything became clear to me. Shattrath must be destroyed and the naaru with it.', 12, 0, 100, 0, 0, 0, 18396, 0, ''), +(20794, 3, 0, 'You are wrong, Adyen. My mind has never been clearer.', 12, 0, 100, 0, 0, 0, 18398, 0 ,''), +(20794, 4, 0, 'Yes... master.', 12, 0, 100, 0, 0, 0, 18409, 0 ,''), +(20794, 5, 0, 'Teacher...', 12, 0, 100, 0, 0, 0, 18399, 0 ,''), +(20794, 6, 0, 'No! What have I done?', 14, 0, 100, 0, 0, 0, 18404, 0 ,''), +(20794, 7, 0, 'Light grant me strength!', 14, 0, 100, 0, 0, 0, 18405, 0 ,''); + +-- Socrethar text +DELETE FROM `creature_text` WHERE `CreatureID` = 20132; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextID`, `TextRange`, `comment`) VALUES +(20132, 0, 0, 'Do not make me laugh. Is this the mighty Aldor army that''s come to defeat me?', 14, 0, 100, 11, 0, 0, 18390, 0, ''), +(20132, 1, 0, 'Yes, let us settle this. Before we begin, however, there''s somebody I''d like you to meet.', 14, 0, 100, 1, 0, 0, 18392, 0, ''), +(20132, 2, 0, 'Slay these dogs, Kaylaan! Earn your place in the Burning Legion!', 14, 0, 100, 25, 0, 0, 18407, 0, ''), +(20132, 3, 0, 'What are you waiting for? Finish them, young one. Let your hatred burn!', 14, 0, 100, 53, 0, 0, 18408, 0, ''), +(20132, 4, 0, 'You foolish old hag... Why would I do that when I can have you both?', 14, 0, 100, 0, 0, 0, 18402, 0 ,''), +(20132, 5, 0, 'Oh, please! This is sickening; I''m going to have to kill you all myself.', 14, 0, 100, 0, 0, 0, 18406, 0 ,''); + +-- Adyen text +DELETE FROM `creature_text` WHERE `CreatureID` = 61021; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextID`, `TextRange`, `comment`) VALUES +(61021, 0, 0, 'We''re here for you, lost brother. It is custom to offer you a chance to repent before you are destroyed. We offer you this chance, as the naaru''s law commands.', 12, 0, 100, 0, 0, 0, 18389, 0, ''), +(61021, 1, 0, 'We may be few, Socrethar, but our faith is strong. Something you will never understand. Now that custom has been served, prepare to meet your end.', 12, 0, 100, 0, 0, 0, 18391, 0, ''), +(61021, 2, 0, 'How... how could you?!', 12, 0, 100, 0, 0, 0, 18393, 0, ''), +(61021, 3, 0, 'Socrethar is clouding your mind, Kaylaan! You do not mean these words! I remember training you when you were but a youngling. Your will was strong even then!', 12, 0, 100, 0, 0, 0, 18397, 0, ''); + +-- Ishanah text +DELETE FROM `creature_text` WHERE `CreatureID` = 18538; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextID`, `TextRange`, `comment`) VALUES +(18538, 0, 0, 'The Light wants its lost son back, Socrethar.', 12, 0, 100, 0, 0, 0, 18400, 0, ''), +(18538, 1, 0, 'I offer myself in exchange. You will have Ishanah, the High Priestess of the Aldor, as your prisoner if you release Kaylaan from your dark grasp.', 12, 0, 100, 0, 0, 0, 18401, 0, ''); diff --git a/src/server/scripts/Outland/zone_netherstorm.cpp b/src/server/scripts/Outland/zone_netherstorm.cpp index 7b0536a3b..254773a49 100644 --- a/src/server/scripts/Outland/zone_netherstorm.cpp +++ b/src/server/scripts/Outland/zone_netherstorm.cpp @@ -24,6 +24,1037 @@ EndContentData */ #include "ScriptedEscortAI.h" #include "Player.h" #include "GameObjectAI.h" +#include "SpellInfo.h" + +/* ################################### + # QUEST: Deathblow to the legion # + ################################### +*/ + +enum DeathblowToTheLegion +{ + ADYEN_THE_LIGHTBRINGER = 61021, + ANCHORITE_KARJA = 50001, + EXARCH_ORELIS = 50002, + SOCRETHAR = 20132, + KAYLAAN_THE_LOST = 20794, + ISHANAH_HIGH_PRIESTESS = 18538, + + DEATHBLOW_TO_THE_LEGION = 10409, // Quest ID + TURNING_POINT = 10507, // Quest ID + SOCRETHAR_QUEST_CREDIT = 35762, // Quest spell + SOCRETHAR_TP_STONE = 29796, + + EXODAR_FACTION = 1806, + EXODAR_ENEMY_FACTION = 90 +}; + +enum RoleplayActions +{ + // ADYEN TEXTS + EVENT_ADYEN_SAY_1 = 1, + EVENT_ADYEN_SAY_2 = 2, + EVENT_ADYEN_SAY_3 = 3, + EVENT_ADYEN_SAY_4 = 4, + + // SOCRETHAR TEXT + EVENT_SOCRETHAR_SAY_1 = 5, + EVENT_SOCRETHAR_SAY_2 = 6, + EVENT_SOCRETHAR_SAY_3 = 7, + EVENT_SOCRETHAR_SAY_4 = 8, + EVENT_SOCRETHAR_SAY_5 = 9, + EVENT_SOCRETHAR_SAY_6 = 10, + + // KAYLAAN TEXT + EVENT_KAYLAAN_SAY_1 = 11, + EVENT_KAYLAAN_SAY_2 = 12, + EVENT_KAYLAAN_SAY_3 = 13, + EVENT_KAYLAAN_SAY_4 = 14, + EVENT_KAYLAAN_SAY_5 = 15, // Spawn Ishanah at this point + EVENT_KAYLAAN_SAY_6 = 16, + EVENT_KAYLAAN_SAY_7 = 17, + + // ISHANAH TEXT + EVENT_ISHANAH_SAY_1 = 18, // Make kaylaan bow + EVENT_ISHANAH_SAY_2 = 19, + + // SOCRETHAR ROLEPLAY EVENTS + EVENT_KILL_ISHANAH = 20, + EVENT_KILL_KAYLAAN = 21, + EVENT_FINAL_FIGHT = 22, // On death grant credit to all players on threat list + + // KAYLAAN ROLEPLAY EVENTS + EVENT_KAYLAAN_WALK_TO_ADYEN = 23, // Adyen talks and 3s later he triggers next event + EVENT_KAYLAAN_RESSURECTION = 24, // Ress Ishanah + EVENT_FIGHT_ALDOR = 25, + EVENT_END_ALDOR_FIGHT = 26, + RESET_DEATHBLOW_EVENT = 27 +}; + +enum Adyen +{ + // ADYEN SPELL EVENTS + EVENT_CRUSADER_STRIKE = 1, + EVENT_HAMMER_OF_JUSTICE = 2, + EVENT_HOLY_LIGHT = 3, + + // ADYEN ROLEPLAY EVENTS + EVENT_START_PLAYER_READY = 4, + + // ADYEN SPELLS + CRUSADER_STRIKE = 14518, + HAMMER_OF_JUSTICE = 13005, + HOLY_LIGHT = 13952, + REDEMPTION = 7328, + DIVINE_SHIELD = 40733, + + ADYEN_PATH_ID = 610210 +}; + +enum Karja +{ + // KARJA SPELL EVENTS + EVENT_SPELL_HOLY_SMITE = 1, + + // KARJA ROLEPLAY EVENTS + EVENT_KARJA_WALK = 2, + + // KARJA SPELLS + HOLY_SMITE_KARJA = 9734, + + KARJA_PATH_ID = 500010 +}; + +enum Orelis +{ + // ORELIS SPELL EVENTS + EVENT_SPELL_DEMORALIZING_SHOUT = 1, + EVENT_SPELL_HEROIC_STRIKE = 2, + EVENT_SPELL_REND = 3, + + // ORELIS ROLEPLAY EVENTS + EVENT_ORELIS_WALK = 4, + + // ORELIS SPELLS + DEMORALIZING_SHOUT = 13730, + HEROIC_STRIKE = 29426, + REND = 16509, + + ORELIS_PATH_ID = 500020 +}; + +enum Kaylaan +{ + // KAYLAAN SPELL EVENTS + EVENT_SPELL_BURNING_LIGHT = 6, + EVENT_SPELL_CONSECRATION = 7, + + // KAYLAAN SPELLS + BURNING_LIGHT = 37552, + CONSECRATION = 37553, + + KAYLAAN_PATH_ID1 = 207940, + KAYLAAN_PATH_ID2 = 207941 +}; + +enum Socrethar +{ + // SOCRETHAR SPELL EVENTS # start high to avoid issues with RP enum + EVENT_SPELL_ANTI_MAGIC_SHIELD = 40, + EVENT_SPELL_BACKLASH = 41, + EVENT_SPELL_CLEAVE = 42, + EVENT_SPELL_FIREBALL_BARRAGE = 43, + EVENT_SPELL_NETHER_PROTECTION = 44, + EVENT_SPELL_POWER_OF_THE_LEGION = 45, + EVENT_SPELL_SHADOW_BOLT_VOLLEY = 46, + EVENT_ISHANAH_DIES = 47, + EVENT_KAYLAAN_DIES = 48, + EVENT_ISHANAH_IS_BACK_AGAIN = 49, + + // SOCRETHAR SPELLS + ANTI_MAGIC_SHIELD = 37538, + BACKLASH = 37537, + CLEAVE = 15496, + FIREBALL_BARRAGE = 37540, + NETHER_PROTECTION = 37539, + POWER_OF_THE_LEGION = 35596, + SHADOW_BOLT_VOLLEY = 28448, + WRATH_OF_SOCRETHAR = 35600 +}; + +enum Ishanah +{ + ISHANAH_PATH_ID = 500050 +}; + +// Ishanah script part is in zone shattrath city . cpp + +const Position AdyenSpawnPosition { 4804.839355f, 3773.218750f, 210.530884f, 5.517495f }; +const Position OrelisSpawnPosition { 4805.345215f, 3774.829346f, 210.535095f, 5.517495f }; +const Position KarjaSpawnPosition { 4803.249512f, 3772.649170f, 210.535095f, 5.517495f }; +const Position KaylaanSpawnPosition { 4955.089355f, 3916.570557f, 209.577209f, 4.603052f }; +const Position IshanahSpawnPosition { 4926.066895f, 3825.549072f, 211.494125f, 0.510522f }; + +class deathblow_to_the_legion_trigger : public CreatureScript +{ + public: + deathblow_to_the_legion_trigger() : CreatureScript("deathblow_to_the_legion_trigger") { } + + CreatureAI* GetAI(Creature* creature) const override + { + return new deathblow_to_the_legion_triggerAI(creature); + } + + struct deathblow_to_the_legion_triggerAI : public ScriptedAI + { + deathblow_to_the_legion_triggerAI(Creature* creature) : ScriptedAI(creature), _summons(me) { } + + EventMap _events; + SummonList _summons; + + void JustSummoned(Creature* cr) override { _summons.Summon(cr); } + + void MoveInLineOfSight(Unit* who) override + { + if (who->GetTypeId() == TYPEID_PLAYER && who->IsAlive()) + { + if (who->ToPlayer()->GetQuestStatus(DEATHBLOW_TO_THE_LEGION) == QUEST_STATUS_INCOMPLETE && me->FindNearestCreature(SOCRETHAR, 500.0f, true)) + { + if (!_summons.HasEntry(ADYEN_THE_LIGHTBRINGER)) + { + _summons.RemoveNotExisting(); + me->SummonCreature(ADYEN_THE_LIGHTBRINGER, AdyenSpawnPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000); + if (!_summons.HasEntry(EXARCH_ORELIS)) + me->SummonCreature(EXARCH_ORELIS, OrelisSpawnPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000); + if (!_summons.HasEntry(ANCHORITE_KARJA)) + me->SummonCreature(ANCHORITE_KARJA, KarjaSpawnPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000); + } + } + } + } + }; +}; + +class adyen_the_lightbringer : public CreatureScript +{ + public: + adyen_the_lightbringer(): CreatureScript("adyen_the_lightbringer") { } + + bool OnGossipHello(Player* player, Creature* creature) override + { + if (player->GetQuestStatus(DEATHBLOW_TO_THE_LEGION) == QUEST_STATUS_INCOMPLETE) + AddGossipItemFor(player, ADYEN_THE_LIGHTBRINGER, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID()); + + return true; + } + + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override + { + ClearGossipMenuFor(player); + + if (action == GOSSIP_ACTION_INFO_DEF + 1) + { + CloseGossipMenuFor(player); + creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + creature->AI()->DoAction(EVENT_START_PLAYER_READY); + if (Creature* orelis = creature->FindNearestCreature(EXARCH_ORELIS, 15.0f, true)) + orelis->AI()->DoAction(EVENT_ORELIS_WALK); + if (Creature* karja = creature->FindNearestCreature(ANCHORITE_KARJA, 15.0f, true)) + karja->AI()->DoAction(EVENT_KARJA_WALK); + if (Creature* socrethar = creature->FindNearestCreature(SOCRETHAR, 500.0f, true)) + socrethar->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + } + + return true; + } + + struct adyen_the_lightbringerAI : public ScriptedAI + { + adyen_the_lightbringerAI(Creature* creature) : ScriptedAI(creature), event_started(false) { } + + EventMap _events; + uint32 eventTimer, eventPhase; + bool event_started = false; + + void DoAction(int32 param) override + { + if (param == EVENT_START_PLAYER_READY) + { + me->GetMotionMaster()->MovePath(ADYEN_PATH_ID, false); + event_started = true; + } + else if (param == RESET_DEATHBLOW_EVENT) + { + me->ClearInCombat(); + me->AttackStop(); + me->GetMotionMaster()->MoveTargetedHome(); + me->DespawnOrUnsummon(15000); + } + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type != POINT_MOTION_TYPE) + if (point == 9) + { + if (Creature* socrethar = me->FindNearestCreature(SOCRETHAR, 50.0f, true)) + socrethar->AI()->DoAction(EVENT_ADYEN_SAY_1); + me->SetHomePosition(me->GetPosition()); + } + } + + void EnterCombat(Unit * /*who*/) override + { + _events.ScheduleEvent(EVENT_CRUSADER_STRIKE, 3000); + _events.ScheduleEvent(EVENT_HAMMER_OF_JUSTICE, 6000); + _events.ScheduleEvent(EVENT_HOLY_LIGHT, 1000); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CRUSADER_STRIKE: + me->CastSpell(me->GetVictim(), CRUSADER_STRIKE, false); + _events.RepeatEvent(3500); + break; + case EVENT_HAMMER_OF_JUSTICE: + me->CastSpell(me->GetVictim(), HAMMER_OF_JUSTICE, false); + _events.RepeatEvent(urand(10000, 14000)); + break; + case EVENT_HOLY_LIGHT: + // if low enough will heal and trigger again in 18s. + if (me->GetHealthPct() <= 45) + { + me->CastSpell(me, HOLY_LIGHT, false); + _events.RepeatEvent(urand(18000, 22000)); + } + else if (Unit* who = me->FindNearestCreature(ANCHORITE_KARJA, 30.0f, true)) + { + if (who->GetHealthPct() <= 45) + { + me->CastSpell(who, HOLY_LIGHT, false); + _events.RepeatEvent(urand(18000, 22000)); + } + } + else if (Unit* who = me->FindNearestCreature(EXARCH_ORELIS, 30.0f, true)) + { + if (who->GetHealthPct() <= 45) + { + me->CastSpell(who, HOLY_LIGHT, false); + _events.RepeatEvent(urand(18000, 22000)); + } + } + else + _events.RepeatEvent(1000); + break; + } + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new adyen_the_lightbringerAI(creature); + } +}; + +class anchorite_karja : public CreatureScript +{ + public: + anchorite_karja() : CreatureScript("anchorite_karja") { } + + struct anchorite_karjaAI : public ScriptedAI + { + anchorite_karjaAI(Creature* creature) : ScriptedAI(creature) { } + + EventMap _events; + + void DoAction(int32 param) override + { + if (param == EVENT_KARJA_WALK) + { + me->GetMotionMaster()->MovePath(KARJA_PATH_ID, false); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + else if (param == RESET_DEATHBLOW_EVENT) + { + me->ClearInCombat(); + me->AttackStop(); + me->GetMotionMaster()->MoveTargetedHome(); + me->DespawnOrUnsummon(15000); + } + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type != POINT_MOTION_TYPE) + if (point == 11) + me->SetHomePosition(me->GetPosition()); + } + + void EnterCombat(Unit* who) override + { + AttackStart(who); + _events.ScheduleEvent(EVENT_SPELL_HOLY_SMITE, 1000); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch ( _events.ExecuteEvent()) + { + case EVENT_SPELL_HOLY_SMITE: + me->CastSpell(me->GetVictim(), HOLY_SMITE_KARJA, false); + _events.ScheduleEvent(EVENT_SPELL_HOLY_SMITE, 2500); + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new anchorite_karjaAI(creature); + } +}; + +class exarch_orelis : public CreatureScript +{ + public: + exarch_orelis() : CreatureScript("exarch_orelis") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new exarch_orelisAI(creature); + } + + struct exarch_orelisAI : public ScriptedAI + { + exarch_orelisAI(Creature* creature) : ScriptedAI(creature) { } + + EventMap _events; + + void DoAction(int32 param) override + { + if (param == EVENT_ORELIS_WALK) + { + me->GetMotionMaster()->MovePath(ORELIS_PATH_ID, false); + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + else if (param == RESET_DEATHBLOW_EVENT) + { + me->ClearInCombat(); + me->AttackStop(); + me->GetMotionMaster()->MoveTargetedHome(); + me->DespawnOrUnsummon(15000); + } + } + + void JustSummoned(Creature *) override + { + me->SetHomePosition(me->GetPosition()); + } + + void AttackStart(Unit* who) override + { + ScriptedAI::AttackStart(who); + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type != POINT_MOTION_TYPE) + if (point == 11) + me->SetHomePosition(me->GetPosition()); + } + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_SPELL_DEMORALIZING_SHOUT, 1000); + _events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, urand(2500, 4000)); + _events.ScheduleEvent(EVENT_SPELL_REND, urand(1500, 6000)); + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + switch (_events.ExecuteEvent()) + { + case EVENT_SPELL_DEMORALIZING_SHOUT: + if (me->FindNearestCreature(me->GetVictim()->GetEntry(), 10.0f, true)) + { + me->CastSpell(me->GetVictim(), DEMORALIZING_SHOUT, false); + _events.ScheduleEvent(EVENT_SPELL_DEMORALIZING_SHOUT, urand(10000, 12000)); + } + else + _events.ScheduleEvent(EVENT_SPELL_DEMORALIZING_SHOUT, 1000); + break; + case EVENT_SPELL_HEROIC_STRIKE: + me->CastSpell(me->GetVictim(), HEROIC_STRIKE, false); + _events.ScheduleEvent(EVENT_SPELL_HEROIC_STRIKE, urand(3000, 4000)); + break; + case EVENT_SPELL_REND: + me->CastSpell(me->GetVictim(), REND, false); + _events.ScheduleEvent(EVENT_SPELL_REND, urand(5000, 8000)); + break; + } + + DoMeleeAttackIfReady(); + } + }; +}; + +class socrethar : public CreatureScript +{ + public: + socrethar() : CreatureScript("socrethar") { } + + struct socretharAI : public ScriptedAI + { + socretharAI(Creature* creature) : ScriptedAI(creature), + adyen(nullptr), orelis(nullptr), karja(nullptr), kaylaan(nullptr), ishanah(nullptr) { } + + EventMap _actionEvents, combatEvents; + bool DeathblowToTheLegionRunning = false; + Creature* adyen, *orelis, *karja, *kaylaan, *ishanah; + + bool GetCreature(uint32 CreatureID) + { + switch (CreatureID) + { + case ADYEN_THE_LIGHTBRINGER: + adyen = nullptr; + adyen = me->FindNearestCreature(ADYEN_THE_LIGHTBRINGER, 100.0f, true); + if (adyen != nullptr) + return true; + break; + case EXARCH_ORELIS: + orelis = nullptr; + orelis = me->FindNearestCreature(EXARCH_ORELIS, 100.0f, true); + if (orelis != nullptr) + return true; + break; + case ANCHORITE_KARJA: + karja = nullptr; + karja = me->FindNearestCreature(ANCHORITE_KARJA, 100.0f, true); + if (karja != nullptr) + return true; + break; + case KAYLAAN_THE_LOST: + kaylaan = nullptr; + kaylaan = me->FindNearestCreature(KAYLAAN_THE_LOST, 100.0f, true); + if (kaylaan != nullptr) + return true; + break; + case ISHANAH_HIGH_PRIESTESS: + ishanah = nullptr; + ishanah = me->FindNearestCreature(ISHANAH_HIGH_PRIESTESS, 100.0f, true); + if (ishanah == nullptr) + { + // Ishanah may be dead; in this case we also need a reference to the creature for the respawn + ishanah = me->FindNearestCreature(ISHANAH_HIGH_PRIESTESS, 100.0f, false); + if (ishanah != nullptr) + return true; + } + else + return true; + break; + } + return false; // When he doesn't find anyone + } + + void Reset() override + { + me->SetReactState(REACT_PASSIVE); + me->setFaction(EXODAR_ENEMY_FACTION); + adyen = nullptr; + orelis = nullptr; + karja = nullptr; + ishanah = nullptr; + } + + void DoAction(int32 param) override + { + switch (param) + { + case EVENT_ADYEN_SAY_1: + DeathblowToTheLegionRunning = true; + _actionEvents.ScheduleEvent(EVENT_ADYEN_SAY_1, 1000); + break; + case EVENT_ADYEN_SAY_3: + _actionEvents.ScheduleEvent(EVENT_ADYEN_SAY_3, 2000); + break; + case EVENT_KAYLAAN_SAY_1: + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_SAY_1, 4000); + break; + case EVENT_END_ALDOR_FIGHT: + _actionEvents.ScheduleEvent(EVENT_END_ALDOR_FIGHT, 1); + break; + case EVENT_ISHANAH_SAY_1: + _actionEvents.ScheduleEvent(EVENT_ISHANAH_SAY_1, 2000); + break; + case RESET_DEATHBLOW_EVENT: + DeathblowToTheLegionRunning = false; + Reset(); + break; + } + } + + void JustDied(Unit* /*killer*/) override + { + DoCast(me, SOCRETHAR_QUEST_CREDIT); + + if (GetCreature(ISHANAH_HIGH_PRIESTESS)) + { + ishanah->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + ishanah->DespawnOrUnsummon(60000); + } + + if (GetCreature(ADYEN_THE_LIGHTBRINGER)) + adyen->GetAI()->DoAction(RESET_DEATHBLOW_EVENT); + + if (GetCreature(EXARCH_ORELIS)) + orelis->GetAI()->DoAction(RESET_DEATHBLOW_EVENT); + + if (GetCreature(ANCHORITE_KARJA)) + karja->GetAI()->DoAction(RESET_DEATHBLOW_EVENT); + } + + void EnterCombat(Unit* /*who*/) override + { + combatEvents.ScheduleEvent(EVENT_SPELL_ANTI_MAGIC_SHIELD, 20000); + combatEvents.ScheduleEvent(EVENT_SPELL_BACKLASH, 4000); + combatEvents.ScheduleEvent(EVENT_SPELL_CLEAVE, 2000); + combatEvents.ScheduleEvent(EVENT_SPELL_FIREBALL_BARRAGE, 9000); + combatEvents.ScheduleEvent(EVENT_SPELL_SHADOW_BOLT_VOLLEY, 5000); + combatEvents.ScheduleEvent(EVENT_SPELL_NETHER_PROTECTION, 1); + } + + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override + { + me->SetReactState(REACT_AGGRESSIVE); + } + + void UpdateAI(uint32 diff) override + { + if (DeathblowToTheLegionRunning) + { + _actionEvents.Update(diff); + + switch (_actionEvents.ExecuteEvent()) + { + case EVENT_ADYEN_SAY_1: + if (GetCreature(ADYEN_THE_LIGHTBRINGER)) + adyen->AI()->Talk(0); + _actionEvents.ScheduleEvent(EVENT_SOCRETHAR_SAY_1, 11000); + break; + case EVENT_SOCRETHAR_SAY_1: + Talk(0); + _actionEvents.ScheduleEvent(EVENT_ADYEN_SAY_2, 7000); + break; + case EVENT_ADYEN_SAY_2: + if (GetCreature(ADYEN_THE_LIGHTBRINGER)) + adyen->AI()->Talk(1); + _actionEvents.ScheduleEvent(EVENT_SOCRETHAR_SAY_2, 11000); + break; + case EVENT_SOCRETHAR_SAY_2: + Talk(1); + if (Creature* summonKaylaan = me->SummonCreature(KAYLAAN_THE_LOST, KaylaanSpawnPosition, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 240000)) + summonKaylaan->GetMotionMaster()->MovePath(KAYLAAN_PATH_ID1, false); + break; + case EVENT_ADYEN_SAY_3: + if (GetCreature(ADYEN_THE_LIGHTBRINGER)) + adyen->AI()->Talk(2); + if (GetCreature(KAYLAAN_THE_LOST)) + kaylaan->SetStandState(UNIT_STAND_STATE_STAND); + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_WALK_TO_ADYEN, 3500); + break; + case EVENT_KAYLAAN_WALK_TO_ADYEN: + if (GetCreature(KAYLAAN_THE_LOST)) + kaylaan->GetMotionMaster()->MovePath(KAYLAAN_PATH_ID2, false); + break; + case EVENT_KAYLAAN_SAY_1: + if (GetCreature(KAYLAAN_THE_LOST)) + { + kaylaan->AI()->Talk(0); + kaylaan->SetHomePosition(kaylaan->GetPosition()); + } + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_SAY_2, 9000); + break; + case EVENT_KAYLAAN_SAY_2: + if (GetCreature(KAYLAAN_THE_LOST)) + kaylaan->AI()->Talk(1); + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_SAY_3, 8000); + break; + case EVENT_KAYLAAN_SAY_3: + if (GetCreature(KAYLAAN_THE_LOST)) + kaylaan->AI()->Talk(2); + _actionEvents.ScheduleEvent(EVENT_ADYEN_SAY_4, 8000); + break; + case EVENT_ADYEN_SAY_4: + if (GetCreature(ADYEN_THE_LIGHTBRINGER)) + adyen->AI()->Talk(3); + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_SAY_4, 11000); + break; + case EVENT_KAYLAAN_SAY_4: + if (GetCreature(KAYLAAN_THE_LOST)) + kaylaan->AI()->Talk(3); + _actionEvents.ScheduleEvent(EVENT_SPELL_POWER_OF_THE_LEGION, 5000); + break; + case EVENT_SPELL_POWER_OF_THE_LEGION: + if (GetCreature(KAYLAAN_THE_LOST)) + me->CastSpell(kaylaan, POWER_OF_THE_LEGION, false); + Talk(2); + _actionEvents.ScheduleEvent(EVENT_FIGHT_ALDOR, 3000); + break; + case EVENT_FIGHT_ALDOR: + if (GetCreature(KAYLAAN_THE_LOST)) + { + kaylaan->setFaction(EXODAR_ENEMY_FACTION); + if (GetCreature(ADYEN_THE_LIGHTBRINGER)) + kaylaan->AI()->AttackStart(adyen); + } + break; + case EVENT_END_ALDOR_FIGHT: + if (GetCreature(KAYLAAN_THE_LOST)) + { + kaylaan->setFaction(EXODAR_FACTION); + kaylaan->GetMotionMaster()->MoveTargetedHome(); + kaylaan->CombatStop(); + kaylaan->ClearInCombat(); + } + + if (GetCreature(ADYEN_THE_LIGHTBRINGER)) + { + adyen->GetMotionMaster()->MoveTargetedHome(); + adyen->CombatStop(); + adyen->ClearInCombat(); + } + + if (GetCreature(EXARCH_ORELIS)) + { + orelis->GetMotionMaster()->MoveTargetedHome(); + orelis->CombatStop(); + orelis->ClearInCombat(); + } + + if (GetCreature(ANCHORITE_KARJA)) + { + karja->GetMotionMaster()->MoveTargetedHome(); + karja->CombatStop(); + karja->ClearInCombat(); + } + _actionEvents.ScheduleEvent(EVENT_SOCRETHAR_SAY_4, 2000); + break; + case EVENT_SOCRETHAR_SAY_4: + Talk(3); + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_SAY_5, 8000); + break; + case EVENT_KAYLAAN_SAY_5: + if (GetCreature(KAYLAAN_THE_LOST)) + kaylaan->AI()->Talk(4); + if (Creature* summonIshanah = me->SummonCreature(ISHANAH_HIGH_PRIESTESS, IshanahSpawnPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 180000)) + { + summonIshanah->GetMotionMaster()->MovePath(ISHANAH_PATH_ID, false); + summonIshanah->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + } + break; + case EVENT_ISHANAH_SAY_1: + if (GetCreature(ISHANAH_HIGH_PRIESTESS)) + ishanah->AI()->Talk(0); + if (GetCreature(KAYLAAN_THE_LOST)) + { + kaylaan->RemoveAurasDueToSpell(POWER_OF_THE_LEGION); + kaylaan->SetStandState(UNIT_STAND_STATE_KNEEL); + } + _actionEvents.ScheduleEvent(EVENT_ISHANAH_SAY_2, 6000); + break; + case EVENT_ISHANAH_SAY_2: + if (GetCreature(ISHANAH_HIGH_PRIESTESS)) + ishanah->AI()->Talk(1); + _actionEvents.ScheduleEvent(EVENT_SOCRETHAR_SAY_5, 8000); + break; + case EVENT_SOCRETHAR_SAY_5: + Talk(4); + _actionEvents.ScheduleEvent(EVENT_KILL_ISHANAH, 4000); + break; + case EVENT_KILL_ISHANAH: + if (GetCreature(ISHANAH_HIGH_PRIESTESS)) + me->CastSpell(ishanah, WRATH_OF_SOCRETHAR); + _actionEvents.ScheduleEvent(EVENT_ISHANAH_DIES, 1500); + break; + case EVENT_ISHANAH_DIES: + if (GetCreature(ISHANAH_HIGH_PRIESTESS)) + me->Kill(me,ishanah); + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_SAY_6, 4000); + break; + case EVENT_KAYLAAN_SAY_6: + if (GetCreature(KAYLAAN_THE_LOST)) + { + kaylaan->AI()->Talk(6); + kaylaan->SetStandState(UNIT_STAND_STATE_STAND); + kaylaan->GetMotionMaster()->MovePath(207942, false); + } + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_SAY_7, 9000); + break; + case EVENT_KAYLAAN_SAY_7: + if (GetCreature(KAYLAAN_THE_LOST)) + { + kaylaan->AI()->Talk(7); + kaylaan->CastSpell(kaylaan, DIVINE_SHIELD); + } + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_RESSURECTION, 1000); + break; + case EVENT_KAYLAAN_RESSURECTION: + if (GetCreature(KAYLAAN_THE_LOST)) + kaylaan->CastSpell(ishanah, REDEMPTION); + _actionEvents.ScheduleEvent(EVENT_ISHANAH_IS_BACK_AGAIN, 11000); + break; + case EVENT_ISHANAH_IS_BACK_AGAIN: + if (GetCreature(ISHANAH_HIGH_PRIESTESS)) + { + ishanah->Respawn(); + ishanah->setActive(true); // ensure that Ishanah disappears, even when no player is near + ishanah->DespawnOrUnsummon(600000); // ensure that Ishanah disappears after 10 minutes + ishanah->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP | UNIT_NPC_FLAG_QUESTGIVER); + } + _actionEvents.ScheduleEvent(EVENT_SOCRETHAR_SAY_6, 3000); + break; + case EVENT_SOCRETHAR_SAY_6: + Talk(5); + _actionEvents.ScheduleEvent(EVENT_KILL_KAYLAAN, 4000); + break; + case EVENT_KILL_KAYLAAN: + if (GetCreature(KAYLAAN_THE_LOST)) + me->CastSpell(kaylaan, WRATH_OF_SOCRETHAR); + _actionEvents.ScheduleEvent(EVENT_KAYLAAN_DIES, 1500); + break; + case EVENT_KAYLAAN_DIES: + if (GetCreature(KAYLAAN_THE_LOST)) + me->Kill(me, kaylaan); + _actionEvents.ScheduleEvent(EVENT_FINAL_FIGHT, 3000); + break; + case EVENT_FINAL_FIGHT: + // Prepare Socrethar for encounter + me->setFaction(EXODAR_ENEMY_FACTION); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE); + me->SetReactState(REACT_AGGRESSIVE); + + // Engage combat with Socrethar + if (GetCreature(ADYEN_THE_LIGHTBRINGER)) + adyen->AI()->EnterCombat(me); + if (GetCreature(EXARCH_ORELIS)) + orelis->AI()->EnterCombat(me); + if (GetCreature(ANCHORITE_KARJA)) + karja->AI()->EnterCombat(me); + if (GetCreature(ISHANAH_HIGH_PRIESTESS)) + ishanah->AI()->EnterCombat(me); + break; + } + } + + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + combatEvents.Update(diff); + + switch (combatEvents.ExecuteEvent()) + { + case EVENT_SPELL_NETHER_PROTECTION: + if (!me->HasAura(NETHER_PROTECTION)) + me->CastSpell(me, NETHER_PROTECTION, false); + break; + case EVENT_SPELL_ANTI_MAGIC_SHIELD: + me->CastSpell(me, ANTI_MAGIC_SHIELD, false); + combatEvents.ScheduleEvent(EVENT_SPELL_ANTI_MAGIC_SHIELD, 20000); + break; + case EVENT_SPELL_BACKLASH: + DoCastVictim(BACKLASH); + combatEvents.ScheduleEvent(EVENT_SPELL_BACKLASH, 7000); + break; + case EVENT_SPELL_CLEAVE: + me->CastSpell(me->GetVictim(), CLEAVE, false); + combatEvents.ScheduleEvent(EVENT_SPELL_CLEAVE, 3000); + break; + case EVENT_SPELL_FIREBALL_BARRAGE: + me->CastSpell(me->GetVictim(), FIREBALL_BARRAGE, false); + combatEvents.ScheduleEvent(EVENT_SPELL_FIREBALL_BARRAGE, 15000); + break; + case EVENT_SPELL_SHADOW_BOLT_VOLLEY: + me->CastSpell(me->GetVictim(), SHADOW_BOLT_VOLLEY, false); + combatEvents.ScheduleEvent(EVENT_SPELL_SHADOW_BOLT_VOLLEY, 10000); + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new socretharAI(creature); + } +}; + +class kaylaan_the_lost : public CreatureScript +{ + public: + kaylaan_the_lost() : CreatureScript("kaylaan_the_lost") { } + + struct kaylaan_the_lostAI : public ScriptedAI + { + kaylaan_the_lostAI(Creature* creature) : ScriptedAI(creature) { } + + EventMap _events; + bool first_waypath_done = false; + bool second_waypath_done = false; + bool adyen_dead = false, karja_dead = false, orelis_dead = false; + + void EnterCombat(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_SPELL_BURNING_LIGHT, 2000); + _events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 3000); + } + + void ResetDeathblowEvent(bool event_over /* If true then reset the event*/) + { + me->RemoveAurasDueToSpell(POWER_OF_THE_LEGION); + me->GetMotionMaster()->MoveTargetedHome(); + + // Get socrethar AI so we can reset the event + if (event_over) + { + if (Unit * socrethar = me->FindNearestCreature(SOCRETHAR, 100.0f, true)) + socrethar->GetAI()->DoAction(RESET_DEATHBLOW_EVENT); + + karja_dead = false; + orelis_dead = false; + adyen_dead = false; + + me->DespawnOrUnsummon(5000); // Despawn in 5 seconds to reset event + } + } + + void KilledUnit(Unit* victim) override + { + switch (victim->GetEntry()) + { + case ADYEN_THE_LIGHTBRINGER: + adyen_dead = true; + break; + case ANCHORITE_KARJA: + karja_dead = true; + break; + case EXARCH_ORELIS: + orelis_dead = true; + break; + } + + if (adyen_dead && karja_dead && orelis_dead) + ResetDeathblowEvent(true); + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type != POINT_MOTION_TYPE) + { + if (point == 4) + { + // First waypath complete + me->SetStandState(UNIT_STAND_STATE_KNEEL); + if (Creature* socrethar = me->FindNearestCreature(SOCRETHAR, 30.0f, true)) + socrethar->AI()->DoAction(EVENT_ADYEN_SAY_3); + first_waypath_done = true; + } + else if (point == 0) + { + if (first_waypath_done) + { + if (!second_waypath_done) + { + // Second waypath complete + me->SetHomePosition(me->GetPosition()); + if (Creature* adyen = me->FindNearestCreature(ADYEN_THE_LIGHTBRINGER, 30.0f, true)) + me->SetOrientation(adyen->GetPositionX()); + if (Creature* socrethar = me->FindNearestCreature(SOCRETHAR, 30.0f, true)) + { + socrethar->AI()->DoAction(EVENT_KAYLAAN_SAY_1); + second_waypath_done = true; + } + } + } + } + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + _events.Update(diff); + + if (me->GetHealthPct() <= 30) + if (Creature* socrethar = me->FindNearestCreature(SOCRETHAR, 200.0f, true)) + socrethar->AI()->DoAction(EVENT_END_ALDOR_FIGHT); + + switch (_events.ExecuteEvent()) + { + case EVENT_SPELL_BURNING_LIGHT: + me->CastSpell(me->GetVictim(), BURNING_LIGHT, false); + _events.ScheduleEvent(EVENT_SPELL_BURNING_LIGHT, 4000); + break; + case EVENT_SPELL_CONSECRATION: + if (me->FindNearestCreature(me->GetVictim()->GetGUID(), 10.0f, true)) + me->CastSpell(me, CONSECRATION, false); + _events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 14000); + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new kaylaan_the_lostAI(creature); + } +}; // Ours enum saeed @@ -967,4 +1998,12 @@ void AddSC_netherstorm() new npc_phase_hunter(); new npc_bessy(); new npc_maxx_a_million_escort(); + + // Deathblow to the legion + new deathblow_to_the_legion_trigger(); + new adyen_the_lightbringer(); + new anchorite_karja(); + new exarch_orelis(); + new kaylaan_the_lost(); + new socrethar(); } diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp index 8342b1e74..a17943f7e 100644 --- a/src/server/scripts/Outland/zone_shattrath_city.cpp +++ b/src/server/scripts/Outland/zone_shattrath_city.cpp @@ -419,6 +419,20 @@ public: # npc_ishanah ######*/ +enum Ishanah +{ + // ISHANAH SPELL EVENTS + EVENT_SPELL_ISHANAH_HOLY_SMITE = 3, + EVENT_SPELL_POWER_WORD_SHIELD = 4, + EVENT_ISHANAH_SAY_1 = 18, // Make kaylaan bow + SOCRETHAR = 20132, + KAYLAAN_THE_LOST = 20794, + + // ISHANAH SPELLS + HOLY_SMITE_ISHANAH = 15238, + POWER_WORLD_SHIELD = 22187 +}; + #define ISANAH_GOSSIP_1 "Who are the Sha'tar?" #define ISANAH_GOSSIP_2 "Isn't Shattrath a draenei city? Why do you allow others here?" @@ -450,6 +464,70 @@ public: return true; } + + struct ishanahAI : public ScriptedAI + { + ishanahAI(Creature* creature) : ScriptedAI(creature) { } + + EventMap _events; + + void EnterCombat(Unit* who) override + { + AttackStart(who); + _events.ScheduleEvent(EVENT_SPELL_ISHANAH_HOLY_SMITE, 2000); + _events.ScheduleEvent(EVENT_SPELL_POWER_WORD_SHIELD, 1000); + } + + void MovementInform(uint32 type, uint32 point) override + { + if (type != POINT_MOTION_TYPE) + { + if (point == 2) + { + if (Creature* kaylaan = me->FindNearestCreature(KAYLAAN_THE_LOST, 30.0f, true)) + { + kaylaan->AI()->Talk(5); + kaylaan->SetOrientation(me->GetPositionX()); + if (Creature* socrethar = me->FindNearestCreature(SOCRETHAR, 30.0f, true)) + { + socrethar->AI()->DoAction(EVENT_ISHANAH_SAY_1); + socrethar->SetOrientation(me->GetPositionX()); + } + } + } + } + } + + void UpdateAI(uint32 diff) override + { + if (!me->GetVictim()) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + _events.Update(diff); + + switch (uint32 eventId = _events.ExecuteEvent()) + { + case EVENT_SPELL_ISHANAH_HOLY_SMITE: + me->CastSpell(me->GetVictim(), HOLY_SMITE_ISHANAH, false); + _events.ScheduleEvent(EVENT_SPELL_ISHANAH_HOLY_SMITE, 2500); + break; + case EVENT_SPELL_POWER_WORD_SHIELD: + me->CastSpell(me, POWER_WORLD_SHIELD, false); + _events.ScheduleEvent(EVENT_SPELL_POWER_WORD_SHIELD, 30000); + break; + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new ishanahAI(creature); + } }; void AddSC_shattrath_city()