From b75b8eba07c26fb21f3e59b8aeb8f315761eb327 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Mon, 5 Aug 2019 20:13:16 +0200 Subject: [PATCH] Scripts/BWD: implement heroic difficulty mechanics and finish Maloriak Encounter implementation --- .../custom/custom_2019_08_05_00_world.sql | 217 +++++++ src/server/game/Spells/SpellMgr.cpp | 8 +- .../BlackwingDescent/blackwing_descent.h | 6 +- .../BlackwingDescent/boss_maloriak.cpp | 592 ++++++++++++++++-- .../instance_blackwing_descent.cpp | 2 + 5 files changed, 774 insertions(+), 51 deletions(-) create mode 100644 sql/updates/world/custom/custom_2019_08_05_00_world.sql diff --git a/sql/updates/world/custom/custom_2019_08_05_00_world.sql b/sql/updates/world/custom/custom_2019_08_05_00_world.sql new file mode 100644 index 00000000000..1d9fa218712 --- /dev/null +++ b/sql/updates/world/custom/custom_2019_08_05_00_world.sql @@ -0,0 +1,217 @@ +-- Template Updates +-- Maloriak +UPDATE `creature_template` SET `ScriptName`= 'boss_maloriak' WHERE `entry`= 41378; +UPDATE `creature_template` SET `speed_run`= 1.71429, `DamageModifier`= 120, `BaseVariance`= 0.5, `mechanic_immune_mask`= 617299839 WHERE `entry` IN (41378, 49974, 49980, 49986); +-- Flash Freeze +UPDATE `creature_template` SET `difficulty_entry_1`= 49973, `difficulty_entry_2`= 49979, `difficulty_entry_3`= 49985, `ScriptName`= 'npc_maloriak_flash_freeze' WHERE `entry`= 41576; +UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 14, `unit_flags`= 33554432, `mechanic_immune_mask`= 650854271, `flags_extra`= 128 | 1073741824, `exp`= 3 WHERE `entry` IN (41576, 49973, 49979, 49985); +-- Aberration +UPDATE `creature_template` SET `difficulty_entry_1`= 49971, `difficulty_entry_2`= 49977, `difficulty_entry_3`= 49983, `ScriptName`= 'npc_maloriak_experiment' WHERE `entry`= 41440; +UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 103, `unit_flags`= 33554688, `DamageModifier`= 15, `BaseVariance`= 0.5, `mechanic_immune_mask`= 8388608, `flags_extra`= 0x00000200 WHERE `entry` IN (41440, 49971, 49977, 49983); +-- Prime Subject +UPDATE `creature_template` SET `difficulty_entry_1`= 49975, `difficulty_entry_2`= 49981, `difficulty_entry_3`= 49987, `ScriptName`= 'npc_maloriak_experiment' WHERE `entry`= 41841; +UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 103, `speed_run`= 1, `unit_flags`= 33554688, `DamageModifier`= 30, `BaseVariance`= 0.5, `mechanic_immune_mask`= 667893631, `flags_extra`= 0x00000200 | 0x40000000 WHERE `entry` IN (41841, 49975, 49981, 49987); +-- Magma Jet +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `ScriptName`= 'npc_maloriak_magma_jet' WHERE `entry`= 50030; +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `AIName`= 'NullCreatureAI' WHERE `entry`= 41901; +-- Absolute Zero +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `AIName`= 'NullCreatureAI' WHERE `entry`= 41961; +-- Lord Victor Nefarius +UPDATE `creature_template` SET `unit_flags`= 33554496, `ScriptName`= 'npc_maloriak_lord_victor_nefarius' WHERE `entry`= 49799; +-- Vile Swill Pre-Effect +UPDATE `creature_template` SET `unit_flags`= 33554432, `flags_extra`= 128, `AIName`= 'NullCreatureAI' WHERE `entry`= 49812; +-- Vile Swill +UPDATE `creature_template` SET `difficulty_entry_1`= 49976, `difficulty_entry_2`= 49982, `difficulty_entry_3`= 49988, `ScriptName`= 'npc_maloriak_vile_swill' WHERE `entry`= 49811; +UPDATE `creature_template` SET `minlevel`= 88, `maxlevel`= 88, `exp`= 3, `faction`= 14, `DamageModifier`= 30, `BaseVariance`= 0.5, `mechanic_immune_mask`= 8388608 WHERE `entry` IN (49811, 49976, 49982, 49988); + +-- Spells +DELETE FROM `spell_script_names` WHERE `ScriptName` IN +('spell_maloriak_throw_bottle', +'spell_maloriak_throw_bottle_triggered', +'spell_maloriak_consuming_flames', +'spell_maloriak_flash_freeze_targeting', +'spell_maloriak_flash_freeze_dummy', +'spell_maloriak_release_experiments', +'spell_maloriak_magma_jets_periodic', +'spell_maloriak_absolute_zero', +'spell_maloriak_vile_swill_summon', +'spell_maloriak_vile_swill', +'spell_maloriak_master_adventurer_award'); + +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(77925, 'spell_maloriak_throw_bottle'), +(77932, 'spell_maloriak_throw_bottle'), +(77937, 'spell_maloriak_throw_bottle'), +(92831, 'spell_maloriak_throw_bottle'), +(77928, 'spell_maloriak_throw_bottle_triggered'), +(77934, 'spell_maloriak_throw_bottle_triggered'), +(77938, 'spell_maloriak_throw_bottle_triggered'), +(92837, 'spell_maloriak_throw_bottle_triggered'), +(77786, 'spell_maloriak_consuming_flames'), +(92971, 'spell_maloriak_consuming_flames'), +(92972, 'spell_maloriak_consuming_flames'), +(92973, 'spell_maloriak_consuming_flames'), +(97693, 'spell_maloriak_flash_freeze_targeting'), +(77716, 'spell_maloriak_flash_freeze_dummy'), +(77569, 'spell_maloriak_release_experiments'), +(77991, 'spell_maloriak_release_experiments'), +(93018, 'spell_maloriak_magma_jets_periodic'), +(78206, 'spell_maloriak_absolute_zero'), +(92737, 'spell_maloriak_vile_swill_summon'), +(92720, 'spell_maloriak_vile_swill'), +(89798, 'spell_maloriak_master_adventurer_award'); + +-- Texts +DELETE FROM `creature_text` WHERE `CreatureID` IN (41378, 49799); +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `comment`) VALUES +-- Maloriak +(41378, 0, 0, 'There can be no disruptions! Mustn\'t keep the master waiting! Mustn\'t fail again!', 14, 0, 100, 0, 0, 19847, 47028, 'Maloriak to Player'), +(41378, 1, 0, 'Mix and stir, apply heat...', 14, 0, 100, 0, 0, 19851, 41594, 'Maloriak to Maloriak'), +(41378, 2, 0, '|TInterface\\Icons\\INV_POTION_24.BLP:20|tMaloriak throws a |cFFFF0000red|r vial into the cauldron!', 41, 0, 100, 0, 0, 0, 47036, 'Maloriak to Maloriak'), +(41378, 3, 0, 'How well does the mortal shell handle extreme temperature change? Must find out! For science!', 14, 0, 100, 0, 0, 19853, 41595, 'Maloriak to Maloriak'), +(41378, 4, 0, '|TInterface\\Icons\\INV_POTION_20.BLP:20|tMaloriak throws a |cFF809FFEblue|r vial into the cauldron!', 41, 0, 100, 0, 0, 0, 47037, 'Maloriak to Maloriak'), +(41378, 5, 0, 'This one\'s a little unstable, but what\'s progress without failure?', 14, 0, 100, 0, 0, 19852, 41596, 'Maloriak to Maloriak'), +(41378, 6, 0, '|TInterface\\Icons\\INV_POTION_162.BLP:20|tMaloriak throws a |cFF33FF00green|r vial into the cauldron!', 41, 0, 100, 0, 0, 0, 47038, 'Maloriak to Maloriak'), +(41378, 7, 0, 'What they lack in intelligence they make up for in ferocity!', 14, 0, 100, 0, 0, 19856, 47032, 'Maloriak'), +(41378, 7, 1, 'My failings will be your downfall!', 14, 0, 100, 0, 0, 19857, 47033, 'Maloriak'), +(41378, 8, 0, 'Meet the brawn to my brains! Prime subjects, devour them!', 14, 0, 100, 0, 0, 19859, 47035, 'Maloriak'), +(41378, 8, 1, 'Too early, but no choice... They must be tested! Face now my prime subjects!', 14, 0, 100, 0, 0, 19858, 47034, 'Maloriak'), +(41378, 8, 2, 'When pushed to the edge, results may become unpredictable...', 14, 0, 100, 0, 0, 19854, 41625, 'Maloriak'), +(41378, 9, 0, 'Nothing goes to waste... ', 14, 0, 100, 0, 0, 19848, 47029, 'Maloriak'), +(41378, 9, 1, 'Strip the flesh, harvest the organs!', 14, 0, 100, 0, 0, 19849, 47030, 'Maloriak'), +(41378, 10, 0, 'There will never be another like me...', 14, 0, 100, 0, 0, 19850, 47031, 'Maloriak to Player'), +-- Lord Victor Nefarius +(49799, 0, 0, 'Maloriak, try not to lose to these mortals. Semicompetent help is SO hard to create.', 14, 0, 100, 0, 0, 23372, 49068, 'Lord Victor Nefarius to Player'), +(49799, 1, 0, 'Your mixtures are weak, Maloriak! They need a bit more... kick!', 14, 0, 100, 0, 0, 23370, 49069, 'Lord Victor Nefarius to Maloriak'), +(49799, 2, 0, '|TInterface\\Icons\\INV_ELEMENTAL_PRIMAL_SHADOW.BLP:20|t%s throws |cFF660099dark|r magic into the cauldron!', 41, 0, 100, 0, 0, 0, 49793, 'Lord Victor Nefarius to Maloriak'), +(49799, 3, 0, 'Congratulations! Allow me to grant you a title befitting the amazing achievement you just performed. Henceforth you shall be known as the \"Slayer of Stupid, Incompetent, and Disappointing Minions.\"', 14, 0, 100, 21, 0, 23371, 49070, 'Lord Victor Nefarius to Player'); + +-- Conditions +DELETE FROM `conditions` WHERE `SourceEntry` IN (77925, 77932, 77937, 92831, 77928, 77934, 77938, 92837, 77948, 77615, 77569, 77716, 77715, 95655, 95656, 95657) AND `SourceTypeOrReferenceId`= 13; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES +(13, 1, 77925, 0, 0, 31, 0, 3, 41505, 0, 0, 0, '', 'Throw Red Bottle - Target Cauldron Trigger'), +(13, 1, 77932, 0, 0, 31, 0, 3, 41505, 0, 0, 0, '', 'Throw Blue Bottle - Target Cauldron Trigger'), +(13, 1, 77937, 0, 0, 31, 0, 3, 41505, 0, 0, 0, '', 'Throw Green Bottle - Target Cauldron Trigger'), +(13, 1, 92831, 0, 0, 31, 0, 3, 41505, 0, 0, 0, '', 'Throw Black Bottle - Target Cauldron Trigger'), +(13, 1, 77928, 0, 0, 31, 0, 3, 41505, 0, 0, 0, '', 'Throw Red Bottle - Target Cauldron Trigger'), +(13, 1, 77934, 0, 0, 31, 0, 3, 41505, 0, 0, 0, '', 'Throw Blue Bottle - Target Cauldron Trigger'), +(13, 1, 77938, 0, 0, 31, 0, 3, 41505, 0, 0, 0, '', 'Throw Green Bottle - Target Cauldron Trigger'), +(13, 1, 92837, 0, 0, 31, 0, 3, 41505, 0, 0, 0, '', 'Throw Black Bottle - Target Cauldron Trigger'), +(13, 2, 77948, 0, 0, 31, 0, 3, 41378, 0, 0, 0, '', 'Dibilitating Slime - Target Maloriak'), +(13, 4, 77948, 0, 0, 31, 0, 3, 41440, 0, 0, 0, '', 'Dibilitating Slime - Target Aberration'), +(13, 2, 77615, 0, 0, 31, 0, 3, 41378, 0, 0, 0, '', 'Dibilitating Slime - Target Maloriak'), +(13, 4, 77615, 0, 0, 31, 0, 3, 41440, 0, 0, 0, '', 'Dibilitating Slime - Target Aberration'), +(13, 4, 77615, 0, 1, 31, 0, 3, 41841, 0, 0, 0, '', 'Dibilitating Slime - Target Prime Subject'), +(13, 1, 77569, 0, 0, 31, 0, 3, 41440, 0, 0, 0, '', 'Release Aberrations - Target Aberration'), +(13, 1, 77716, 0, 0, 31, 0, 3, 41576, 0, 0, 0, '', 'Flash Freeze - Target Flash Freeze'), +(13, 2, 77715, 0, 0, 31, 0, 3, 41576, 0, 0, 0, '', 'Shatter - Target Flash Freeze'), +(13, 2, 95655, 0, 0, 31, 0, 3, 41576, 0, 0, 0, '', 'Shatter - Target Flash Freeze'), +(13, 2, 95656, 0, 0, 31, 0, 3, 41576, 0, 0, 0, '', 'Shatter - Target Flash Freeze'), +(13, 2, 95657, 0, 0, 31, 0, 3, 41576, 0, 0, 0, '', 'Shatter - Target Flash Freeze'); + +-- Procs +DELETE FROM `spell_proc` WHERE `SpellId` IN (77786, 92971, 92972, 92973); +INSERT INTO `spell_proc` (`SpellId`, `ProcFlags`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`, `Charges`, `AttributesMask`) VALUES +(77786, 0x00020000, 0, 0, 0, 0, 2), +(92971, 0x00020000, 0, 0, 0, 0, 2), +(92972, 0x00020000, 0, 0, 0, 0, 2), +(92973, 0x00020000, 0, 0, 0, 0, 2); + +-- Custom Attributes +DELETE FROM `spell_custom_attr` WHERE `entry` IN (77679, 92968, 92969, 92970); +INSERT INTO `spell_custom_attr` (`entry`, `attributes`) VALUES +(77679, 0x00000008), +(92968, 0x00000008), +(92969, 0x00000008), +(92970, 0x00000008); + +-- Addons +DELETE FROM `creature_template_addon` WHERE `entry` IN (41440, 41841, 41901, 50030, 41961, 49799, 49812, 49971, 49977, 49983, 49975, 49981, 49987); +INSERT INTO `creature_template_addon` (`entry`, `auras`) VALUES +-- Aberration +(41440, '91334, 77564'), +(49971, '91334, 77564'), +(49977, '91334, 77564'), +(49983, '91334, 77564'), +-- Prime Subject +(41841, '91334, 77564'), +(49975, '91334, 77564'), +(49981, '91334, 77564'), +(49987, '91334, 77564'), +-- Magma Jet +(50030, '93018'), +-- Lord Victor Nefarius +(49799, '78494'), +-- Vile Swill Pre-Effect +(49812, '92737'); + +DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (41440, 41841, 49799, 49812); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Flight`, `Rooted`) VALUES +(49799, 1, 1, 0), +(49812, 0, 1, 1); + +-- Summon Groups +DELETE FROM `creature_summon_groups` WHERE `summonerId`= 41378 AND `summonerType`= 0; +INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`) VALUES +-- Aberration +(41378, 0, 0, 41440, -149.401, -421.208, 82.86744, 4.782202, 8, 0), +(41378, 0, 0, 41440, -143.931, -418.472, 94.99654, 5.201081, 8, 0), +(41378, 0, 0, 41440, -143.809, -418.507, 103.9453, 5.113815, 8, 0), +(41378, 0, 0, 41440, -144.153, -418.741, 85.51984, 5.585053, 8, 0), +(41378, 0, 0, 41440, -148.575, -438.087, 104.4583, 5.689773, 8, 0), +(41378, 0, 0, 41440, -151.0955, -426.809, 83.10994, 0.1745329, 8, 0), +(41378, 0, 0, 41440, -148.835, -438.078, 85.23814, 5.654867, 8, 0), +(41378, 0, 0, 41440, -149.1545, -438.099, 94.94753, 5.67232, 8, 0), +(41378, 0, 0, 41440, -150.332, -432.316, 83.05254, 5.742133, 8, 0), +(41378, 0, 0, 41440, -69.3472, -417.59, 104.4583, 3.141593, 8, 0), +(41378, 0, 0, 41440, -69.1615, -417.741, 94.94753, 3.124139, 8, 0), +(41378, 0, 0, 41440, -69.0035, -417.688, 85.23814, 3.106686, 8, 0), +(41378, 0, 0, 41440, -63.2465, -437.377, 103.9453, 2.687807, 8, 0), +(41378, 0, 0, 41440, -63.1927, -437.582, 94.99654, 2.775074, 8, 0), +(41378, 0, 0, 41440, -64.0729, -420.663, 83.64043, 3.420845, 8, 0), +(41378, 0, 0, 41440, -61.3299, -425.25, 83.69794, 3.804818, 8, 0), +(41378, 0, 0, 41440, -63.2135, -437.502, 85.51984, 3.159046, 8, 0), +(41378, 0, 0, 41440, -61.2656, -431.288, 83.45544, 2.70526, 8, 0), +-- Prime Subject +(41378, 0, 0, 41841, -145.46, -427.517, 97.17764, 0.6108652, 8, 0), +(41378, 0, 0, 41841, -66.408, -426.899, 97.17764, 4.18879, 8, 0); + +-- Spawn Group +DELETE FROM `spawn_group_template` WHERE `groupId`= 401; +INSERT INTO `spawn_group_template` (`groupId`, `groupName`, `groupFlags`) VALUES +(401, 'Blackwing Descent - Growth Chambers', 4); + +DELETE FROM `spawn_group` WHERE `groupId`= 401; +INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) VALUES +(401, 1, 235157), +(401, 1, 235158), +(401, 1, 235159), +(401, 1, 235160), +(401, 1, 235161), +(401, 1, 235162), +(401, 1, 235163), +(401, 1, 235164), +(401, 1, 235165), +(401, 1, 235166), +(401, 1, 235167), +(401, 1, 235168), +(401, 1, 235169), +(401, 1, 235170), +(401, 1, 235171), +(401, 1, 235172), +(401, 1, 235173), +(401, 1, 235174), +(401, 1, 235175), +(401, 1, 235176); + +-- Delete encounter relatest spawns +DELETE FROM `creature` WHERE `guid` IN (250115, 250114); +DELETE FROM `creature_addon` WHERE `guid` IN (250115, 250114); + +-- Currency Loot +DELETE FROM `creature_onkill_reward` WHERE `creature_id` IN (41378, 49974, 49980, 49986); +INSERT INTO `creature_onkill_reward` (`creature_id`, `CurrencyId1`, `CurrencyCount1`) VALUES +(41378, 396, 3500), +(49974, 396, 4500), +(49980, 396, 3500), +(49986, 396, 4500); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 4b444e6655e..54c7ef7c80e 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -5431,7 +5431,13 @@ void SpellMgr::LoadSpellInfoCorrections() spellInfo->AttributesEx8 |= SPELL_ATTR8_CANT_MISS; }); - // END OF BLACKWING DESCENT SPELLS + // Debilitating Slime + ApplySpellFix({ 77615 }, [](SpellInfo* spellInfo) + { + spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO; + }); + + // ENDOF BLACKWING DESCENT SPELLS // Living Bomb ApplySpellFix({ 44457 }, [](SpellInfo* spellInfo) diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h index 7e00ed89259..267f3449a48 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/blackwing_descent.h @@ -65,7 +65,8 @@ enum BWDDataTypes /*Maloriak*/ DATA_CAULDRON_TRIGGER, - DATA_CAULDRON + DATA_CAULDRON, + DATA_LORD_VICTOR_NEFARIUS_MALORIAK }; enum BWDCreatureIds @@ -123,6 +124,9 @@ enum BWDCreatureIds NPC_ABERRATION = 41440, NPC_PRIME_SUBJECT = 41841, NPC_FLASH_FREEZE = 41576, + NPC_ABSOLUTE_ZERO = 41961, + NPC_LORD_VICTOR_NEFARIUS_MALORIAK = 49799, + NPC_VILE_SWILL = 49811, /*Events*/ NPC_SPIRIT_OF_MOLTENFIST = 43125, diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_maloriak.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_maloriak.cpp index dcac82d8369..dd8a359c334 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_maloriak.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/boss_maloriak.cpp @@ -18,6 +18,7 @@ #include "ObjectMgr.h" #include "ScriptMgr.h" #include "CommonPredicates.h" +#include "DBCStores.h" #include "GridNotifiers.h" #include "PassiveAI.h" #include "ScriptedCreature.h" @@ -44,12 +45,20 @@ enum Spells SPELL_THROW_RED_BOTTLE_TRIGGERED = 77928, SPELL_THROW_BLUE_BOTTLE_TRIGGERED = 77934, SPELL_THROW_GREEN_BOTTLE_TRIGGERED = 77938, - SPELL_THROW_BLACK_BOTTLE_TRIGGERED = 92837, SPELL_RELEASE_ABERRATIONS = 77569, SPELL_RELEASE_ALL_MINIONS = 77991, SPELL_SCORCHING_BLAST = 77679, SPELL_BITING_CHILL = 77760, SPELL_FLASH_FREEZE_TARGETING = 97693, + SPELL_DRINK_ALL_BOTTLES = 95662, + SPELL_UNSTABLE_MIX = 95663, + SPELL_MAGMA_JETS_SCRIPT_EFFECT = 93022, + SPELL_MAGMA_JETS_SUMMON = 78194, + SPELL_ACID_NOVA = 78225, + SPELL_ABSOLUTE_ZERO = 78223, + SPELL_ENGULFING_DARKNESS = 92754, + SPELL_VILE_SWILL = 92720, + SPELL_VILE_SWILL_SUMMON = 92724, // Cauldron Trigger SPELL_DEBILITATING_SLIME_CAST = 77602, @@ -64,6 +73,23 @@ enum Spells SPELL_DROWNED_STATE = 77564, SPELL_GROWTH_CATALYST = 77987, + // Magma Jet + SPELL_MAGMA_JETS_SUMMON_FIRE = 78094, + SPELL_MAGMA_JETS_ERUPTION = 78095, + + // Absolute Zero + SPELL_ABSOLUTE_ZERO_TRANSFORM = 78201, + SPELL_ABSOLUTE_ZERO_EXPLOSION = 78208, + + // Lord Victor Nefarius + SPELL_TELEPORT_VISUAL_ONLY = 41232, + SPELL_THROW_BLACK_BOTTLE = 92831, + SPELL_THROW_BLACK_BOTTLE_TRIGGERED = 92837, + SPELL_MASTER_ADVENTURER_AWARD = 89798, + + // Vile Swill + SPELL_DARK_SLUDGE = 92929, + // Player SPELL_FLASH_FREEZE_SUMMON = 77711, SPELL_FLASH_FREEZE_DUMMY = 77716, @@ -91,24 +117,61 @@ enum Events EVENT_SCORCHING_BLAST, EVENT_BITING_CHILL, EVENT_FLASH_FREEZE, + EVENT_ENTER_PHASE_TWO, + EVENT_DRINK_ALL_BOTTLES, + EVENT_UNSTABLE_MIX, + EVENT_MAGMA_JETS, + EVENT_ACID_NOVA, + EVENT_ABSOLUTE_ZERO, + EVENT_MOVE_AWAY_FROM_CAULDRON, + EVENT_ENGULFING_DARKNESS, + EVENT_VILE_SWILL, // Experiments EVENT_LEAP_OUT_OF_CHAMBER, + + // Lord Victor Nefarius + EVENT_MOCK_MALORIAK, + EVENT_THROW_BLACK_BOTTLE, + EVENT_LAND, + EVENT_SAY_MALORIAK_DEAD, + EVENT_MASTER_ADVENTURER_AWARD, + EVENT_TELEPORT_AWAY, + + // Vile Swill + EVENT_DARK_SLUDGE +}; + +enum Phases +{ + PHASE_ONE = 1, + PHASE_TWO = 2 }; enum Actions { + // Maloriak ACTION_SCHEDULE_EVENTS_FOR_PHASE = 1, - ACTION_RELEASE_EXPERIMENT = 1 + + // Experiments + ACTION_RELEASE_EXPERIMENT = 1, + + // Lord Victor Nefarius + ACTION_THROW_BLACK_BOTTLE = 1, + ACTION_MALORIAK_DEAD = 2 }; enum MovePoints { // Maloriak + POINT_NONE = 0, POINT_CAULDRON = 1, // Experiments - POINT_GROUND = 1 + POINT_GROUND = 1, + + // Lord Victor Nefarius + POINT_LAND = 1 }; enum Texts @@ -122,13 +185,23 @@ enum Texts SAY_GREEN_VIAL = 5, SAY_ANNOUNCE_GREEN_VIAL = 6, SAY_RELEASE_ABERRATIONS = 7, + SAY_RELEASE_ALL_MINIONS = 8, + SAY_SLAY = 9, + SAY_DEATH = 10, + + // Lord Victor Nefarius + SAY_MOCK_MALORIAK = 0, + SAY_THROW_BLACK_BOTTLE = 1, + SAY_ANNOUNCE_BLACK_VIAL = 2, + SAY_MALORIAK_DEAD = 3 }; enum Vials { VIAL_RED = 0, VIAL_BLUE = 1, - VIAL_GREEN = 2 + VIAL_GREEN = 2, + VIAL_BLACK = 3 }; enum GameObjectCustomAnim @@ -139,7 +212,9 @@ enum GameObjectCustomAnim CUSTOM_ANIM_BLACK_CAULDRON = 3 }; -Position const CauldronMovePosition = { -106.6782f, -475.4438f, 73.45684f }; +Position const CauldronMovePosition = { -106.6782f, -475.4438f, 73.45684f }; +Position const LordVictorNefariusSummonPosition = { -105.9514f, -494.0278f, 89.33157f, 1.605703f }; +Position const LordVictorNefariusLandPosition = { -105.9514f, -494.0278f, 73.44659f }; struct VialData { @@ -152,21 +227,24 @@ struct VialData enum Misc { - SUMMON_GROUP_EXPERIMENTS = 0, - SPAWN_GROUP_GROWTH_CHAMBERS = 401 + SUMMON_GROUP_EXPERIMENTS = 0, + SPAWN_GROUP_GROWTH_CHAMBERS = 401, + AI_ANIM_KIT_ID_LORD_VICTOR_NEFARIUS = 1173, + TITLE_ADVENTURER_AWARD = 188 }; std::unordered_map vialData = { - { VIAL_RED, { SAY_RED_VIAL, SAY_ANNOUNCE_RED_VIAL, SPELL_THROW_RED_BOTTLE, SPELL_DRINK_RED_BOTTLE, SPELL_FIRE_IMBUED }}, - { VIAL_BLUE, { SAY_BLUE_VIAL, SAY_ANNOUNCE_BLUE_VIAL, SPELL_THROW_BLUE_BOTTLE, SPELL_DRINK_BLUE_BOTTLE, SPELL_FROST_IMBUED }}, - { VIAL_GREEN, { SAY_GREEN_VIAL, SAY_ANNOUNCE_GREEN_VIAL, SPELL_THROW_GREEN_BOTTLE, 0, SPELL_SLIME_IMBUED }}, + { VIAL_RED, { SAY_RED_VIAL, SAY_ANNOUNCE_RED_VIAL, SPELL_THROW_RED_BOTTLE, SPELL_DRINK_RED_BOTTLE, SPELL_FIRE_IMBUED }}, + { VIAL_BLUE, { SAY_BLUE_VIAL, SAY_ANNOUNCE_BLUE_VIAL, SPELL_THROW_BLUE_BOTTLE, SPELL_DRINK_BLUE_BOTTLE, SPELL_FROST_IMBUED }}, + { VIAL_GREEN, { SAY_GREEN_VIAL, SAY_ANNOUNCE_GREEN_VIAL, SPELL_THROW_GREEN_BOTTLE, 0, SPELL_SLIME_IMBUED }}, + { VIAL_BLACK, { 0, 0, 0, SPELL_DRINK_BLACK_BOTTLE, SPELL_SHADOW_IMBUED }}, }; struct boss_maloriak : public BossAI { boss_maloriak(Creature* creature) : BossAI(creature, DATA_MALORIAK), - _currentVial(urand(VIAL_RED, VIAL_BLUE)), _usedVialsCount(0), _releasedAberrationsCount(0) { } + _currentVial(0), _usedVialsCount(0), _vialsPerCycle(IsHeroic() ? 3 : 2), _releasedAberrationsCount(0) { } void Reset() override { @@ -185,23 +263,56 @@ struct boss_maloriak : public BossAI _JustEngagedWith(); Talk(SAY_AGGRO); instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); - events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, 15s + 500ms); + events.SetPhase(PHASE_ONE); + events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, 15s + 500ms, 0, PHASE_ONE); + + if (IsHeroic()) + DoSummon(NPC_LORD_VICTOR_NEFARIUS_MALORIAK, LordVictorNefariusSummonPosition, 0, TEMPSUMMON_MANUAL_DESPAWN); } void EnterEvadeMode(EvadeReason /*why*/) override { _EnterEvadeMode(); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + if (Creature* nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS_MALORIAK)) + nefarius->DespawnOrUnsummon(); CleanupEncounter(); _DespawnAtEvade(); } void JustDied(Unit* /*killer*/) override { - // Talk(SAY_DEATH); + Talk(SAY_DEATH); instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); CleanupEncounter(); _JustDied(); + + if (Creature * nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS_MALORIAK)) + if (nefarius->IsAIEnabled) + nefarius->AI()->DoAction(ACTION_MALORIAK_DEAD); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY, victim); + } + + void JustSummoned(Creature* summon) override + { + switch (summon->GetEntry()) + { + case NPC_LORD_VICTOR_NEFARIUS_MALORIAK: + break; + case NPC_ABSOLUTE_ZERO: + summon->GetMotionMaster()->MoveRandom(10.0f); + summon->CastSpell(summon, SPELL_ABSOLUTE_ZERO_TRANSFORM); + summons.Summon(summon); + break; + default: + summons.Summon(summon); + break; + } } void OnSpellCastInterrupt(SpellInfo const* spell) override @@ -253,42 +364,57 @@ struct boss_maloriak : public BossAI switch (action) { case ACTION_SCHEDULE_EVENTS_FOR_PHASE: - events.ScheduleEvent(EVENT_ATTACK_PLAYERS, _currentVial != VIAL_GREEN ? 1ms : 4s); + if (_currentVial != VIAL_BLACK) + events.ScheduleEvent(EVENT_ATTACK_PLAYERS, _currentVial != VIAL_GREEN ? 1ms : 4s); + events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, _currentVial == VIAL_BLACK ? 1min + 30s : 40s, 0, PHASE_ONE); - if (_currentVial == VIAL_RED || _currentVial == VIAL_BLUE) + switch (_currentVial) { - events.ScheduleEvent(EVENT_ARCANE_STORM, 14s + 500ms); - events.ScheduleEvent(EVENT_REMEDY, 21s + 500ms); - events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 11s); - } - else if (_currentVial == VIAL_GREEN) - { - if (Creature* cauldron = instance->GetCreature(DATA_CAULDRON_TRIGGER)) - cauldron->CastSpell(cauldron, SPELL_DEBILITATING_SLIME_DEBUFF); + case VIAL_RED: + events.ScheduleEvent(EVENT_ARCANE_STORM, 15s + 500ms, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_REMEDY, 20s + 500ms, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 11s, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_CONSUMING_FLAMES, 7s, 8s, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_SCORCHING_BLAST, 19s, 22s, 0, PHASE_ONE); + break; + case VIAL_BLUE: + events.ScheduleEvent(EVENT_ARCANE_STORM, 6s, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_REMEDY, 21s + 500ms, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 14s + 500ms, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_BITING_CHILL, 13s, 14s, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_FLASH_FREEZE, 17s, 0, PHASE_ONE); + break; + case VIAL_GREEN: + if (Creature* cauldron = instance->GetCreature(DATA_CAULDRON_TRIGGER)) + cauldron->CastSpell(cauldron, SPELL_DEBILITATING_SLIME_DEBUFF); - events.ScheduleEvent(EVENT_ARCANE_STORM, 8s); - events.ScheduleEvent(EVENT_REMEDY, 33s + 500ms); - events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 15s); + events.ScheduleEvent(EVENT_ARCANE_STORM, 5s, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_REMEDY, 7s + 500ms, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_RELEASE_ABERRATIONS, 9s, 0, PHASE_ONE); + break; + case VIAL_BLACK: + me->GetMotionMaster()->MovePoint(POINT_NONE, me->GetHomePosition()); + events.ScheduleEvent(EVENT_VILE_SWILL, 2s, 0, PHASE_ONE); + events.ScheduleEvent(EVENT_ENGULFING_DARKNESS, 8s, 0, PHASE_ONE); + break; + default: + break; } - - if (_currentVial == VIAL_RED) - { - events.ScheduleEvent(EVENT_CONSUMING_FLAMES, 7s + 500ms); - events.ScheduleEvent(EVENT_SCORCHING_BLAST, 22s); - } - else if (_currentVial == VIAL_BLUE) - { - events.ScheduleEvent(EVENT_BITING_CHILL, 13s + 500ms); - events.ScheduleEvent(EVENT_FLASH_FREEZE, 22s); - } - - events.ScheduleEvent(EVENT_FACE_TO_CAULDRON, 40s); break; default: break; } } + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(25, damage) && !events.IsInPhase(PHASE_TWO)) + { + events.SetPhase(PHASE_TWO); + events.ScheduleEvent(EVENT_ENTER_PHASE_TWO, 1ms, 0, PHASE_TWO); + } + } + void UpdateAI(uint32 diff) override { if (!UpdateVictim()) @@ -309,18 +435,19 @@ struct boss_maloriak : public BossAI DoCastSelf(SPELL_ARCANE_STORM); Creature* maloriak = me; me->m_Events.AddEventAtOffset([maloriak]() { maloriak->MakeInterruptable(false); }, 6s + 500ms); - events.Repeat(13s + 500ms); + events.Repeat(15s + 500ms, 17s); break; } case EVENT_REMEDY: DoCastSelf(SPELL_REMEDY); + events.Repeat(24s); break; case EVENT_RELEASE_ABERRATIONS: if (_releasedAberrationsCount < 6) { me->MakeInterruptable(true); DoCastAOE(SPELL_RELEASE_ABERRATIONS); - events.Repeat(24s + 500ms); + events.Repeat(17s, 18s); _releasedAberrationsCount++; } break; @@ -330,17 +457,37 @@ struct boss_maloriak : public BossAI { me->AttackStop(); me->SetReactState(REACT_PASSIVE); + me->ClearUnitState(UNIT_STATE_ROOT); me->SetFacingToObject(cauldron); - _currentVial = _usedVialsCount < 2 ? _currentVial == VIAL_BLUE ? VIAL_RED : VIAL_BLUE : VIAL_GREEN; - Talk(vialData[_currentVial].SayTextId); - _usedVialsCount = _usedVialsCount < 2 ? _usedVialsCount + 1 : 0; - events.ScheduleEvent(EVENT_THROW_VIAL, 1s + 300ms); + if (!_usedVialsCount && IsHeroic()) + _currentVial = VIAL_BLACK; + else + { + if ((_currentVial == VIAL_BLACK || _currentVial == VIAL_GREEN) && _usedVialsCount < _vialsPerCycle) + _currentVial = urand(VIAL_RED, VIAL_BLUE); + else if (_usedVialsCount == _vialsPerCycle) + _currentVial = VIAL_GREEN; + else + _currentVial = _currentVial == VIAL_BLUE ? VIAL_RED : VIAL_BLUE; + } + + if (_currentVial != VIAL_BLACK) + Talk(vialData[_currentVial].SayTextId); + else if (Creature * nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS_MALORIAK)) + if (nefarius->IsAIEnabled) + nefarius->AI()->DoAction(ACTION_THROW_BLACK_BOTTLE); + + _usedVialsCount = _usedVialsCount < _vialsPerCycle ? _usedVialsCount + 1 : 0; + events.ScheduleEvent(EVENT_THROW_VIAL, 1s + 300ms, 0, PHASE_ONE); } break; case EVENT_THROW_VIAL: - DoCastSelf(vialData[_currentVial].ThrowSpellId); - Talk(vialData[_currentVial].AnnounceTextId); + if (_currentVial != VIAL_BLACK) + { + DoCastSelf(vialData[_currentVial].ThrowSpellId); + Talk(vialData[_currentVial].AnnounceTextId); + } events.ScheduleEvent(EVENT_MOVE_TO_CAULDRON, 1s); break; case EVENT_MOVE_TO_CAULDRON: @@ -370,7 +517,7 @@ struct boss_maloriak : public BossAI case EVENT_CONSUMING_FLAMES: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) DoCast(target, SPELL_CONSUMING_FLAMES); - events.Repeat(17s); + events.Repeat(14s + 500ms); break; case EVENT_SCORCHING_BLAST: DoCastSelf(SPELL_SCORCHING_BLAST); @@ -383,7 +530,54 @@ struct boss_maloriak : public BossAI break; case EVENT_FLASH_FREEZE: DoCastAOE(SPELL_FLASH_FREEZE_TARGETING); - events.Repeat(17s); + events.Repeat(19s); + break; + case EVENT_ENTER_PHASE_TWO: + me->AttackStop(); + me->SetReactState(REACT_PASSIVE); + Talk(SAY_RELEASE_ALL_MINIONS); + DoCastSelf(SPELL_RELEASE_ALL_MINIONS); + events.ScheduleEvent(EVENT_DRINK_ALL_BOTTLES, 5s, 0, PHASE_TWO); + break; + case EVENT_DRINK_ALL_BOTTLES: + for (uint8 i = 0; i < VIAL_BLACK; i++) + me->RemoveAurasDueToSpell(vialData[i].ImbuedSpellId); + + DoCastSelf(SPELL_DRINK_ALL_BOTTLES); + events.ScheduleEvent(EVENT_UNSTABLE_MIX, 2s + 300ms, 0, PHASE_TWO); + break; + case EVENT_UNSTABLE_MIX: + DoCastSelf(SPELL_UNSTABLE_MIX); + me->SetReactState(REACT_AGGRESSIVE); + events.ScheduleEvent(EVENT_MAGMA_JETS, 3s + 500ms, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_ACID_NOVA, 8s + 400ms, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_ABSOLUTE_ZERO, 8s + 400ms, 0, PHASE_TWO); + break; + case EVENT_MAGMA_JETS: + //DoCastAOE(SPELL_MAGMA_JETS_SCRIPT_EFFECT); // seems like an old changed mechanic spell. No purpose atm. + DoCastSelf(SPELL_MAGMA_JETS_SUMMON); + events.Repeat(6s); + break; + case EVENT_ACID_NOVA: + DoCastAOE(SPELL_ACID_NOVA); + events.Repeat(20s); + break; + case EVENT_ABSOLUTE_ZERO: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) + DoCast(target, SPELL_ABSOLUTE_ZERO); + events.Repeat(7s); + break; + case EVENT_ENGULFING_DARKNESS: + if (me->GetReactState() == REACT_PASSIVE) + { + me->AddUnitState(UNIT_STATE_ROOT); + me->SetReactState(REACT_AGGRESSIVE); + } + DoCastSelf(SPELL_ENGULFING_DARKNESS); + events.Repeat(12s + 500ms); + break; + case EVENT_VILE_SWILL: + DoCastSelf(SPELL_VILE_SWILL); break; default: break; @@ -395,6 +589,7 @@ struct boss_maloriak : public BossAI private: uint8 _currentVial; uint8 _usedVialsCount; + uint8 _vialsPerCycle; uint8 _releasedAberrationsCount; void CleanupEncounter() @@ -413,6 +608,7 @@ struct npc_maloriak_flash_freeze : public NullCreatureAI void JustAppeared() override { + me->ApplySpellImmune(0, IMMUNITY_ID, sSpellMgr->GetSpellIdForDifficulty(SPELL_GROWTH_CATALYST, me), true); DoCastSelf(SPELL_FLASH_FREEZE_VISUAL); Creature* creature = me; me->m_Events.AddEventAtOffset([creature]() { creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); }, 1s); @@ -544,6 +740,145 @@ private: EventMap _events; }; +struct npc_maloriak_magma_jet : public NullCreatureAI +{ + npc_maloriak_magma_jet(Creature* creature) : NullCreatureAI(creature) { } + + void JustSummoned(Creature* summon) override + { + summon->CastSpell(summon, SPELL_MAGMA_JETS_ERUPTION); + summon->DespawnOrUnsummon(30s); + } +}; + +struct npc_maloriak_lord_victor_nefarius : public NullCreatureAI +{ + npc_maloriak_lord_victor_nefarius(Creature* creature) : NullCreatureAI(creature) { } + + void JustAppeared() override + { + me->SetHover(true); + DoCastSelf(SPELL_TELEPORT_VISUAL_ONLY); + _events.ScheduleEvent(EVENT_MOCK_MALORIAK, 7s + 200ms); + } + + void MovementInform(uint32 motionType, uint32 pointId) override + { + if (motionType != POINT_MOTION_TYPE && motionType != EFFECT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_LAND: + me->SetDisableGravity(false); + me->SetHover(false); + _events.ScheduleEvent(EVENT_SAY_MALORIAK_DEAD, 2s); + break; + default: + break; + } + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_THROW_BLACK_BOTTLE: + Talk(SAY_THROW_BLACK_BOTTLE); + _events.ScheduleEvent(EVENT_THROW_BLACK_BOTTLE, 2s + 400ms); + break; + case ACTION_MALORIAK_DEAD: + me->SetAIAnimKitId(AI_ANIM_KIT_ID_LORD_VICTOR_NEFARIUS); + _events.Reset(); + _events.ScheduleEvent(EVENT_LAND, 3s); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_MOCK_MALORIAK: + Talk(SAY_MOCK_MALORIAK); + break; + case EVENT_THROW_BLACK_BOTTLE: + Talk(SAY_ANNOUNCE_BLACK_VIAL); + DoCastAOE(SPELL_THROW_BLACK_BOTTLE, true); + break; + case EVENT_LAND: + me->GetMotionMaster()->MoveLand(POINT_LAND, LordVictorNefariusLandPosition); + break; + case EVENT_SAY_MALORIAK_DEAD: + Talk(SAY_MALORIAK_DEAD); + _events.ScheduleEvent(EVENT_MASTER_ADVENTURER_AWARD, 7s); + break; + case EVENT_MASTER_ADVENTURER_AWARD: + DoCastAOE(SPELL_MASTER_ADVENTURER_AWARD); + _events.ScheduleEvent(EVENT_TELEPORT_AWAY, 2s + 500ms); + break; + case EVENT_TELEPORT_AWAY: + DoCastSelf(SPELL_TELEPORT_VISUAL_ONLY); + me->DespawnOrUnsummon(1s + 200ms); + break; + default: + break; + } + } + } + +private: + EventMap _events; +}; + +struct npc_maloriak_vile_swill : public ScriptedAI +{ + npc_maloriak_vile_swill(Creature* creature) : ScriptedAI(creature) { } + + void JustAppeared() override + { + DoZoneInCombat(); + _events.ScheduleEvent(EVENT_DARK_SLUDGE, 6s); + } + + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(5s); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_DARK_SLUDGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true)) + DoCast(target, SPELL_DARK_SLUDGE); + _events.Repeat(6s); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } +private: + EventMap _events; +}; + class spell_maloriak_throw_bottle : public SpellScript { PrepareSpellScript(spell_maloriak_throw_bottle); @@ -763,15 +1098,174 @@ class spell_maloriak_release_experiments : public SpellScript } }; +class spell_maloriak_magma_jets_periodic : public AuraScript +{ + PrepareAuraScript(spell_maloriak_magma_jets_periodic); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_MAGMA_JETS_SUMMON_FIRE }); + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + + uint8 ticks = aurEff->GetTickNumber(); + float dist = 3.0f * ticks; + float x = target->GetPositionX() + cos(target->GetOrientation()) * dist; + float y = target->GetPositionY() + sin(target->GetOrientation()) * dist; + float z = target->GetMapHeight(x, y, target->GetPositionZ() + 5.0f); + if (target->IsWithinLOS(x, y, z)) + target->CastSpell(x, y, z, SPELL_MAGMA_JETS_SUMMON_FIRE, true); + else + Remove(); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_maloriak_magma_jets_periodic::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + +class spell_maloriak_absolute_zero : public SpellScript +{ + PrepareSpellScript(spell_maloriak_absolute_zero); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ABSOLUTE_ZERO_EXPLOSION }); + } + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + Unit* caster = GetCaster(); + caster->RemoveAllAuras(); + caster->CastSpell(caster, SPELL_ABSOLUTE_ZERO_EXPLOSION); + if (Creature * creature = caster->ToCreature()) + creature->DespawnOrUnsummon(3s); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_maloriak_absolute_zero::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } +}; + +class spell_maloriak_vile_swill: public AuraScript +{ + PrepareAuraScript(spell_maloriak_vile_swill); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_VILE_SWILL_SUMMON }); + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + Position const destination = target->GetRandomPoint(target->GetPosition(), 11.0f); + target->CastSpell(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ(), SPELL_VILE_SWILL_SUMMON, true); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_maloriak_vile_swill::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } +}; + +class spell_maloriak_vile_swill_summon: public AuraScript +{ + PrepareAuraScript(spell_maloriak_vile_swill_summon); + + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + int32 summonSpellId = GetSpellInfo()->Effects[EFFECT_0].TriggerSpell; + Creature* target = GetTarget()->ToCreature(); + if (!target) + return; + + target->m_Events.AddEventAtOffset([target, summonSpellId]() + { + target->CastSpell(target, summonSpellId, true); + target->SetObjectScale(0.1f); + target->m_Events.AddEventAtOffset([target]() + { + target->RemoveAllAuras(); + target->DespawnOrUnsummon(4s + 300ms); + }, 1s + 200ms); + }, 2s); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_maloriak_vile_swill_summon::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + +class spell_maloriak_master_adventurer_award : public AuraScript +{ + PrepareAuraScript(spell_maloriak_master_adventurer_award); + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Player* player = GetTarget()->ToPlayer(); + if (!player) + return; + + CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(TITLE_ADVENTURER_AWARD); + if (!titleInfo) + return; + + player->SetTitle(titleInfo); + player->SetUInt32Value(PLAYER_CHOSEN_TITLE, titleInfo->bit_index); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Player* player = GetTarget()->ToPlayer(); + if (!player) + return; + + CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(TITLE_ADVENTURER_AWARD); + if (!titleInfo) + return; + + player->SetTitle(titleInfo, false); + + if (!player->HasTitle(player->GetInt32Value(PLAYER_CHOSEN_TITLE))) + player->SetUInt32Value(PLAYER_CHOSEN_TITLE, 0); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_maloriak_master_adventurer_award::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_maloriak_master_adventurer_award::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_boss_maloriak() { RegisterBlackwingDescentCreatureAI(boss_maloriak); RegisterBlackwingDescentCreatureAI(npc_maloriak_flash_freeze); RegisterBlackwingDescentCreatureAI(npc_maloriak_experiment); + RegisterBlackwingDescentCreatureAI(npc_maloriak_magma_jet); + RegisterBlackwingDescentCreatureAI(npc_maloriak_lord_victor_nefarius); + RegisterBlackwingDescentCreatureAI(npc_maloriak_vile_swill); RegisterSpellScript(spell_maloriak_throw_bottle); RegisterSpellScript(spell_maloriak_throw_bottle_triggered); RegisterAuraScript(spell_maloriak_consuming_flames); RegisterSpellScript(spell_maloriak_flash_freeze_targeting); RegisterSpellScript(spell_maloriak_flash_freeze_dummy); RegisterSpellScript(spell_maloriak_release_experiments); + RegisterAuraScript(spell_maloriak_magma_jets_periodic); + RegisterSpellScript(spell_maloriak_absolute_zero); + RegisterAuraScript(spell_maloriak_vile_swill); + RegisterAuraScript(spell_maloriak_vile_swill_summon); + RegisterAuraScript(spell_maloriak_master_adventurer_award); } diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp index afb6a8608dc..13694fcb68a 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingDescent/instance_blackwing_descent.cpp @@ -41,6 +41,7 @@ ObjectData const creatureData[] = { NPC_FINKLE_EINHORN, DATA_FINKLE_EINHORN }, { NPC_LORD_VICTOR_NEFARIUS_CHIMAERON, DATA_LORD_VICTOR_NEFARIUS_CHIMAERON }, { NPC_CAULDRON_TRIGGER, DATA_CAULDRON_TRIGGER }, + { NPC_LORD_VICTOR_NEFARIUS_MALORIAK, DATA_LORD_VICTOR_NEFARIUS_MALORIAK }, { 0, 0 } // END }; @@ -164,6 +165,7 @@ class instance_blackwing_descent : public InstanceMapScript atramedes->AI()->JustSummoned(creature); break; case NPC_FLASH_FREEZE: + case NPC_VILE_SWILL: if (Creature * maloriak = GetCreature(DATA_MALORIAK)) maloriak->AI()->JustSummoned(creature); break;