Scripts/Instance: The Vortex Pinnacle

By Mihapro
This commit is contained in:
Aokromes
2016-07-02 16:06:29 +02:00
parent 17a50fe8ed
commit dc11f9fdd5
8 changed files with 3161 additions and 0 deletions

View File

@@ -0,0 +1,277 @@
-- The Vortex Pinnacle
UPDATE `instance_template` SET `script` = 'instance_vortex_pinnacle' WHERE `map` = 657;
UPDATE `creature_template` SET `mechanic_immune_mask` = 617299839 WHERE `entry` IN (43878, 43873, 43875);
-- Script names
UPDATE `creature_template` SET `ScriptName` = 'boss_grand_vizier_ertan' WHERE `entry` = 43878;
UPDATE `creature_template` SET `ScriptName` = 'boss_altairus' WHERE `entry` = 43873;
UPDATE `creature_template` SET `ScriptName` = 'boss_asaad' WHERE `entry` = 43875;
UPDATE `creature_template` SET `ScriptName` = 'npc_lurking_tempest' WHERE `entry` = 45704;
UPDATE `creature_template` SET `ScriptName` = 'npc_ertans_vortex' WHERE `entry` = 46007;
UPDATE `creature_template` SET `ScriptName` = 'npc_slipstream' WHERE `entry` = 45455;
UPDATE `creature_template` SET `ScriptName` = 'npc_slipstream_landing_zone' WHERE `entry` = 45504;
UPDATE `creature_template` SET `ScriptName` = 'npc_young_storm_dragon' WHERE `entry` = 45919;
UPDATE `creature_template` SET `ScriptName` = 'npc_air_current' WHERE `entry` = 47305;
UPDATE `creature_template` SET `ScriptName` = 'npc_grounding_field' WHERE `entry` = 47085;
UPDATE `creature_template` SET `ScriptName` = 'npc_skyfall' WHERE `entry` = 45981;
UPDATE `creature_template` SET `ScriptName` = 'npc_skyfall_star' WHERE `entry` = 45932;
UPDATE `creature_template` SET `ScriptName` = 'npc_unstable_grounding_field' WHERE `entry` = 46492;
UPDATE `creature_template` SET `ScriptName` = 'npc_storm_target' WHERE `entry` = 46387;
UPDATE `creature_template` SET `ScriptName` = 'npc_asaad_grounding_field' WHERE `entry` = 47000;
DELETE FROM `spell_script_names` WHERE `spell_id` IN (84978, 84989, 85395, 85396, 85017);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(84978, 'spell_slipstream'),
(84989, 'spell_slipstream'),
(85395, 'spell_slipstream'),
(85396, 'spell_slipstream'),
(85017, 'spell_slipstream');
DELETE FROM `spell_script_names` WHERE `spell_id` IN (85294, 85291, 85267, 86493, 85281, 86456, 86284, 86311, 86299, 85084, 88276, 88282, 88772, 88322, 87726, 87850, 87854);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(85294, 'spell_lurk_search'),
(85291, 'spell_lurk_search_check'),
(85267, 'spell_feign_death'),
(86493, 'spell_lurk_search_check'),
(85281, 'spell_lurk_ressurect'),
(86456, 'spell_lurk_search_victim'),
(86284, 'spell_storms_edge'),
(86311, 'spell_storms_edge'),
(86299, 'spell_storms_edge_script'),
(85084, 'spell_howling_gale'),
(88276, 'spell_call_the_wind'),
(88282, 'spell_upwind_of_altairus'),
(88772, 'spell_call_the_wind_channel'),
(88322, 'spell_chilling_breath'),
(87726, 'spell_grounding_field'),
(87850, 'spell_skyfall'),
(87854, 'spell_arcane_barrage');
-- Asaad spell script names
DELETE FROM `spell_script_names` WHERE `spell_id` IN (86632, 86926, 86921, 86923, 86925, 87517, 87553, 93994);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(86632, 'spell_sots_targeting'),
(86926, 'spell_sots_trigger'),
(86921, 'spell_storm_rune_beam'),
(86923, 'spell_storm_rune_beam'),
(86925, 'spell_storm_rune_beam'),
(87517, 'spell_grounding_field_visual_beams'),
(87553, 'spell_supremacy_of_the_storm'),
(93994, 'spell_supremacy_of_the_storm');
-- Spell condition
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` IN (86284, 86299, 88276, 88772, 87724, 87726, 87850, 86632, 86926, 86911, 86981, 87328);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 86284, 0, 0, 35, 0, 1, 25, 3, 0, 0, 0, '', 'Storm''s Edge targets must be further than 25 yards'),
(13, 1, 86299, 0, 0, 31, 0, 3, 46007, 0, 0, 0, 0, '', 'Call The Wind targets NPC_ERTANS_VORTEX'),
(13, 1, 88276, 0, 0, 31, 0, 3, 47305, 0, 0, 0, 0, '', 'Call The Wind EFFECT_0 can only hit NPC_AIR_CURRENT'),
(13, 1, 88772, 0, 0, 31, 0, 3, 47305, 0, 0, 0, 0, '', 'Call The Wind targets NPC_AIR_CURRENT'),
(13, 1, 88772, 0, 0, 1, 0, 88244, 0, 0, 0, 0, 0, '', 'Call The Wind target must have Call The Wind aura'),
(13, 1, 87724, 0, 0, 1, 0, 87721, 0, 0, 0, 0, 0, '', 'Prism Beam EFFECT_0 target must have SPELL_BEAM_A aura'),
(13, 2, 87724, 0, 0, 1, 0, 87722, 0, 0, 0, 0, 0, '', 'Prism Beam EFFECT_1 target must have SPELL_BEAM_B aura'),
(13, 4, 87724, 0, 0, 1, 0, 87723, 0, 0, 0, 0, 0, '', 'Prism Beam EFFECT_2 target must have SPELL_BEAM_C aura'),
(13, 1, 87726, 0, 0, 31, 0, 3, 45926, 0, 0, 0, 0, '', 'Grounding Field can target npc Servant of Asaad'),
(13, 1, 87726, 0, 1, 31, 0, 3, 45928, 0, 0, 0, 0, '', 'Grounding Field can target npc Executor of the Caliph'),
(13, 1, 87726, 0, 2, 31, 0, 3, 45930, 0, 0, 0, 0, '', 'Grounding Field can target npc Minister of Air'),
(13, 1, 87726, 0, 3, 31, 0, 3, 45935, 0, 0, 0, 0, '', 'Grounding Field can target npc Temple Adept'),
(13, 1, 87850, 0, 0, 31, 0, 3, 52019, 0, 0, 0, 0, '', 'Skyfall targets NPC_SKYFALL_STAR'),
(13, 1, 86632, 0, 0, 31, 0, 3, 46387, 0, 0, 0, 0, '', 'SOTS Targeting targets NPC_STORM_TARGET'),
(13, 1, 86926, 0, 0, 31, 0, 3, 43875, 0, 0, 0, 0, '', 'SOTS Trigger targets BOSS_ASAAD'),
(13, 1, 86911, 0, 0, 31, 0, 3, 46492, 0, 0, 0, 0, '', 'Unstable Grounding Field targets NPC_UNSTABLE_GROUNDING_FIELD'),
(13, 1, 86981, 0, 0, 31, 0, 3, 46387, 0, 0, 0, 0, '', 'Storm Rune Beam AA targets NPC_STORM_TARGET'),
(13, 1, 87328, 0, 0, 31, 0, 3, 47000, 0, 0, 0, 0, '', 'Supremacy of the Storm targets NPC_ASAAD_GROUNDING_FIELD');
-- Lurking Tempest
DELETE FROM `creature_template_addon` WHERE `entry` = 45704;
DELETE FROM `creature_text` WHERE `entry` = 45704;
INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(45704, 0, 0, '%s realizes it''s been spotted and quickly plays dead!', 16, 0, 100, 0, 0, 0, 0, 0, 'Lurking Tempest to Lurking Tempest');
-- Grand Vizier Ertan
UPDATE `creature_template` SET `difficulty_entry_1` = 43879 WHERE `entry` = 43878;
UPDATE `creature_template` SET `minlevel` = 87, `maxlevel` = 87, `exp` = 3, `faction` = 16, `speed_walk` = 1.6, `speed_run` = 1.71429, `unit_class` = 2, `unit_flags` = 32832, `ManaModifier` = 2, `flags_extra` = 1 WHERE `entry` = 43879;
-- Grand Vizier Ertan texts
DELETE FROM `creature_text` WHERE `entry` = 43878;
INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(43878, 0, 0, 'Filthy beasts! Your presence in Skywall will not be tolerated!', 14, 0, 100, 0, 0, 20876, 0, 0, 'Grand Vizier Ertan to Player'),
(43878, 1, 0, '%s retracts her cyclone shield!', 41, 0, 100, 0, 0, 0, 47800, 0, 'Grand Vizier Ertan');
-- Grand Vizier Ertan loot
UPDATE `creature_template` SET `lootid` = 43878 WHERE `entry` = 43878;
UPDATE `creature_template` SET `lootid` = 43879 WHERE `entry` = 43879;
DELETE FROM `creature_loot_template` WHERE `Entry` IN (43878, 43879);
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(43878, 1, 43410, 100, 0, 1, 0, 1, 1, 'Grand Vizier Ertan N - Reference Loot'),
(43879, 1, 43411, 100, 0, 1, 0, 1, 1, 'Grand Vizier Ertan H - Reference Loot'),
(43878, 65660, 0, 100, 1, 1, 0, 1, 1, 'Grand Vizier Ertan N - Quest Item'),
(43879, 65660, 0, 100, 1, 1, 0, 1, 1, 'Grand Vizier Ertan H - Quest Item');
DELETE FROM `reference_loot_template` WHERE `Entry` IN (43410, 43411);
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(43410, 55830, 0, 0, 0, 1, 1, 1, 1, NULL),
(43410, 55831, 0, 0, 0, 1, 1, 1, 1, NULL),
(43410, 55832, 0, 0, 0, 1, 1, 1, 1, NULL),
(43410, 55833, 0, 0, 0, 1, 1, 1, 1, NULL),
(43410, 55834, 0, 0, 0, 1, 1, 1, 1, NULL),
(43411, 56356, 0, 0, 0, 1, 1, 1, 1, NULL),
(43411, 56357, 0, 0, 0, 1, 1, 1, 1, NULL),
(43411, 56358, 0, 0, 0, 1, 1, 1, 1, NULL),
(43411, 56359, 0, 0, 0, 1, 1, 1, 1, NULL),
(43411, 56360, 0, 0, 0, 1, 1, 1, 1, NULL);
-- Ertan's Vortex.
UPDATE `creature_template` SET `flags_extra` = 128 WHERE `entry` = 46007;
-- Slipstream
UPDATE `creature_template` SET `InhabitType` = 7 WHERE `entry` IN (45455, 45504);
UPDATE `creature_template` SET `unit_flags` = 33554432 WHERE `entry` = 45504;
DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` = 45455;
INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES
(45455, 84965, 1, 0);
DELETE FROM `creature_template_addon` WHERE `entry` = 45455;
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
(45455, 0, 0, 0, 1, 0, '85021');
-- Young Storm Dragon
UPDATE `creature_template` SET `InhabitType` = 7 WHERE `entry` = 45919;
DELETE FROM `creature_template_addon` WHERE `entry` = 45919;
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
(45919, 0, 0, 0, 1, 0, '88192');
-- Howling Gale
DELETE FROM `creature_template_addon` WHERE `entry` = 45572;
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
(45572, 0, 0, 0, 1, 0, '85084');
-- Altairus
UPDATE `creature_template` SET `difficulty_entry_1` = 43874, `InhabitType` = 7 WHERE `entry` = 43873;
UPDATE `creature_template` SET `minlevel` = 87, `maxlevel` = 87, `exp` = 3, `faction` = 16, `speed_walk` = 1.6, `speed_run` = 1.71429, `unit_flags` = 32832, `InhabitType` = 7, `HoverHeight` = 10.125, `flags_extra` = 1 WHERE `entry` = 43874;
-- Altairus texts
DELETE FROM `creature_text` WHERE `entry` = 43873;
INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(43873, 0, 0, 'The wind abruptly shifts direction at %s'' command!', 41, 0, 100, 0, 0, 0, 0, 0, 'Altairus');
-- Altairus loot
UPDATE `creature_template` SET `lootid` = 43873 WHERE `entry` = 43873;
UPDATE `creature_template` SET `lootid` = 43874 WHERE `entry` = 43874;
DELETE FROM `creature_loot_template` WHERE `Entry` IN (43873, 43874);
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(43873, 1, 43412, 100, 0, 1, 0, 1, 1, 'Altairus N - Reference Loot'),
(43874, 1, 43413, 100, 0, 1, 0, 1, 1, 'Altairus H - Reference Loot'),
(43873, 63040, 0, 1, 0, 1, 0, 1, 1, 'Altairus N - Mount Drop'),
(43874, 63040, 0, 1, 0, 1, 0, 1, 1, 'Altairus H - Mount Drop');
DELETE FROM `reference_loot_template` WHERE `Entry` IN (43412, 43413);
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(43412, 55835, 0, 0, 0, 1, 1, 1, 1, NULL),
(43412, 55838, 0, 0, 0, 1, 1, 1, 1, NULL),
(43412, 55839, 0, 0, 0, 1, 1, 1, 1, NULL),
(43412, 55840, 0, 0, 0, 1, 1, 1, 1, NULL),
(43412, 55841, 0, 0, 0, 1, 1, 1, 1, NULL),
(43413, 56361, 0, 0, 0, 1, 1, 1, 1, NULL),
(43413, 56362, 0, 0, 0, 1, 1, 1, 1, NULL),
(43413, 56363, 0, 0, 0, 1, 1, 1, 1, NULL),
(43413, 56364, 0, 0, 0, 1, 1, 1, 1, NULL),
(43413, 56365, 0, 0, 0, 1, 1, 1, 1, NULL);
-- Invisible Stalker (Cataclysm Boss, Ignore Combat)
UPDATE `creature_template` SET `flags_extra` = 128 WHERE `entry` = 42844;
DELETE FROM `creature_template_addon` WHERE `entry` = 42844;
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
(42844, 0, 0, 0, 1, 0, '88350');
-- Air Current
UPDATE `creature_template` SET `InhabitType` = 7, `flags_extra` = 128 WHERE `entry` = 47305;
-- Twister
UPDATE `creature_template` SET `flags_extra` = 128 WHERE `entry` = 47342;
DELETE FROM `creature_template_addon` WHERE `entry` = 47342;
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
(47342, 0, 0, 0, 1, 0, '88313');
-- Zephyr
UPDATE `creature_template` SET `speed_walk` = 4, `speed_run` = 12, `flags_extra` = 128 WHERE `entry` = 45991;
DELETE FROM `creature_template_addon` WHERE `entry` = 45991;
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
(45991, 0, 0, 0, 1, 0, '85734');
DELETE FROM `waypoint_data` WHERE `id` IN (4599100, 4599101);
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(4599100, 1, -1050.74, 429.649, 651.2561, 0, 0, 0, 0, 100, 0),
(4599100, 2, -1025.79, 446.358, 657.6731, 0, 0, 0, 0, 100, 0),
(4599100, 3, -1021.287, 474.0407, 664.598, 0, 0, 0, 0, 100, 0),
(4599100, 4, -1036.114, 495.2139, 670.9863, 0, 0, 0, 0, 100, 0),
(4599100, 5, -1059.67, 498.865, 677.6423, 0, 0, 0, 0, 100, 0),
(4599100, 6, -1077.17, 485.951, 683.4588, 0, 0, 0, 0, 100, 0),
(4599100, 7, -1080.06, 466.3477, 688.7894, 0, 0, 0, 0, 100, 0),
(4599100, 8, -1069.01, 452.476, 693.6293, 0, 0, 0, 0, 100, 0),
(4599100, 9, -1053.397, 450.5248, 698.0431, 0, 0, 0, 45991, 100, 0),
(4599101, 1, -781.4438, 491.1446, 698.0991, 0, 0, 0, 0, 100, 0),
(4599101, 2, -765.677, 487.116, 693.6418, 0, 0, 0, 0, 100, 0),
(4599101, 3, -756.743, 472.135, 688.8555, 0, 0, 0, 0, 100, 0),
(4599101, 4, -762.127, 453.059, 683.3886, 0, 0, 0, 0, 100, 0),
(4599101, 5, -780.924, 442.635, 677.577, 0, 0, 0, 0, 100, 0),
(4599101, 6, -803.446, 449.476, 670.8987, 0, 0, 0, 0, 100, 0),
(4599101, 7, -815.382, 471.972, 664.5117, 0, 0, 0, 0, 100, 0),
(4599101, 8, -807.351, 498.323, 657.6155, 0, 0, 0, 0, 100, 0),
(4599101, 9, -780.9688, 511.8101, 651.2169, 0, 0, 0, 45991, 100, 0);
DELETE FROM `waypoint_scripts` WHERE `id` = 45991;
INSERT INTO `waypoint_scripts` (`id`, `delay`, `command`, `datalong`, `datalong2`, `dataint`, `x`, `y`, `z`, `o`, `guid`) VALUES
(45991, 0, 18, 0, 0, 0, 0, 0, 0, 0, 891);
-- Grounding Field and Skyfall Star inhabit type correction
UPDATE `creature_template` SET `InhabitType` = 7 WHERE `entry` IN (47085, 45932);
-- Asaad
UPDATE `creature_template` SET `difficulty_entry_1` = 43876, `InhabitType` = 7 WHERE `entry` = 43875;
UPDATE `creature_template` SET `minlevel` = 87, `maxlevel` = 87, `exp` = 3, `faction` = 16, `speed_walk` = 1.6, `speed_run` = 1.71429, `unit_class` = 2, `unit_flags` = 32832, `ManaModifier` = 2, `flags_extra` = 1 WHERE `entry` = 43876;
-- Asaad texts
DELETE FROM `creature_text` WHERE `entry` = 43875;
INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(43875, 0, 0, 'YOU tread upon the sacrosanct! Mortals have no place amidst the clouds.', 14, 0, 100, 0, 0, 20867, 0, 0, 'Asaad to Player'),
(43875, 1, 0, 'Al''Akir, your servant calls for aid!', 14, 0, 100, 0, 0, 20869, 0, 0, 'Asaad'),
(43875, 2, 0, '%s conjures a temporary grounding field!', 41, 0, 100, 0, 0, 20869, 0, 0, 'Asaad'),
(43875, 3, 0, 'The winds take me!', 14, 0, 100, 0, 0, 20870, 0, 0, 'Asaad to Player');
-- Asaad loot
UPDATE `creature_template` SET `lootid` = 43875 WHERE `entry` = 43875;
UPDATE `creature_template` SET `lootid` = 43876 WHERE `entry` = 43876;
DELETE FROM `creature_loot_template` WHERE `Entry` IN (43875, 43876);
INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(43875, 1, 43414, 100, 0, 1, 0, 2, 2, 'Asaad N - Reference Loot'),
(43876, 1, 43415, 100, 0, 1, 0, 2, 2, 'Asaad H - Reference Loot'),
(43876, 52078, 0, 100, 0, 1, 0, 1, 1, 'Asaad H - Chaos Orb');
DELETE FROM `reference_loot_template` WHERE `Entry` IN (43414, 43415);
INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES
(43414, 55842, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55844, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55845, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55846, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55847, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55848, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55849, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55850, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55851, 0, 0, 0, 1, 1, 1, 1, NULL),
(43414, 55852, 0, 0, 0, 1, 1, 1, 1, NULL);
-- Grounding Field inhabit type correction
UPDATE `creature_template` SET `InhabitType` = 7 WHERE `entry` IN (47000);
-- Set CREATURE_FLAG_EXTRA_TRIGGER to Storm Target, Unstable Grounding Field and Grounding Field.
UPDATE `creature_template` SET `flags_extra` = 128 WHERE `entry` IN (46387, 46492, 47000);
--

View File

@@ -3753,6 +3753,27 @@ void SpellMgr::LoadSpellInfoCorrections()
case 95285: // Teleport (from Slabhide to entrance)
spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_DB);
break;
// Vortex of Pinnacle spells
case 85085: // Howling Gale
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS);
break;
case 85159: // Howling Gale
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(84); // To-do: Enum this radius entry - EFFECT_RADIUS_17_YARDS.
break;
// Altairus
case 88282: // Upwind of Altairus
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS);
break;
case 88314: // Twisting Winds
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS);
spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS);
break;
// Grounding Field
case 87721: // Beam A
case 87722: // Beam B
case 87723: // Beam C
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
break;
// Halls Of Origination spells
// Temple Guardian Anhuur
case 76606: // Disable Beacon Beams L

View File

@@ -0,0 +1,406 @@
/*
* Copyright (C) 2008-2016 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 "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "Player.h"
#include "vortex_pinnacle.h"
enum Spells
{
SPELL_CALL_THE_WIND = 88276, // targets 47305 in hook
SPELL_CHILLING_BREATH = 88322,
// Invisible Stalker
SPELL_CALL_THE_WIND_CHANNEL = 88772, // visual channeling targeting Air Current
// Air Current
SPELL_CALL_THE_WIND_AURA = 88244, // periodically triggers upwind
SPELL_UPWIND_OF_ALTAIRUS = 88282,
SPELL_DOWNWIND_OF_ALTAIRUS = 88286,
// Twister
SPELL_TWISTER_AURA = 88313,
};
enum NPCs
{
NPC_INVISIBLE_STALKER = 42844,
NPC_AIR_CURRENT = 47305,
NPC_TWISTER = 47342,
};
enum Texts
{
SAY_CALL_THE_WIND = 0,
};
enum Events
{
EVENT_NONE,
EVENT_CALL_THE_WIND,
EVENT_CHILLING_BREATH,
// Air Current
EVENT_SET_FACING,
EVENT_CAST_VISUAL,
// Twister
EVENT_MOVE_RANDOM,
};
enum Actions
{
ACTION_CALL_THE_WIND,
};
enum Points
{
POINT_RANDOM,
POINT_TWISTER_MAX = 24,
};
const Position InvisibleStalkerPos = { -1216.12f, 64.026f, 734.2573f };
const Position TwisterSpawnPoints[POINT_TWISTER_MAX] = {
{ -1226.936f, 58.03993f, 734.2574f },
{ -1250.604f, 78.47916f, 729.8842f },
{ -1255.609f, 63.03125f, 729.05f },
{ -1235.368f, 85.2691f, 732.747f },
{ -1245.059f, 61.33333f, 732.6014f },
{ -1237.84f, 72.69965f, 734.2705f },
{ -1190.684f, 69.16666f, 734.2564f },
{ -1194.172f, 54.2066f, 734.2574f },
{ -1215.405f, 65.88541f, 734.2574f },
{ -1236.722f, 48.6632f, 734.2571f },
{ -1193.104f, 82.77431f, 737.7465f },
{ -1210.278f, 80.68056f, 734.2574f },
{ -1202.799f, 68.46702f, 734.2574f },
{ -1224.179f, 76.04688f, 734.2574f },
{ -1244.069f, 92.11979f, 729.0458f },
{ -1211.163f, 53.77778f, 734.2574f },
{ -1198.332f, 106.1181f, 740.7894f },
{ -1203.602f, 93.05209f, 738.5089f },
{ -1242.745f, 37.7257f, 734.257f },
{ -1219.642f, 93.82291f, 737.8855f },
{ -1223.229f, 40.89063f, 734.2574f },
{ -1211.016f, 105.4375f, 740.8424f },
{ -1189.568f, 95.77604f, 740.8668f },
{ -1204.863f, 40.49826f, 734.2564f },
};
// TO-DO:
// - Fix hovering with disabled gravity. Altairus falls down every time position is updated.
// - Add argument to MoveRandom() to manually set i_nextMoveTime in "RandomMovementGenerator.h". This npc needs i_nextMoveTime = 1000.
class boss_altairus : public CreatureScript
{
public:
boss_altairus() : CreatureScript("boss_altairus") { }
struct boss_altairusAI : public BossAI
{
boss_altairusAI(Creature* creature) : BossAI(creature, DATA_ALTAIRUS)
{
//me->SetHover(true);
//me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
}
void Reset() override
{
_Reset();
events.ScheduleEvent(EVENT_CALL_THE_WIND, 6000);
events.ScheduleEvent(EVENT_CHILLING_BREATH, 15000);
}
void EnterCombat(Unit* /*target*/) override
{
_EnterCombat();
me->SummonCreature(NPC_INVISIBLE_STALKER, InvisibleStalkerPos);
if (IsHeroic())
for (int8 i = 0; i < POINT_TWISTER_MAX; i++)
if (Creature* twister = me->SummonCreature(NPC_TWISTER, TwisterSpawnPoints[i]))
twister->GetMotionMaster()->MoveRandom(10.0f);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_CALL_THE_WIND:
DoCast(me, SPELL_CALL_THE_WIND);
Talk(SAY_CALL_THE_WIND);
events.ScheduleEvent(EVENT_CALL_THE_WIND, 20500);
break;
case EVENT_CHILLING_BREATH:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_CHILLING_BREATH);
events.ScheduleEvent(EVENT_CHILLING_BREATH, 13000);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_altairusAI>(creature);
}
};
// 47305 - Air Current
class npc_air_current : public CreatureScript
{
public:
npc_air_current() : CreatureScript("npc_air_current") { }
struct npc_air_currentAI : public ScriptedAI
{
npc_air_currentAI(Creature* creature) : ScriptedAI(creature)
{
me->SetDisableGravity(true);
}
void SpellHit(Unit* /*unit*/, const SpellInfo* spellInfo) override
{
if (spellInfo->Id != SPELL_CALL_THE_WIND)
return;
DoCast(me, SPELL_CALL_THE_WIND_AURA);
events.ScheduleEvent(EVENT_SET_FACING, 400);
events.ScheduleEvent(EVENT_CAST_VISUAL, 1600);
}
void UpdateAI(uint32 diff) override
{
if (events.Empty())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SET_FACING:
if (Creature* invisibleStalker = me->FindNearestCreature(NPC_INVISIBLE_STALKER, 100.0f))
{
invisibleStalker->CastStop();
invisibleStalker->SetFacingToObject(me);
}
break;
case EVENT_CAST_VISUAL:
if (Creature* invisibleStalker = me->FindNearestCreature(NPC_INVISIBLE_STALKER, 100.0f))
invisibleStalker->CastSpell(me, SPELL_CALL_THE_WIND_CHANNEL);
break;
default:
break;
}
}
}
private:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<npc_air_currentAI>(creature);
}
};
// 88276 - Call The Wind
class spell_call_the_wind : public SpellScriptLoader
{
public:
spell_call_the_wind() : SpellScriptLoader("spell_call_the_wind") { }
class spell_call_the_wind_SpellScript : public SpellScript
{
PrepareSpellScript(spell_call_the_wind_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_CALL_THE_WIND_AURA))
return false;
return true;
}
void FilterTargets(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_CALL_THE_WIND_AURA));
Trinity::Containers::RandomResizeList(targets, 1);
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_CALL_THE_WIND_AURA);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_call_the_wind_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_call_the_wind_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_call_the_wind_SpellScript();
}
};
// 88282 - Upwind of Altairus
class spell_upwind_of_altairus : public SpellScriptLoader
{
public:
spell_upwind_of_altairus() : SpellScriptLoader("spell_upwind_of_altairus") { }
class spell_upwind_of_altairus_SpellScript : public SpellScript
{
PrepareSpellScript(spell_upwind_of_altairus_SpellScript);
void GetDistance()
{
Unit* caster = GetCaster();
if (InstanceScript* instance = caster->GetInstanceScript())
if (Creature* altairus = instance->GetCreature(DATA_ALTAIRUS))
upwindDistance = caster->GetExactDist(altairus);
}
void CheckDistance(SpellEffIndex /*effIndex*/)
{
Unit* target = GetHitUnit();
if (GetCaster()->GetExactDist(target) < upwindDistance)
{
// Upwind of Altairus (applied by default effects)
if (target->HasAura(SPELL_DOWNWIND_OF_ALTAIRUS))
target->RemoveAurasDueToSpell(SPELL_DOWNWIND_OF_ALTAIRUS);
}
else
{
// Downwind of Altairus
PreventHitDefaultEffect(EFFECT_0);
PreventHitDefaultEffect(EFFECT_1);
if (target->HasAura(SPELL_UPWIND_OF_ALTAIRUS))
target->RemoveAurasDueToSpell(SPELL_UPWIND_OF_ALTAIRUS);
target->CastSpell(target, SPELL_DOWNWIND_OF_ALTAIRUS, true);
}
}
void Register() override
{
BeforeCast += SpellCastFn(spell_upwind_of_altairus_SpellScript::GetDistance);
OnEffectHitTarget += SpellEffectFn(spell_upwind_of_altairus_SpellScript::CheckDistance, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
private:
float upwindDistance;
};
SpellScript* GetSpellScript() const override
{
return new spell_upwind_of_altairus_SpellScript();
}
};
// 88772 - Call the Wind (visual, channeling on Air Current with Call The Wind aura)
class spell_call_the_wind_channel : public SpellScriptLoader
{
public:
spell_call_the_wind_channel() : SpellScriptLoader("spell_call_the_wind_channel") { }
class spell_call_the_wind_channel_AuraScript : public AuraScript
{
PrepareAuraScript(spell_call_the_wind_channel_AuraScript);
void RemoveCallTheWindAura(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Creature* creature = GetOwner()->ToCreature())
creature->RemoveAurasDueToSpell(SPELL_CALL_THE_WIND_AURA);
}
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_call_the_wind_channel_AuraScript::RemoveCallTheWindAura, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_call_the_wind_channel_AuraScript();
}
};
// 88322 - Chilling Breath
class spell_chilling_breath : public SpellScriptLoader
{
public:
spell_chilling_breath() : SpellScriptLoader("spell_chilling_breath") { }
class spell_chilling_breath_SpellScript : public SpellScript
{
PrepareSpellScript(spell_chilling_breath_SpellScript);
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetCaster()->CastSpell(GetHitUnit(), uint32(GetEffectValue()));
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_chilling_breath_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_chilling_breath_SpellScript();
}
};
void AddSC_boss_altairus()
{
new boss_altairus();
new npc_air_current();
new spell_call_the_wind();
new spell_upwind_of_altairus();
new spell_call_the_wind_channel();
new spell_chilling_breath();
}

View File

@@ -0,0 +1,775 @@
/*
* Copyright (C) 2008-2015 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 "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "ObjectAccessor.h"
#include "Player.h"
#include "vortex_pinnacle.h"
enum Spells
{
SPELL_SUMMON_SKYFALL_STAR = 96260, // summons 52019
SPELL_CHAIN_LIGHTNING = 87622,
SPELL_SOTS_TARGETING = 86632,
SPELL_STATIC_CLING = 87618,
SPELL_UNSTABLE_GROUNDING_FIELD = 86911, // 20 sec channel, visual
SPELL_SUPREMACY_OF_THE_STORM_TELEPORT = 87328,
SPELL_SUPREMACY_OF_THE_STORM = 86930,
// Skyfall Star
SPELL_ARCANE_BARRAGE_AURA = 87845,
// Storm Target
SPELL_SOTS_SUMMON = 86658,
// Unstable Grounding Field
SPELL_SOTS_TRIGGER = 86926,
SPELL_STORM_RUNE_BEAM_AA = 86981,
SPELL_STORM_RUNE_BEAM_A = 86921,
SPELL_STORM_RUNE_BEAM_B = 86923,
SPELL_STORM_RUNE_BEAM_C = 86925,
SPELL_STORM_SUMMON_GROUNDING_FIELD = 87518,
// Grounding Field
SPELL_GROUNDING_FIELD_VISUAL_BEAMS = 87517,
};
enum NPCs
{
NPC_SKYFALL_STAR = 52019,
NPC_STORM_TARGET = 46387,
NPC_UNSTABLE_GROUNDING_FIELD = 46492,
};
enum Texts
{
SAY_AGGRO = 0,
SAY_SOTS_EMOTE = 1,
SAY_SOTS = 2,
SAY_DEATH = 3,
};
enum Actions
{
ACTION_NONE,
ACTION_SOTS_TARGET,
ACTION_SUPREMACY_OF_THE_STORM,
};
enum Events
{
EVENT_NONE,
EVENT_SUMMON_SKYFALL_STAR,
EVENT_CHAIN_LIGHTNING,
EVENT_STATIC_CLING,
EVENT_SOTS,
EVENT_SOTS_START,
EVENT_SOTS_END,
EVENT_ATTACK,
// Storm Target
EVENT_SOTS_SUMMON,
// Unstable Grounding Field npc
EVENT_STORM_ASSAD_CHANNEL,
EVENT_STORM_RUNE_BEAM_AA,
EVENT_STORM_MOVE_B,
EVENT_STORM_MOVE_C,
EVENT_STORM_MOVE_A,
EVENT_STORM_ASAAD_TELEPORT,
// Grounding Field npc
EVENT_GROUNDING_FIELD_VISUAL_BEAMS,
};
enum Points
{
POINT_STORM_A,
POINT_STORM_B,
POINT_STORM_C,
};
uint32 const StormTargetPositions = 39;
Position const StormTargetPositionData[StormTargetPositions] =
{
{ -633.771f, 490.976f, 646.7143f, 3.141593f }, // 56889
{ -625.688f, 501.934f, 646.7143f, 3.141593f }, // 56890
{ -620.226f, 490.892f, 646.7143f, 3.141593f }, // 56891
{ -649.906f, 494.905f, 646.7143f, 3.141593f }, // 56892
{ -643.214f, 503.953f, 646.7143f, 3.141593f }, // 56893
{ -640.542f, 487.474f, 646.7143f, 3.141593f }, // 56894
{ -637.839f, 516.186f, 646.7143f, 1.099557f }, // 56895
{ -634.068f, 507.51f, 646.7143f, 1.099557f }, // 56896
{ -650.894f, 509.323f, 646.7143f, 1.099557f }, // 56897
{ -637.01f, 530.09f, 646.7143f, 1.099557f }, // 56898
{ -632.167f, 521.153f, 646.7143f, 1.099557f }, // 56899
{ -646.939f, 519.566f, 646.7143f, 1.099557f }, // 56900
{ -628.512f, 516.988f, 646.7143f, 1.099557f }, // 56901
{ -622.184f, 507.908f, 646.7143f, 1.099557f }, // 56902
{ -633.148f, 499.762f, 646.7143f, 1.099557f }, // 56903
{ -615.528f, 515.944f, 646.7143f, 1.099557f }, // 56904
{ -609.41f, 504.675f, 646.7143f, 1.099557f }, // 56905
{ -618.748f, 501.946f, 646.7143f, 1.099557f }, // 56906
{ -600.986f, 522.576f, 646.7143f, 1.099557f }, // 56907
{ -594.96f, 507.582f, 646.7143f, 1.099557f }, // 56908
{ -605.094f, 509.141f, 646.7143f, 1.099557f }, // 56909
{ -617.269f, 521.168f, 646.7143f, 0.0f }, // 56910
{ -606.75f, 530.002f, 646.7143f, 0.0f }, // 56911
{ -608.832f, 515.175f, 646.7143f, 0.0f }, // 56912
{ -627.957f, 529.927f, 646.7143f, 0.0f }, // 56913
{ -616.997f, 530.564f, 646.7143f, 0.0f }, // 56914
{ -621.91f, 517.644f, 646.7143f, 0.0f }, // 56915
{ -604.839f, 485.186f, 646.7143f, 3.141593f }, // 56916
{ -616.885f, 496.186f, 646.7143f, 3.141593f }, // 56917
{ -606.833f, 500.078f, 646.7143f, 3.141593f }, // 56918
{ -600.387f, 482.604f, 646.7143f, 3.141593f }, // 56919
{ -602.899f, 497.245f, 646.7143f, 3.141593f }, // 56920
{ -592.599f, 500.392f, 646.7143f, 3.141593f }, // 56921
{ -622.946f, 483.113f, 646.7143f, 3.141593f }, // 56922
{ -613.104f, 488.776f, 646.7143f, 3.141593f }, // 56923
{ -606.915f, 477.097f, 646.7143f, 3.141593f }, // 56924
{ -640.717f, 480.623f, 646.7143f, 3.141593f }, // 56925
{ -627.049f, 486.917f, 646.7143f, 3.141593f }, // 56926
{ -623.059f, 476.104f, 646.7143f, 3.141593f }, // 56927
};
class boss_asaad : public CreatureScript
{
public:
boss_asaad() : CreatureScript("boss_asaad") { }
struct boss_asaadAI : public BossAI
{
boss_asaadAI(Creature* creature) : BossAI(creature, DATA_ASAAD) { }
void Reset() override
{
_Reset();
me->SetReactState(REACT_AGGRESSIVE);
events.ScheduleEvent(EVENT_SUMMON_SKYFALL_STAR, 11000);
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 14500);
events.ScheduleEvent(EVENT_SOTS, 18000);
if (IsHeroic())
events.ScheduleEvent(EVENT_STATIC_CLING, 10800);
}
void EnterCombat(Unit* /*target*/) override
{
_EnterCombat();
Talk(SAY_AGGRO);
// Spawn Storm Targets
for (uint32 i = 0; i < StormTargetPositions; i++)
if (Creature* stormTarget = me->SummonCreature(NPC_STORM_TARGET, StormTargetPositionData[i]))
stormTargetGUIDs.push_back(stormTarget->GetGUID());
}
void JustSummoned(Creature* creature) override
{
if (creature->GetEntry() == NPC_SKYFALL_STAR)
{
creature->SetReactState(REACT_PASSIVE);
creature->SetInCombatWithZone();
creature->CastSpell(creature, SPELL_ARCANE_BARRAGE_AURA);
}
BossAI::JustSummoned(creature);
}
void SpellHitTarget(Unit* target, const SpellInfo* spellInfo) override
{
if (spellInfo->Id != SPELL_SOTS_TARGETING || target->GetEntry() != NPC_STORM_TARGET)
return;
stormTargetA = target->ToCreature();
for (uint32 i = 0; i < StormTargetPositions; i++)
{
if (stormTargetGUIDs[i] != target->GetGUID())
continue;
stormTargetB = ObjectAccessor::GetCreature(*me, stormTargetGUIDs[i % 3 == 0 ? i + 1 : (i % 3 == 1 ? i - 1 : i - 2)]);
stormTargetC = ObjectAccessor::GetCreature(*me, stormTargetGUIDs[i % 3 == 0 ? i + 2 : (i % 3 == 1 ? i + 1 : i - 1)]);
ASSERT(stormTargetB);
ASSERT(stormTargetC);
break;
}
}
void DoAction(int32 action) override
{
if (action != ACTION_SUPREMACY_OF_THE_STORM)
return;
me->CastStop();
me->SetDisableGravity(true);
DoCast(me, SPELL_SUPREMACY_OF_THE_STORM_TELEPORT);
DoCast(me, SPELL_SUPREMACY_OF_THE_STORM);
events.ScheduleEvent(EVENT_SOTS_END, 6000);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_STATIC_CLING:
DoCast(me, SPELL_STATIC_CLING);
events.ScheduleEvent(EVENT_STATIC_CLING, 16000);
break;
case EVENT_SUMMON_SKYFALL_STAR:
DoCast(me, SPELL_SUMMON_SKYFALL_STAR);
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 14500);
break;
case EVENT_CHAIN_LIGHTNING:
DoCast(me, SPELL_CHAIN_LIGHTNING);
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 14500);
break;
case EVENT_SOTS:
Talk(SAY_SOTS_EMOTE);
events.Reset();
events.ScheduleEvent(EVENT_SOTS_START, 200);
events.ScheduleEvent(EVENT_SOTS, 45800);
break;
case EVENT_SOTS_START:
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
Talk(SAY_SOTS);
DoCast(me, SPELL_SOTS_TARGETING);
break;
case EVENT_SOTS_END:
ResetStormTargets();
me->SetDisableGravity(false);
events.ScheduleEvent(EVENT_ATTACK, 2000);
break;
case EVENT_ATTACK:
me->SetReactState(REACT_AGGRESSIVE);
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 100);
events.ScheduleEvent(EVENT_STATIC_CLING, 2000);
events.ScheduleEvent(EVENT_SUMMON_SKYFALL_STAR, 3500);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
Creature* GetSelectedStormTarget(uint32 point)
{
if (point == POINT_STORM_A)
return stormTargetA;
if (point == POINT_STORM_B)
return stormTargetB;
if (point == POINT_STORM_C)
return stormTargetC;
return NULL;
}
Position GetTriangleCenterPosition()
{
Position pos;
pos.m_positionX = (stormTargetA->GetPositionX() + stormTargetB->GetPositionX() + stormTargetC->GetPositionX()) / 3;
pos.m_positionY = (stormTargetA->GetPositionY() + stormTargetB->GetPositionY() + stormTargetC->GetPositionY()) / 3;
pos.m_positionZ = stormTargetA->GetPositionZ() + 8.0f;
return pos;
}
void ResetStormTargets()
{
stormTargetA->CastStop();
stormTargetB->CastStop();
stormTargetC->CastStop();
}
private:
GuidVector stormTargetGUIDs;
Creature* stormTargetA;
Creature* stormTargetB;
Creature* stormTargetC;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_asaadAI>(creature);
}
};
typedef boss_asaad::boss_asaadAI AsaadAI;
// 46387 - Storm Target
class npc_storm_target : public CreatureScript
{
public:
npc_storm_target() : CreatureScript("npc_storm_target") { }
struct npc_storm_targetAI : public ScriptedAI
{
npc_storm_targetAI(Creature* creature) : ScriptedAI(creature) { }
void DoAction(int32 action) override
{
if (action != ACTION_SOTS_TARGET)
return;
events.ScheduleEvent(EVENT_SOTS_SUMMON, 400);
}
void JustSummoned(Creature* creature) override
{
if (InstanceScript* instance = me->GetInstanceScript())
if (Creature* asaad = instance->GetCreature(DATA_ASAAD))
ENSURE_AI(AsaadAI, asaad->AI())->JustSummoned(creature);
}
void UpdateAI(uint32 diff) override
{
if (events.Empty())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SOTS_SUMMON:
DoCast(me, SPELL_SOTS_SUMMON);
break;
default:
break;
}
}
}
private:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<npc_storm_targetAI>(creature);
}
};
// 46492 - Unstable Grounding Field
class npc_unstable_grounding_field : public CreatureScript
{
public:
npc_unstable_grounding_field() : CreatureScript("npc_unstable_grounding_field") { }
struct npc_unstable_grounding_fieldAI : public ScriptedAI
{
npc_unstable_grounding_fieldAI(Creature* creature) : ScriptedAI(creature)
{
if (InstanceScript* instance = me->GetInstanceScript())
if (Creature* asaad = instance->GetCreature(DATA_ASAAD))
asaadAI = CAST_AI(AsaadAI, asaad->AI());
me->SetWalk(true);
events.ScheduleEvent(EVENT_STORM_ASSAD_CHANNEL, 400);
}
void MovementInform(uint32 movementType, uint32 pointId) override
{
if (movementType != POINT_MOTION_TYPE)
return;
switch (pointId)
{
case POINT_STORM_B:
if (Creature* stormTargetB = asaadAI->GetSelectedStormTarget(POINT_STORM_B))
stormTargetB->CastSpell((Unit*)NULL, SPELL_STORM_RUNE_BEAM_A);
events.ScheduleEvent(EVENT_STORM_MOVE_C, 1200);
break;
case POINT_STORM_C:
if (Creature* stormTargetB = asaadAI->GetSelectedStormTarget(POINT_STORM_C))
stormTargetB->CastSpell((Unit*)NULL, SPELL_STORM_RUNE_BEAM_B);
events.ScheduleEvent(EVENT_STORM_MOVE_A, 1200);
break;
case POINT_STORM_A:
{
if (Creature* stormTargetB = asaadAI->GetSelectedStormTarget(POINT_STORM_A))
stormTargetB->CastSpell((Unit*)NULL, SPELL_STORM_RUNE_BEAM_C);
DoCast(me, SPELL_STORM_SUMMON_GROUNDING_FIELD);
Position pos = asaadAI->GetTriangleCenterPosition();
me->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_STORM_SUMMON_GROUNDING_FIELD, true);
events.ScheduleEvent(EVENT_STORM_ASAAD_TELEPORT, 500);
break;
}
default:
break;
}
};
void UpdateAI(uint32 diff) override
{
if (events.Empty())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_STORM_ASSAD_CHANNEL:
DoCast(me, SPELL_SOTS_TRIGGER);
events.ScheduleEvent(EVENT_STORM_RUNE_BEAM_AA, 400);
break;
case EVENT_STORM_RUNE_BEAM_AA:
DoCast(me, SPELL_STORM_RUNE_BEAM_AA);
events.ScheduleEvent(EVENT_STORM_MOVE_B, 800);
break;
case EVENT_STORM_MOVE_B:
if (Creature* stormTargetB = asaadAI->GetSelectedStormTarget(POINT_STORM_B))
me->GetMotionMaster()->MovePoint(POINT_STORM_B, stormTargetB->GetPosition());
break;
case EVENT_STORM_MOVE_C:
DoCast(me, SPELL_STORM_RUNE_BEAM_B);
if (Creature* stormTargetC = asaadAI->GetSelectedStormTarget(POINT_STORM_C))
me->GetMotionMaster()->MovePoint(POINT_STORM_C, stormTargetC->GetPosition());
break;
case EVENT_STORM_MOVE_A:
me->CastStop();
DoCast(me, SPELL_STORM_RUNE_BEAM_C);
if (Creature* stormTargetA = asaadAI->GetSelectedStormTarget(POINT_STORM_A))
me->GetMotionMaster()->MovePoint(POINT_STORM_A, stormTargetA->GetPosition());
break;
case EVENT_STORM_ASAAD_TELEPORT:
asaadAI->DoAction(ACTION_SUPREMACY_OF_THE_STORM);
me->DespawnOrUnsummon(700);
break;
default:
break;
}
}
}
private:
AsaadAI* asaadAI;
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<npc_unstable_grounding_fieldAI>(creature);
}
};
// 47000 - Grounding Field
class npc_asaad_grounding_field : public CreatureScript
{
public:
npc_asaad_grounding_field() : CreatureScript("npc_asaad_grounding_field") { }
struct npc_asaad_grounding_fieldAI : public ScriptedAI
{
npc_asaad_grounding_fieldAI(Creature* creature) : ScriptedAI(creature)
{
me->SetDisableGravity(true);
events.ScheduleEvent(EVENT_GROUNDING_FIELD_VISUAL_BEAMS, 500);
}
void UpdateAI(uint32 diff) override
{
if (events.Empty())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_GROUNDING_FIELD_VISUAL_BEAMS:
DoCast(me, SPELL_GROUNDING_FIELD_VISUAL_BEAMS);
me->DespawnOrUnsummon(6000);
break;
default:
break;
}
}
}
private:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<npc_asaad_grounding_fieldAI>(creature);
}
};
// 86632 - SOTS Targeting
class spell_sots_targeting : public SpellScriptLoader
{
public:
spell_sots_targeting() : SpellScriptLoader("spell_sots_targeting") { }
class spell_sots_targeting_SpellScript : public SpellScript
{
PrepareSpellScript(spell_sots_targeting_SpellScript);
void SelectRandom(std::list<WorldObject*>& targets)
{
Trinity::Containers::RandomResizeList(targets, 1);
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Creature* creature = GetHitCreature())
creature->GetAI()->DoAction(ACTION_SOTS_TARGET);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sots_targeting_SpellScript::SelectRandom, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_sots_targeting_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_sots_targeting_SpellScript();
}
};
// 86926 - SOTS Trigger (makes Asaad channel Unstable Grounding Field)
class spell_sots_trigger : public SpellScriptLoader
{
public:
spell_sots_trigger() : SpellScriptLoader("spell_sots_trigger") { }
class spell_sots_trigger_SpellScript : public SpellScript
{
PrepareSpellScript(spell_sots_trigger_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_UNSTABLE_GROUNDING_FIELD))
return false;
return true;
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_UNSTABLE_GROUNDING_FIELD, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_sots_trigger_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_sots_trigger_SpellScript();
}
};
// 86981 - Storm Rune Beam AA
// 86921 - Storm Rune Beam A
// 86923 - Storm Rune Beam B
// 86925 - Storm Rune Beam C
class spell_storm_rune_beam : public SpellScriptLoader
{
public:
spell_storm_rune_beam() : SpellScriptLoader("spell_storm_rune_beam") { }
class spell_storm_rune_beam_SpellScript : public SpellScript
{
PrepareSpellScript(spell_storm_rune_beam_SpellScript);
void SetTarget(WorldObject*& target)
{
InstanceScript* instance = GetCaster()->GetInstanceScript();
if (!instance)
return;
Creature* asaad = instance->GetCreature(DATA_ASAAD);
if (!asaad)
return;
switch (GetSpellInfo()->Id)
{
case SPELL_STORM_RUNE_BEAM_AA:
case SPELL_STORM_RUNE_BEAM_A:
target = ENSURE_AI(AsaadAI, asaad->AI())->GetSelectedStormTarget(POINT_STORM_A);
break;
case SPELL_STORM_RUNE_BEAM_B:
target = ENSURE_AI(AsaadAI, asaad->AI())->GetSelectedStormTarget(POINT_STORM_B);
break;
case SPELL_STORM_RUNE_BEAM_C:
target = ENSURE_AI(AsaadAI, asaad->AI())->GetSelectedStormTarget(POINT_STORM_C);
break;
default:
break;
}
}
void Register() override
{
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_storm_rune_beam_SpellScript::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_storm_rune_beam_SpellScript();
}
};
// 87517 - Grounding Field Visual Beams
class spell_grounding_field_visual_beams : public SpellScriptLoader
{
public:
spell_grounding_field_visual_beams() : SpellScriptLoader("spell_grounding_field_visual_beams") { }
class spell_grounding_field_visual_beams_SpellScript : public SpellScript
{
PrepareSpellScript(spell_grounding_field_visual_beams_SpellScript);
void SetTargetA(WorldObject*& target)
{
target = GetStormTarget(POINT_STORM_A);
}
void SetTargetB(WorldObject*& target)
{
target = GetStormTarget(POINT_STORM_B);
}
void SetTargetC(WorldObject*& target)
{
target = GetStormTarget(POINT_STORM_C);
}
void Register() override
{
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_grounding_field_visual_beams_SpellScript::SetTargetA, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_grounding_field_visual_beams_SpellScript::SetTargetB, EFFECT_1, TARGET_UNIT_NEARBY_ENTRY);
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_grounding_field_visual_beams_SpellScript::SetTargetC, EFFECT_2, TARGET_UNIT_NEARBY_ENTRY);
}
private:
Creature* GetStormTarget(uint32 point)
{
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
if (Creature* asaad = instance->GetCreature(DATA_ASAAD))
return ENSURE_AI(AsaadAI, asaad->AI())->GetSelectedStormTarget(point);
return NULL;
}
};
SpellScript* GetSpellScript() const override
{
return new spell_grounding_field_visual_beams_SpellScript();
}
};
// 87553/93994 - Supremacy of the Storm (massive aoe damage)
class spell_supremacy_of_the_storm : public SpellScriptLoader
{
public:
spell_supremacy_of_the_storm() : SpellScriptLoader("spell_supremacy_of_the_storm") { }
class spell_supremacy_of_the_storm_SpellScript : public SpellScript
{
PrepareSpellScript(spell_supremacy_of_the_storm_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
InstanceScript* instance = GetCaster()->GetInstanceScript();
if (!instance)
return;
Creature* asaad = instance->GetCreature(DATA_ASAAD);
if (!asaad)
return;
AsaadAI* asaadAI = CAST_AI(AsaadAI, asaad->AI());
if (Creature* stormTargetA = asaadAI->GetSelectedStormTarget(POINT_STORM_A))
if (Creature* stormTargetB = asaadAI->GetSelectedStormTarget(POINT_STORM_B))
if (Creature* stormTargetC = asaadAI->GetSelectedStormTarget(POINT_STORM_C))
targets.remove_if(TargetInTriangleCheck(false, stormTargetA->GetPosition(), stormTargetB->GetPosition(), stormTargetC->GetPosition()));
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_supremacy_of_the_storm_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_supremacy_of_the_storm_SpellScript();
}
};
void AddSC_boss_asaad()
{
new boss_asaad();
new npc_storm_target();
new npc_unstable_grounding_field();
new npc_asaad_grounding_field();
new spell_sots_targeting();
new spell_sots_trigger();
new spell_storm_rune_beam();
new spell_grounding_field_visual_beams();
new spell_supremacy_of_the_storm();
}

View File

@@ -0,0 +1,337 @@
/*
* Copyright (C) 2008-2015 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 "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "Player.h"
#include "vortex_pinnacle.h"
enum Spells
{
SPELL_STORMS_EDGE_AURA = 86295,
SPELL_LIGHTNING_BOLT = 86331,
SPELL_SUMMON_TEMPEST = 86340,
SPELL_STORMS_EDGE_VISUAL = 86329,
SPELL_STORMS_EDGE_CYCLONE_SHIELD_AURA = 86310, // periodically triggers 86311
// Ertan's Vortex
SPELL_CYCLONE_SHIELD = 86267,
SPELL_CYCLONE_SHIELD_TRIGGER = 86292,
SPELL_STORMS_EDGE_SCRIPT = 86299, // targets closest cyclone and makes it cast SPELL_STORMS_EDGE_DAMAGE on caster
// SPELL_STORMS_EDGE_DAMAGE = 86309,
};
enum NPCs
{
NPC_ERTANS_VORTEX = 46007,
};
enum Texts
{
SAY_AGGRO = 0,
SAY_STORMS_EDGE = 1,
};
enum Actions
{
ACTION_STORMS_EDGE,
};
enum Events
{
EVENT_NONE,
EVENT_SUMMON_TEMPEST,
EVENT_STORMS_EDGE_SPAWN,
EVENT_STORMS_EDGE,
EVENT_STORMS_EDGE_AURA,
EVENT_STORMS_EDGE_END,
// Ertan's Vortex
EVENT_MOVE_POINT,
};
enum Points
{
POINT_ERTANS_VORTEX_S = 0,
POINT_ERTANS_VORTEX_SW = 1,
POINT_ERTANS_VORTEX_W = 2,
POINT_ERTANS_VORTEX_NW = 3,
POINT_ERTANS_VORTEX_N = 4,
POINT_ERTANS_VORTEX_NE = 5,
POINT_ERTANS_VORTEX_E = 6,
POINT_ERTANS_VORTEX_SE = 7,
POINT_ERTANS_VORTEX_MAX = 8,
POINT_NONE,
};
const Position ErtansVortexPoints[POINT_ERTANS_VORTEX_MAX] =
{
{ -744.889f, 3.98611f, 635.6728f }, // South
{ -737.552f, 21.592f, 635.6728f }, // South-West
{ -719.802f, 28.8351f, 635.6728f }, // West
{ -702.144f, 21.9878f, 635.6728f }, // North-West
{ -694.911f, 4.16493f, 635.6728f }, // North
{ -702.212f, -13.6806f, 635.6728f }, // North-East
{ -719.934f, -20.9497f, 635.6728f }, // East
{ -737.649f, -13.5347f, 635.6728f }, // South-East
};
const Position ErtansVortexMiddlePoints[POINT_ERTANS_VORTEX_MAX] =
{
{ -724.3819f, 2.915083f, 635.6728f }, // South
{ -724.0161f, 6.648534f, 635.6728f }, // South-West
{ -721.1381f, 9.082433f, 635.6728f }, // West
{ -716.7177f, 8.423817f, 635.6728f }, // North-West
{ -714.6548f, 5.146466f, 635.6728f }, // North
{ -715.2417f, 1.857746f, 635.6728f }, // North-East
{ -718.2345f, -0.4830246f, 635.6728f }, // East
{ -721.9816f, -0.05864143f, 635.6728f }, // South-East
};
class boss_grand_vizier_ertan : public CreatureScript
{
public:
boss_grand_vizier_ertan() : CreatureScript("boss_grand_vizier_ertan") { }
struct boss_grand_vizier_ertanAI : public BossAI
{
boss_grand_vizier_ertanAI(Creature* creature) : BossAI(creature, DATA_GRAND_VIZIER_ERTAN)
{
me->SetDisableGravity(true);
SetCombatMovement(false);
}
void Reset() override
{
_Reset();
// Should have, but gets stuck in evade mode...
//me->AddUnitState(UNIT_STATE_ROOT);
events.ScheduleEvent(EVENT_STORMS_EDGE_SPAWN, 400);
events.ScheduleEvent(EVENT_STORMS_EDGE, 23000);
if (IsHeroic())
events.ScheduleEvent(EVENT_SUMMON_TEMPEST, 17000);
}
void EnterCombat(Unit* /*target*/) override
{
_EnterCombat();
SummonErtansVortexes();
DoCast(me, SPELL_STORMS_EDGE_AURA);
Talk(SAY_AGGRO);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SUMMON_TEMPEST:
DoCast(me, SPELL_SUMMON_TEMPEST);
events.ScheduleEvent(EVENT_SUMMON_TEMPEST, 17000);
break;
case EVENT_STORMS_EDGE:
{
DoCast(me, SPELL_STORMS_EDGE_VISUAL);
EntryCheckPredicate pred(NPC_ERTANS_VORTEX);
summons.DoAction(ACTION_STORMS_EDGE, pred);
Talk(SAY_STORMS_EDGE);
events.ScheduleEvent(EVENT_STORMS_EDGE_AURA, 3000);
events.ScheduleEvent(EVENT_STORMS_EDGE, 32000);
break;
}
case EVENT_STORMS_EDGE_AURA:
me->RemoveAurasDueToSpell(SPELL_STORMS_EDGE_AURA);
DoCast(me, SPELL_STORMS_EDGE_CYCLONE_SHIELD_AURA);
events.ScheduleEvent(EVENT_STORMS_EDGE_END, 6000);
break;
case EVENT_STORMS_EDGE_END:
me->RemoveAurasDueToSpell(SPELL_STORMS_EDGE_CYCLONE_SHIELD_AURA);
DoCast(me, SPELL_STORMS_EDGE_AURA);
break;
default:
break;
}
}
DoSpellAttackIfReady(SPELL_LIGHTNING_BOLT);
}
private:
void SummonErtansVortexes() // Summons Ertan's Vortex at each point and makes them move to the next point
{
for (int8 i = 0; i < POINT_ERTANS_VORTEX_MAX; i++)
{
if (Creature* ertansVortex = me->SummonCreature(NPC_ERTANS_VORTEX, ErtansVortexPoints[i]))
{
if (i == POINT_ERTANS_VORTEX_SE)
ertansVortex->GetMotionMaster()->MovePoint(POINT_ERTANS_VORTEX_S, ErtansVortexPoints[POINT_ERTANS_VORTEX_S]);
else
ertansVortex->GetMotionMaster()->MovePoint(i + 1, ErtansVortexPoints[i + 1]);
}
}
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_grand_vizier_ertanAI>(creature);
}
};
// 46007 - Ertan's Vortex
class npc_ertans_vortex : public CreatureScript
{
public:
npc_ertans_vortex() : CreatureScript("npc_ertans_vortex") { }
struct npc_ertans_vortexAI : public ScriptedAI
{
npc_ertans_vortexAI(Creature* creature) : ScriptedAI(creature)
{
currentPointId = 0;
DoCast(me, SPELL_CYCLONE_SHIELD);
}
void DoAction(int32 action) override
{
if (action != ACTION_STORMS_EDGE)
return;
me->GetMotionMaster()->MovePoint(POINT_NONE, ErtansVortexMiddlePoints[currentPointId]);
events.ScheduleEvent(EVENT_MOVE_POINT, 9000);
}
void MovementInform(uint32 movementType, uint32 pointId) override
{
if (movementType != POINT_MOTION_TYPE || pointId == POINT_NONE)
return;
if (pointId < POINT_ERTANS_VORTEX_SE)
currentPointId = pointId + 1;
else
currentPointId = POINT_ERTANS_VORTEX_S;
events.ScheduleEvent(EVENT_MOVE_POINT, 1);
};
void UpdateAI(uint32 diff) override
{
if (events.Empty())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_MOVE_POINT:
me->GetMotionMaster()->MovePoint(currentPointId, ErtansVortexPoints[currentPointId]);
break;
default:
break;
}
}
}
private:
EventMap events;
uint32 currentPointId;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<npc_ertans_vortexAI>(creature);
}
};
// 86284 - Storm's Edge (targets players outside cyclone ring/further than 25 yards and makes them cast 86299)
// 86311 - Storm's Edge (targets all players and makes them cast 86299)
class spell_storms_edge : public SpellScriptLoader
{
public:
spell_storms_edge() : SpellScriptLoader("spell_storms_edge") { }
class spell_storms_edge_SpellScript : public SpellScript
{
PrepareSpellScript(spell_storms_edge_SpellScript);
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetHitUnit(), SPELL_STORMS_EDGE_SCRIPT, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_storms_edge_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_storms_edge_SpellScript();
}
};
// 86299 - Storm's Edge (targets closest Ertan's Vortex and makes it cast 86309 on caster)
class spell_storms_edge_script : public SpellScriptLoader
{
public:
spell_storms_edge_script() : SpellScriptLoader("spell_storms_edge_script") { }
class spell_storms_edge_script_SpellScript : public SpellScript
{
PrepareSpellScript(spell_storms_edge_script_SpellScript);
void HandleScript(SpellEffIndex /*effIndex*/)
{
GetHitUnit()->CastSpell(GetCaster(), uint32(GetEffectValue()), true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_storms_edge_script_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_storms_edge_script_SpellScript();
}
};
void AddSC_boss_grand_vizier_ertan()
{
new boss_grand_vizier_ertan();
new npc_ertans_vortex();
new spell_storms_edge();
new spell_storms_edge_script();
}

View File

@@ -0,0 +1,230 @@
/*
* Copyright (C) 2008-2015 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 "ScriptMgr.h"
#include "Player.h"
#include "CreatureGroups.h"
#include "Vehicle.h"
#include "InstanceScript.h"
#include "vortex_pinnacle.h"
#define MAX_ENCOUNTER 3
/* The Vortex Pinnacle encounters:
0 - Grand Vizier Ertan
1 - Altairus
2 - Asaad
*/
struct Slipstream
{
uint32 entry;
uint32 vehicleId;
Position position;
uint32 data;
uint32 bossData; // boss that has to die/be dead for Slipstream to spawn
};
Slipstream const SlipstreamData[Slipstreams] =
{
// Grand Vizier Ertan Slipstreams
{ NPC_SLIPSTREAM, 1111, { -775.517f, -70.9323f, 640.3123f, 0.0f }, DATA_SLIPSTREAM_1, DATA_GRAND_VIZIER_ERTAN },
{ NPC_SLIPSTREAM, 1112, { -848.227f, -68.724f, 654.2203f, 0.0f }, DATA_SLIPSTREAM_2, DATA_GRAND_VIZIER_ERTAN },
{ NPC_SLIPSTREAM, 1113, { -844.885f, -205.135f, 660.7083f, 0.0f }, DATA_SLIPSTREAM_3, DATA_GRAND_VIZIER_ERTAN },
// Grand Vizier Ertan Slipstream Landing Zone
{ NPC_SLIPSTREAM_LANDING_ZONE, 1114, { -906.08f, -176.514f, 664.5053f, 2.86234f }, 0, DATA_GRAND_VIZIER_ERTAN },
// Altairus Slipstreams
{ NPC_SLIPSTREAM, 1111, { -1190.88f, 125.203f, 737.6243f, 0.0f }, DATA_SLIPSTREAM_4, DATA_ALTAIRUS },
{ NPC_SLIPSTREAM, 1112, { -1138.55f, 178.524f, 711.4943f, 0.0f }, DATA_SLIPSTREAM_5, DATA_ALTAIRUS },
{ NPC_SLIPSTREAM, 1149, { -1245.21f, 230.986f, 690.6083f, 0.0f }, DATA_SLIPSTREAM_6, DATA_ALTAIRUS },
{ NPC_SLIPSTREAM, 1150, { -1282.07f, 344.856f, 660.9873f, 0.0f }, DATA_SLIPSTREAM_7, DATA_ALTAIRUS },
{ NPC_SLIPSTREAM, 1113, { -1229.64f, 412.26f, 641.2933f, 0.0f }, DATA_SLIPSTREAM_8, DATA_ALTAIRUS },
// Altairus Slipstream Landing Zone
{ NPC_SLIPSTREAM_LANDING_ZONE, 1114, { -1193.67f, 472.835f, 634.8653f, 0.5061455f }, 0, DATA_ALTAIRUS },
// Asaad Slipstream
{ NPC_SLIPSTREAM, 1551, { -746.9566f, 529.1406f, 644.8316f, 0.0f }, DATA_SLIPSTREAM_9, DATA_ASAAD },
// Entrance Slipstreams
{ NPC_SLIPSTREAM, 1305, { -310.4583f, -29.74479f, 625.0833f, 0.0f }, DATA_SLIPSTREAM_10, DATA_GRAND_VIZIER_ERTAN },
{ NPC_SLIPSTREAM, 1306, { -382.441f, 42.31597f, 625.0833f, 0.0f }, DATA_SLIPSTREAM_11, DATA_ALTAIRUS },
};
Position const SouthZephyrSummonLocation = { -1070.639f, 432.2814f, 647.0389f, 6.15166f };
Position const NorthZephyrSummonLocation = { -781.4438f, 491.1446f, 698.0991f, 0.3193802f };
Position const FirstPrismGroundingFieldTop = { -1008.997f, 474.3663f, 708.1033f, 0.0f };
Position const FirstPrismGroundingFieldPoints[PrismGroundingFieldPoints] =
{
{ -990.934f, 466.7552f, 700.0436f, 0.0f },
{ -1021.677f, 461.6684f, 700.1023f, 0.0f },
{ -1016.434f, 492.8455f, 700.0325f, 0.0f },
};
Position const SecondPrismGroundingFieldTop = { -829.7674f, 477.9531f, 708.1063f, 4.328416f };
Position const SecondPrismGroundingFieldPoints[PrismGroundingFieldPoints] =
{
{ -851.3368f, 469.3629f, 700.0286f, 4.328416f },
{ -820.2327f, 468.5017f, 700.1062f, 4.328416f },
{ -821.4792f, 500.3004f, 700.0289f, 4.328416f },
};
ObjectData const creatureData[] =
{
{ NPC_ALTAIRUS, DATA_ALTAIRUS },
{ NPC_ASAAD, DATA_ASAAD },
{ 0, 0 }
};
class instance_vortex_pinnacle : public InstanceMapScript
{
public:
instance_vortex_pinnacle() : InstanceMapScript(SCScriptName, 657) { }
struct instance_vortex_pinnacle_InstanceScript : public InstanceScript
{
instance_vortex_pinnacle_InstanceScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTER);
LoadObjectData(creatureData, nullptr);
CheckSlipstreams();
SummonGroundingFieldPrism(FirstPrismGroundingFieldTop, FirstPrismGroundingFieldPoints);
SummonGroundingFieldPrism(SecondPrismGroundingFieldTop, SecondPrismGroundingFieldPoints);
events.ScheduleEvent(EVENT_SUMMON_ZEPHYRS, 0);
}
void OnCreatureCreate(Creature* creature) override
{
switch (creature->GetEntry())
{
case NPC_HOWLING_GALE:
creature->SetReactState(REACT_PASSIVE);
break;
default:
break;
}
InstanceScript::OnCreatureCreate(creature);
}
bool SetBossState(uint32 type, EncounterState state) override
{
InstanceScript::SetBossState(type, state);
// Spawn Slipstreams
if (state == DONE)
SummonSlipstreams(type);
return true;
}
void Update(uint32 diff) override
{
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SUMMON_ZEPHYRS: // Summon Zephyrs every 10 seconds. There is no sniff data about trigger npc or spells that would handle summoning.
if (TempSummon* zephyr = instance->SummonCreature(NPC_ZEPHYR, SouthZephyrSummonLocation))
zephyr->GetMotionMaster()->MovePath(PATH_ZEPHYR_SOUTH, false);
if (TempSummon* zephyr = instance->SummonCreature(NPC_ZEPHYR, NorthZephyrSummonLocation))
zephyr->GetMotionMaster()->MovePath(PATH_ZEPHYR_NORTH, false);
events.ScheduleEvent(EVENT_SUMMON_ZEPHYRS, 10000);
break;
default:
break;
}
}
}
private:
// Check which Slipstreams can be spawned on script init
void CheckSlipstreams()
{
if (GetBossState(DATA_GRAND_VIZIER_ERTAN) == DONE)
SummonSlipstreams(DATA_GRAND_VIZIER_ERTAN);
if (GetBossState(DATA_ALTAIRUS) == DONE)
SummonSlipstreams(DATA_ALTAIRUS);
if (GetBossState(DATA_ASAAD) == DONE)
SummonSlipstreams(DATA_ASAAD);
}
// Spawns Slipstreams belonging bossType
void SummonSlipstreams(uint32 bossType)
{
for (uint8 i = 0; i < Slipstreams; ++i)
{
if (SlipstreamData[i].bossData != bossType)
continue;
TempSummon* summon = instance->SummonCreature(SlipstreamData[i].entry, SlipstreamData[i].position);
if (!summon)
continue;
AddObject(summon, SlipstreamData[i].data, true);
if (SlipstreamData[i].data == DATA_SLIPSTREAM_1 || SlipstreamData[i].data == DATA_SLIPSTREAM_4 ||
SlipstreamData[i].data == DATA_SLIPSTREAM_10 || SlipstreamData[i].data == DATA_SLIPSTREAM_11)
{
summon->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, summon->GetPackGUID().size() + 4);
data << summon->GetPackGUID();
data << uint32(SlipstreamData[i].vehicleId);
summon->SendMessageToSet(&data, true);
}
}
// Spawns Grounding Field prism
void SummonGroundingFieldPrism(Position positionTop, const Position positionPoints[PrismGroundingFieldPoints])
{
// Spawn lower three grounding fields
TempSummon* points[PrismGroundingFieldPoints];
for (uint32 i = 0; i < PrismGroundingFieldPoints; i++)
points[i] = instance->SummonCreature(NPC_GROUNDING_FIELD, positionPoints[i]);
// If all three grounding fields spawned, cast beams and spawn the upper grounding field
if (points[0] && points[1] && points[2])
{
points[1]->CastSpell(points[0], SPELL_BEAM_A, true);
points[2]->CastSpell(points[1], SPELL_BEAM_B, true);
points[0]->CastSpell(points[2], SPELL_BEAM_C, true);
if (TempSummon* top = instance->SummonCreature(NPC_GROUNDING_FIELD, positionTop))
top->ToCreature()->GetAI()->DoAction(ACTION_GROUNDING_FIELD_TOP);
}
}
EventMap events;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_vortex_pinnacle_InstanceScript(map);
}
};
void AddSC_instance_vortex_pinnacle()
{
new instance_vortex_pinnacle();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2008-2015 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/>.
*/
#ifndef DEF_VORTEX_PINNACLE_H
#define DEF_VORTEX_PINNACLE_H
#define SCScriptName "instance_vortex_pinnacle"
#define DataHeader "VP"
#include "G3D/Vector3.h"
#include "G3D/Triangle.h"
#include "G3D/Plane.h"
#include "G3D/CollisionDetection.h"
uint32 const Slipstreams = 13;
uint32 const PrismGroundingFieldPoints = 3;
enum DataTypes
{
// Encounter States/Boss GUIDs
DATA_GRAND_VIZIER_ERTAN,
DATA_ALTAIRUS,
DATA_ASAAD,
// Additional Data
DATA_SLIPSTREAM,
DATA_SLIPSTREAM_1,
DATA_SLIPSTREAM_2,
DATA_SLIPSTREAM_3,
DATA_SLIPSTREAM_4,
DATA_SLIPSTREAM_5,
DATA_SLIPSTREAM_6,
DATA_SLIPSTREAM_7,
DATA_SLIPSTREAM_8,
DATA_SLIPSTREAM_9,
DATA_SLIPSTREAM_10,
DATA_SLIPSTREAM_11,
};
enum Misc
{
NPC_GRAND_VIZIER_ERTAN = 43878,
NPC_ALTAIRUS = 43873,
NPC_ASAAD = 43875,
NPC_SLIPSTREAM = 45455,
NPC_SLIPSTREAM_LANDING_ZONE = 45504,
NPC_HOWLING_GALE = 45572,
// Grounding Field
NPC_GROUNDING_FIELD = 47085,
SPELL_BEAM_A = 87721,
SPELL_BEAM_B = 87722,
SPELL_BEAM_C = 87723,
ACTION_GROUNDING_FIELD_TOP = 1,
// Zephyr
NPC_ZEPHYR = 45991,
EVENT_SUMMON_ZEPHYRS = 1,
PATH_ZEPHYR_SOUTH = 4599100,
PATH_ZEPHYR_NORTH = 4599101,
};
class TargetInTriangleCheck
{
public:
TargetInTriangleCheck(bool negate, Position positionA, Position positionB, Position positionC)
: negate(negate), positionA(positionA), positionB(positionB), positionC(positionC) { }
bool operator()(WorldObject* target) const
{
return negate != IsInTriangle(target);
}
private:
bool IsInTriangle(WorldObject* target) const
{
G3D::Triangle const triangle(PositionToVector3(positionA), PositionToVector3(positionB), PositionToVector3(positionC));
G3D::Vector3 const vector(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
float b[3];
return G3D::CollisionDetection::isPointInsideTriangle(triangle.vertex(0), triangle.vertex(1), triangle.vertex(2), triangle.normal(), vector, b, triangle.primaryAxis());
}
G3D::Vector3 PositionToVector3(Position const& position) const
{
return G3D::Vector3(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ());
}
bool const negate;
Position const positionA;
Position const positionB;
Position const positionC;
};
#endif // DEF_VORTEX_PINNACLE_H