From 50bf6cad6a6bf1e4190a492c3a88316d6d831656 Mon Sep 17 00:00:00 2001 From: Mihapro Date: Sat, 25 Oct 2014 17:37:55 +0200 Subject: [PATCH] Scripts/Instance: The Stonecore --- sql/updates/world/2014_11_05_00_world.sql | 350 ++++++++ src/server/game/Scripting/ScriptLoader.cpp | 12 + src/server/scripts/Maelstrom/CMakeLists.txt | 7 + .../Maelstrom/Stonecore/boss_corborus.cpp | 319 +++++++ .../Stonecore/boss_high_priestess_azil.cpp | 807 ++++++++++++++++++ .../Maelstrom/Stonecore/boss_ozruk.cpp | 287 +++++++ .../Maelstrom/Stonecore/boss_slabhide.cpp | 599 +++++++++++++ .../Stonecore/instance_stonecore.cpp | 262 ++++++ .../scripts/Maelstrom/Stonecore/stonecore.cpp | 440 ++++++++++ .../scripts/Maelstrom/Stonecore/stonecore.h | 72 ++ 10 files changed, 3155 insertions(+) create mode 100644 sql/updates/world/2014_11_05_00_world.sql create mode 100644 src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp create mode 100644 src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp create mode 100644 src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp create mode 100644 src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp create mode 100644 src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp create mode 100644 src/server/scripts/Maelstrom/Stonecore/stonecore.cpp create mode 100644 src/server/scripts/Maelstrom/Stonecore/stonecore.h diff --git a/sql/updates/world/2014_11_05_00_world.sql b/sql/updates/world/2014_11_05_00_world.sql new file mode 100644 index 0000000000000..64a59180b4610 --- /dev/null +++ b/sql/updates/world/2014_11_05_00_world.sql @@ -0,0 +1,350 @@ +-- The Stonecore +DELETE FROM `instance_template` WHERE `map` = 725; +INSERT INTO `instance_template` (`map`, `parent`, `script`, `allowMount`) VALUES +(725, 0, 'instance_stonecore', 0); + +DELETE FROM `instance_encounters` WHERE `entry` IN (1056, 1059, 1058, 1057); +INSERT INTO `instance_encounters` (`entry`, `creditType`, `creditEntry`, `lastEncounterDungeon`, `comment`) VALUES +(1056, 0, 43438, 0, 'Corborus'), +(1059, 0, 43214, 0, 'Slabhide'), +(1058, 0, 42188, 0, 'Ozruk'), +(1057, 0, 42333, 0, 'High Priestess Azil'); + +UPDATE `creature_template` SET `mechanic_immune_mask` = 617299839 WHERE `entry` IN (43391, 43438, 43214, 42188, 42333); + +-- Script names +UPDATE `creature_template` SET `ScriptName` = 'boss_corborus' WHERE `entry` = 43438; +UPDATE `creature_template` SET `ScriptName` = 'boss_slabhide' WHERE `entry` = 43214; +UPDATE `creature_template` SET `ScriptName` = 'boss_ozruk' WHERE `entry` = 42188; +UPDATE `creature_template` SET `ScriptName` = 'boss_high_priestess_azil' WHERE `entry` = 42333; +UPDATE `creature_template` SET `ScriptName` = 'npc_rock_borer' WHERE `entry` = 43917; +UPDATE `creature_template` SET `ScriptName` = 'npc_sc_millhouse_manastorm' WHERE `entry` = 43391; +UPDATE `creature_template` SET `ScriptName` = 'npc_lava_fissure' WHERE `entry` = 43242; +UPDATE `creature_template` SET `ScriptName` = 'npc_stalactite_trigger' WHERE `entry` = 43159; +UPDATE `creature_template` SET `ScriptName` = 'npc_devout_follower' WHERE `entry` = 42428; +UPDATE `creature_template` SET `ScriptName` = 'npc_gravity_well' WHERE `entry` = 42499; +UPDATE `creature_template` SET `ScriptName` = 'npc_seismic_shard' WHERE `entry` = 42355; + +DELETE FROM `spell_script_names` WHERE `spell_id` IN (81459, 45313, 93167, 81008, 81035, 81028, 80650, 80654, 80643, 92653, 80647, 92309, 92306, 92300, 92393, 78835, 92429, 79200, 79196, 79251, 79249, 79332, 86862, 86863, 79015); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(81459, 'spell_force_of_earth'), +(45313, 'spell_sc_anchor_here'), +(93167, 'spell_sc_twilight_documents'), +(81008, 'spell_sc_quake'), +(81035, 'spell_s81035_stalactite'), +(81028, 'spell_s81028_s80650_stalactite'), +(80650, 'spell_s81028_s80650_stalactite'), +(80654, 'spell_stalactite_mod_dest_height'), +(80643, 'spell_stalactite_mod_dest_height'), +(92653, 'spell_stalactite_mod_dest_height'), +(80647, 'spell_stalactite_mod_dest_height'), +(92309, 'spell_stalactite_mod_dest_height'), +(92306, 'spell_s92306_crystal_storm'), +(92300, 'spell_s92300_crystal_storm'), +(92393, 'spell_rupture'), +(78835, 'spell_elementium_spike_shield'), +(92429, 'spell_elementium_spike_shield'), +(79200, 'spell_summon_wave_south'), +(79196, 'spell_summon_wave_west'), +(79251, 'spell_gravity_well_damage_nearby'), +(79249, 'spell_gravity_well_damage'), +(79332, 'spell_gravity_well_pull'), +(86862, 'spell_seismic_shard_prepare'), +(86863, 'spell_seismic_shard_change_seat'), +(79015, 'spell_seismic_shard'); + +DELETE FROM `areatrigger_scripts` WHERE `entry` IN (6076, 6070); +INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES +(6076, 'at_sc_corborus_intro'), +(6070, 'at_sc_slabhide_intro'); + +-- Twilight Documents object is spawned by Millhouse. +DELETE FROM `gameobject` WHERE `id` = 207415; + +-- Millhouse Manastorm texts +DELETE FROM `creature_text` WHERE `entry` IN (43391); +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(43391, 0, 1, 'Follow me if you dare!', 14, 0, 100, 0, 0, 21783, 0, 0, 'Millhouse Manastorm'), +(43391, 0, 2, 'It''s time for a tactical retreat!', 14, 0, 100, 0, 0, 21784, 0, 0, 'Millhouse Manastorm'), +(43391, 0, 3, 'You''re gonna be sorry!', 14, 0, 100, 0, 0, 21785, 0, 0, 'Millhouse Manastorm'), +(43391, 0, 4, 'Don''t say I didn''t warn ya!', 14, 0, 100, 0, 0, 21786, 0, 0, 'Millhouse Manastorm'), +(43391, 1, 1, 'Ah-ha! I''ve got you right where I want you!', 14, 0, 100, 0, 0, 21787, 0, 0, 'Millhouse Manastorm'), +(43391, 1, 2, 'Now... witness the full power of Millhouse Manastorm!', 14, 0, 100, 0, 0, 21788, 0, 0, 'Millhouse Manastorm'), +(43391, 1, 3, 'Prison taught me one very important lesson, well, two if you count how to hold your soap, but yes! SURVIVAL!', 14, 0, 100, 0, 0, 21789, 0, 0, 'Millhouse Manastorm'); + +-- Creature formations for Millhouse event (340418 -> trash, 340492 -> last group) +DELETE FROM `creature_formations` WHERE `leaderGUID` IN (340418, 340392, 340492); +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(340418, 340418, 0, 0, 0, 0, 0), +(340418, 340419, 0, 0, 0, 0, 0), +(340418, 340421, 0, 0, 0, 0, 0), +(340418, 340422, 0, 0, 0, 0, 0), +(340418, 340465, 0, 0, 0, 0, 0), +(340418, 340466, 0, 0, 0, 0, 0), +(340418, 340467, 0, 0, 0, 0, 0), +(340418, 340469, 0, 0, 0, 0, 0), +(340418, 340476, 0, 0, 0, 0, 0), +(340418, 340477, 0, 0, 0, 0, 0), +(340418, 340478, 0, 0, 0, 0, 0), +(340418, 340479, 0, 0, 0, 0, 0), +(340492, 340492, 0, 0, 0, 0, 0), +(340492, 340493, 0, 0, 0, 0, 0), +(340492, 340494, 0, 0, 0, 0, 0), +(340492, 340495, 0, 0, 0, 0, 0), +(340492, 340496, 0, 0, 0, 0, 0), +(340492, 340497, 0, 0, 0, 0, 0), +(340492, 340498, 0, 0, 0, 0, 0), +(340492, 340499, 0, 0, 0, 0, 0), +(340492, 340500, 0, 0, 0, 0, 0); + +-- Stonecore Flayer SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 42808; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 42808 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(42808, 0, 0, 0, 1, 0, 100, 0, 0, 0, 60000, 60000, 17, 438, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Flayer - In Combat - Set emote state 438"), +(42808, 0, 1, 0, 4, 0, 100, 0, 2500, 10000, 10000, 15000, 17, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Flayer - On Aggro - Set emote state 0"), +(42808, 0, 2, 0, 0, 0, 100, 0, 2500, 10000, 10000, 15000, 11, 79922, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Flayer - In Combat - Cast 'Flay'"); + +-- Stonecore Earthshaper SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 43537; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 43537 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(43537, 0, 0, 1, 25, 0, 100, 0, 0, 0, 0, 0, 22, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - On Reset - Set Phase 1"), +(43537, 0, 1, 0, 61, 0, 100, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - Linked - Demorph"), +(43537, 0, 2, 0, 0, 1, 100, 0, 3000, 3000, 10000, 15000, 11, 81576, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - In Combat (Phase 1) - Cast 'Lava Burst'"), +(43537, 0, 3, 4, 0, 1, 100, 0, 9000, 9000, 12000, 12000, 11, 81459, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - In Combat (Phase 1) - Cast 'Force of Earth'"), +(43537, 0, 4, 0, 61, 1, 100, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - Linked - Say Text 0"), +(43537, 0, 5, 0, 0, 1, 100, 0, 15000, 15000, 10000, 15000, 11, 81530, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - In Combat (Phase 1) - Cast 'Ground Shock'"), +(43537, 0, 6, 7, 8, 1, 100, 1, 81459, 0, 0, 0, 22, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - Hit by 'Force of Earth' (Phase 1) - Set Phase 2"), +(43537, 0, 7, 0, 61, 1, 100, 1, 81459, 0, 0, 0, 3, 26693, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - Linked - Morph"), +(43537, 0, 8, 0, 0, 2, 100, 0, 5000, 5000, 15000, 15000, 11, 81463, 64, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - In Combat (Phase 2) - Cast 'Dust Storm'"), +(43537, 0, 9, 0, 6, 0, 100, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Earthshaper - On Death - Demorph"); +-- TODO: Demorph 3 seconds after death. Need more sniffs for Force of Earth's dummy. + +DELETE FROM `creature_text` WHERE `entry` = 43537 AND `groupid` = 0; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextID`, `comment`) VALUES +(43537, 0, 0, '%s begins to transform into a Force of Earth!', 16, 0, 100, 0, 0, 0, 46680, 'Stonecore Earthshaper'); + +-- Stonecore Warbringer SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 42696; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 42696 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(42696, 0, 0, 0, 0, 0, 100, 0, 4000, 4000, 12000, 12000, 11, 80158, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, "Stonecore Warbringer - In Combat - Cast 'Rage'"), +(42696, 0, 1, 0, 0, 0, 100, 0, 8000, 8000, 8000, 12000, 11, 15496, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, "Stonecore Warbringer - In Combat - Cast 'Cleave'"); + +-- Stonecore Berserker SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 43430; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 43430 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(43430, 0, 0, 0, 0, 0, 100, 0, 0, 0, 10000, 10000, 11, 81574, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, "Stonecore Warbringer - In Combat - Cast 'Charge'"), +(43430, 0, 1, 0, 0, 0, 100, 0, 10000, 15000, 10000, 20000, 11, 81568, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Warbringer - In Combat - Cast 'Spinning Slash'"); + +-- Heroic template of Corborus, Flags on creation (from sniffs) +UPDATE `creature_template` SET `difficulty_entry_1` = 49642, `unit_flags` = 33088 WHERE `entry` = 43438; +DELETE FROM `creature_template` WHERE `entry` = 49642; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `femaleName`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `exp_unk`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `dmgschool`, `BaseAttackTime`, `RangeAttackTime`, `BaseVariance`, `RangeVariance`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_class`, `trainer_race`, `type`, `type_flags`, `type_flags2`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `HealthModifierExtra`, `ManaModifier`, `ManaModifierExtra`, `ArmorModifier`, `DamageModifier`, `ExperienceModifier`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) VALUES +(49642, 0, 0, 0, 0, 0, 33477, 0, 0, 0, 'Corborus (1)', '', '', '', 0, 87, 87, 3, 0, 14, 0, 2.8, 1.14286, 1, 1, 0, 2000, 2000, 1, 1, 1, 33088, 2048, 0, 0, 0, 0, 0, 4, 584, 0, 49642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 35, 1, 1, 1, 1, 1, 1, 0, 52506, 0, 0, 0, 0, 0, 154, 1, 617299839, 1, '', 15595); + +-- Corborus loot +UPDATE `creature_template` SET `lootid` = 43438 WHERE `entry` = 43438; +UPDATE `creature_template` SET `lootid` = 49642 WHERE `entry` = 49642; + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (43438, 49642); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(43438, 1, 43400, 100, 0, 1, 0, 1, 1, NULL), +(49642, 1, 43401, 100, 0, 1, 0, 1, 1, NULL); + +DELETE FROM `reference_loot_template` WHERE `Entry` IN (43400, 43401); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(43400, 55792, 0, 0, 0, 1, 1, 1, 1, NULL), +(43400, 55793, 0, 0, 0, 1, 1, 1, 1, NULL), +(43400, 55794, 0, 0, 0, 1, 1, 1, 1, NULL), +(43400, 55795, 0, 0, 0, 1, 1, 1, 1, NULL), +(43400, 55796, 0, 0, 0, 1, 1, 1, 1, NULL), +(43401, 56328, 0, 0, 0, 1, 1, 1, 1, NULL), +(43401, 56329, 0, 0, 0, 1, 1, 1, 1, NULL), +(43401, 56330, 0, 0, 0, 1, 1, 1, 1, NULL), +(43401, 56331, 0, 0, 0, 1, 1, 1, 1, NULL), +(43401, 56332, 0, 0, 0, 1, 1, 1, 1, NULL); + +-- Set UNIT_FLAG_NOT_SELECTABLE to Trashing Charge. +UPDATE `creature_template` SET `unit_flags` = 33554432 WHERE `entry` = 43743; + +-- Crystalspawn Giant SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 42810; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 42810 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(42810, 0, 0, 0, 0, 0, 100, 0, 5000, 5000, 12000, 12000, 11, 81008, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Crystalspawn Giant - In Combat - Cast 'Quake'"); +-- (42810, 0, 1, 0, 0, 0, 100, 0, 10000, 10000, 12000, 12000, 11, ?????, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Crystalspawn Giant - In Combat - Cast 'Crystal Shard'"); +-- need Stonecore HC sniffs for this spell + +-- Remove one Slabhide spawn, only the flying one is needed +DELETE FROM `creature` WHERE `id` = 43214; +INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `PhaseId`, `PhaseGroup`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `spawndist`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES +(340550, 43214, 725, 0, 0, 3, 1, 0, 0, 0, 0, 1191.1, 1154.01, 270.759, 4.69494, 7200, 0, 0, 1, 0, 0, 0, 0, 0, 0); + +-- Heroic template of Slabhide, InhabitType correction +UPDATE `creature_template` SET `difficulty_entry_1` = 49538, `InhabitType` = 7 WHERE `entry` = 43214; +DELETE FROM `creature_template` WHERE `entry` = 49538; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `femaleName`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `exp_unk`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `dmgschool`, `BaseAttackTime`, `RangeAttackTime`, `BaseVariance`, `RangeVariance`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_class`, `trainer_race`, `type`, `type_flags`, `type_flags2`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `HealthModifierExtra`, `ManaModifier`, `ManaModifierExtra`, `ArmorModifier`, `DamageModifier`, `ExperienceModifier`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) VALUES +(49538, 0, 0, 0, 0, 0, 36476, 0, 0, 0, 'Slabhide (1)', '', '', '', 0, 87, 87, 3, 0, 16, 0, 2.8, 1.42857, 1, 1, 0, 2000, 2000, 1, 1, 1, 33587264, 2048, 0, 0, 0, 0, 0, 2, 72, 0, 49538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 7, 1.25, 50, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 154, 1, 0, 1, '', 15595); + +-- Slabhide loot +UPDATE `creature_template` SET `lootid` = 43214 WHERE `entry` = 43214; +UPDATE `creature_template` SET `lootid` = 49538 WHERE `entry` = 49538; + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (43214, 49538); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(43214, 1, 43402, 100, 0, 1, 0, 1, 1, 'Slabhide N - Reference Loot'), +(49538, 1, 43403, 100, 0, 1, 0, 1, 1, 'Slabhide H - Reference Loot'), +(43214, 63043, 0, 1, 0, 1, 0, 1, 1, 'Slabhide N - Mount Drop'), +(49538, 63043, 0, 1, 0, 1, 0, 1, 1, 'Slabhide H - Mount Drop'); + +DELETE FROM `reference_loot_template` WHERE `Entry` IN (43402, 43403); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(43402, 55797, 0, 0, 0, 1, 1, 1, 1, NULL), +(43402, 55798, 0, 0, 0, 1, 1, 1, 1, NULL), +(43402, 55799, 0, 0, 0, 1, 1, 1, 1, NULL), +(43402, 55800, 0, 0, 0, 1, 1, 1, 1, NULL), +(43402, 55801, 0, 0, 0, 1, 1, 1, 1, NULL), +(43403, 56333, 0, 0, 0, 1, 1, 1, 1, NULL), +(43403, 56334, 0, 0, 0, 1, 1, 1, 1, NULL), +(43403, 56335, 0, 0, 0, 1, 1, 1, 1, NULL), +(43403, 56336, 0, 0, 0, 1, 1, 1, 1, NULL), +(43403, 56337, 0, 0, 0, 1, 1, 1, 1, NULL); + +-- Set UNIT_FLAG_NOT_SELECTABLE to Stalactite Trigger - Boss, Lava Fissure, . +UPDATE `creature_template` SET `unit_flags` = 33554432 WHERE `entry` IN (43159, 43242); + +-- "Stalactite Trigger - Boss": InhabitType correction +UPDATE `creature_template` SET `InhabitType` = 7 WHERE `entry` = 43159; + +-- Stonecore Magmalord SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 42789; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 42789 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(42789, 0, 0, 0, 0, 0, 100, 0, 4000, 8000, 10000, 20000, 11, 80151, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, "Stonecore Magmalord - In Combat - Cast '80151'"), +(42789, 0, 1, 0, 0, 0, 100, 0, 8000, 10000, 10000, 20000, 11, 80038, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Magmalord - In Combat - Cast 'Eruption'"); + +-- Stonecore Rift Conjurer SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 42691; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 42691 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(42691, 0, 0, 0, 0, 0, 100, 0, 0, 0, 2000, 2000, 11, 80279, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, "Stonecore Rift Conjurer - In Combat - Cast 'Shadow Bolt'"), +(42691, 0, 1, 0, 0, 0, 100, 0, 10000, 20000, 20000, 30000, 11, 80308, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Rift Conjurer - In Combat - Cast 'Demon Portal'"); + +-- Imp SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 43014; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 43014 AND `source_type` = 0; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(43014, 0, 1, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 80344, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, "Imp - In Combat - Cast 'Fel Firebolt'"); + +-- Stonecore Bruiser SAI +UPDATE `creature_template` SET `AIName` = "SmartAI" WHERE `entry` = 42692; +DELETE FROM `smart_scripts` WHERE `entryorguid` = 42692 AND `source_type` = 0 OR `entryorguid` = 4269200 AND `source_type` = 9; +INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES +(42692, 0, 0, 0, 0, 0, 100, 0, 8000, 10000, 13000, 15000, 80, 4269200, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Bruiser - In Combat - Start Actionlist"), +(4269200, 9, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 11, 80180, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, "Stonecore Bruiser - Actionlist- Cast 'Body Slam'"), +(4269200, 9, 1, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 11, 80180, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, "Stonecore Bruiser - Actionlist - Cast 'Body Slam' again"), +(4269200, 9, 2, 0, 0, 0, 100, 0, 2400, 2400, 0, 0, 11, 80180, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, "Stonecore Bruiser - Actionlist - Cast 'Body Slam' again"), +(42692, 0, 1, 0, 0, 0, 100, 0, 14000, 18000, 14000, 18000, 11, 80195, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "Stonecore Bruiser - In Combat - Cast 'Shockwave'"); + +-- Heroic template of Ozruk +UPDATE `creature_template` SET `difficulty_entry_1` = 49654 WHERE `entry` = 42188; +DELETE FROM `creature_template` WHERE `entry` = 49654; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `femaleName`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `exp_unk`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `dmgschool`, `BaseAttackTime`, `RangeAttackTime`, `BaseVariance`, `RangeVariance`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_class`, `trainer_race`, `type`, `type_flags`, `type_flags2`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `HealthModifierExtra`, `ManaModifier`, `ManaModifierExtra`, `ArmorModifier`, `DamageModifier`, `ExperienceModifier`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) VALUES +(49654, 0, 0, 0, 0, 0, 36475, 0, 0, 0, 'Ozruk (1)', '', '', '', 0, 87, 87, 3, 0, 14, 0, 1, 1.5873, 1, 1, 0, 2000, 2000, 1, 1, 1, 32832, 134219776, 0, 0, 0, 0, 0, 5, 584, 0, 49654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 867, 0, 0, '', 0, 3, 1, 40, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 617299839, 1, '', 15595); + +-- Ozruk texts +DELETE FROM `creature_text` WHERE `entry` = 42188; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(42188, 0, 0, 'None may pass into the World''s Heart!', 14, 0, 100, 0, 0, 21919, 0, 0, 'Ozruk to Player'), +(42188, 1, 0, '|TInterface\\Icons\\ability_warrior_shieldreflection.blp:20|tOzruk casts |cFFFF0000|Hspell:78939|h[Elementium Bulwark]|h|r!', 41, 0, 100, 0, 0, 0, 0, 0, 'Ozruk'), +(42188, 2, 0, 'Break yourselves upon my body. Feel the strength of the earth!', 14, 0, 100, 0, 0, 21921, 0, 0, 'Ozruk'), +(42188, 3, 0, '%s becomes enraged!', 41, 0, 100, 0, 0, 0, 0, 0, 'Ozruk'), +(42188, 4, 0, 'A protector has fallen. The World''s Heart lies exposed!', 14, 0, 100, 0, 0, 21922, 0, 0, 'Ozruk to Player'); + +-- Ozruk loot +UPDATE `creature_template` SET `lootid` = 42188 WHERE `entry` = 42188; +UPDATE `creature_template` SET `lootid` = 49654 WHERE `entry` = 49654; + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (42188, 49654); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(42188, 1, 43404, 100, 0, 1, 0, 1, 1, 'Ozruk N - Reference Loot'), +(49654, 1, 43405, 100, 0, 1, 0, 1, 1, 'Ozruk H - Reference Loot'); + +DELETE FROM `reference_loot_template` WHERE `Entry` IN (43404, 43405); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(43404, 55802, 0, 0, 0, 1, 1, 1, 1, NULL), +(43404, 55803, 0, 0, 0, 1, 1, 1, 1, NULL), +(43404, 55804, 0, 0, 0, 1, 1, 1, 1, NULL), +(43404, 55810, 0, 0, 0, 1, 1, 1, 1, NULL), +(43404, 55811, 0, 0, 0, 1, 1, 1, 1, NULL), +(43405, 56338, 0, 0, 0, 1, 1, 1, 1, NULL), +(43405, 56339, 0, 0, 0, 1, 1, 1, 1, NULL), +(43405, 56340, 0, 0, 0, 1, 1, 1, 1, NULL), +(43405, 56341, 0, 0, 0, 1, 1, 1, 1, NULL), +(43405, 56342, 0, 0, 0, 1, 1, 1, 1, NULL); + +-- Set UNIT_FLAG_NOT_SELECTABLE to Rupture Controller and Rupture. +UPDATE `creature_template` SET `unit_flags` = 33554432 WHERE `entry` IN (49597, 49576); + +-- Heroic template of High Priestess Azil +UPDATE `creature_template` SET `difficulty_entry_1` = 49624 WHERE `entry` = 42333; +DELETE FROM `creature_template` WHERE `entry` = 49624; +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `femaleName`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `exp_unk`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `dmgschool`, `BaseAttackTime`, `RangeAttackTime`, `BaseVariance`, `RangeVariance`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_class`, `trainer_race`, `type`, `type_flags`, `type_flags2`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `HealthModifierExtra`, `ManaModifier`, `ManaModifierExtra`, `ArmorModifier`, `DamageModifier`, `ExperienceModifier`, `RacialLeader`, `questItem1`, `questItem2`, `questItem3`, `questItem4`, `questItem5`, `questItem6`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) VALUES +(49624, 0, 0, 0, 0, 0, 26448, 0, 0, 0, 'High Priestess Azil (1)', '', '', '', 0, 84, 84, 3, 0, 14, 2, 1.2, 1.42857, 1, 1, 0, 2000, 2000, 1, 1, 1, 32832, 2048, 0, 0, 0, 0, 0, 7, 72, 0, 49624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, '', 0, 3, 1, 30, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 721, 1, 617299839, 1, '', 15595); + +-- "Stalactite Trigger - Boss": InhabitType correction +UPDATE `creature_template` SET `InhabitType` = 7 WHERE `entry` IN (42333, 49624); + +-- High Priestess Azil texts +DELETE FROM `creature_text` WHERE `entry` = 42333; +INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(42333, 0, 0, 'The world will be reborn in flames!', 14, 0, 100, 0, 0, 21634, 0, 0, 'High Priestess Azil to Player'), +(42333, 1, 0, 'Witness the power bestowed upon me by Deathwing! Feel the fury of earth!', 14, 0, 100, 0, 0, 21628, 0, 0, 'High Priestess Azil to High Priestess Azil'), +(42333, 2, 0, 'For my death, countless more will fall. The burden is now yours to bear.', 14, 0, 100, 0, 0, 21633, 0, 0, 'High Priestess Azil to Player'); + +-- High Priestess Azil loot +UPDATE `creature_template` SET `lootid` = 42333 WHERE `entry` = 42333; +UPDATE `creature_template` SET `lootid` = 49624 WHERE `entry` = 49624; + +DELETE FROM `creature_loot_template` WHERE `Entry` IN (42333, 49624); +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(42333, 1, 43406, 100, 0, 1, 0, 1, 1, 'High Priestess Azil N - Reference Loot'), +(49624, 1, 43407, 100, 0, 1, 0, 1, 1, 'High Priestess Azil H - Reference Loot'), +(49624, 52078, 0, 100, 0, 1, 0, 1, 1, 'High Priestess Azil H - Chaos Orb'); + +DELETE FROM `reference_loot_template` WHERE `Entry` IN (43406, 43407); +INSERT INTO `reference_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES +(43406, 55812, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55813, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55814, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55815, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55816, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55817, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55818, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55819, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55820, 0, 0, 0, 1, 1, 1, 1, NULL), +(43406, 55821, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56343, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56344, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56345, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56346, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56347, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56348, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56349, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56350, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56351, 0, 0, 0, 1, 1, 1, 1, NULL), +(43407, 56352, 0, 0, 0, 1, 1, 1, 1, NULL); + +DELETE FROM `spell_target_position` WHERE `id` IN (79193, 79199, 86860, 86858, 86856); +INSERT INTO `spell_target_position` (`id`, `effIndex`, `target_map`, `target_position_x`, `target_position_y`, `target_position_z`, `target_orientation`, `VerifiedBuild`) VALUES +(79193, 0, 725, 1260, 960, 205.443756, 0, 0), +(79199, 0, 725, 1280, 1050, 210.383057, 0, 0), +(86860, 0, 725, 1350.75, 919.133, 194.769, 0, 0), +(86858, 0, 725, 1341.19, 913.399, 197.092, 0, 0), +(86856, 0, 725, 1361.89, 920.219, 196.308, 0, 0); + +-- Set UNIT_FLAG_NOT_SELECTABLE to Gravity Well and Seismic Shard. +UPDATE `creature_template` SET `unit_flags` = 33554432 WHERE `entry` IN (42499, 42355); diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 0e43a63c98e3d..ad727fc17d25c 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -677,6 +677,12 @@ void AddSC_zangarmarsh(); // Maelstrom void AddSC_kezan(); +void AddSC_instance_stonecore(); // Stonecore +void AddSC_stonecore(); +void AddSC_boss_corborus(); +void AddSC_boss_slabhide(); +void AddSC_boss_ozruk(); +void AddSC_boss_high_priestess_azil(); // Events void AddSC_event_childrens_week(); @@ -1411,6 +1417,12 @@ void AddMaelstromScripts() { #ifdef SCRIPTS AddSC_kezan(); + AddSC_instance_stonecore(); // Stonecore + AddSC_stonecore(); + AddSC_boss_corborus(); + AddSC_boss_slabhide(); + AddSC_boss_ozruk(); + AddSC_boss_high_priestess_azil(); #endif } diff --git a/src/server/scripts/Maelstrom/CMakeLists.txt b/src/server/scripts/Maelstrom/CMakeLists.txt index 79f0789fd3f6c..8d3f1ee1c699a 100644 --- a/src/server/scripts/Maelstrom/CMakeLists.txt +++ b/src/server/scripts/Maelstrom/CMakeLists.txt @@ -9,6 +9,13 @@ set(scripts_STAT_SRCS ${scripts_STAT_SRCS} Maelstrom/kezan.cpp + Maelstrom/Stonecore/instance_stonecore.cpp + Maelstrom/Stonecore/stonecore.cpp + Maelstrom/Stonecore/stonecore.h + Maelstrom/Stonecore/boss_corborus.cpp + Maelstrom/Stonecore/boss_slabhide.cpp + Maelstrom/Stonecore/boss_ozruk.cpp + Maelstrom/Stonecore/boss_high_priestess_azil.cpp ) message(" -> Prepared: The Maelstrom") diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp new file mode 100644 index 0000000000000..2d522928fcea9 --- /dev/null +++ b/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * 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 . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "CreatureGroups.h" +#include "stonecore.h" + +// TO-DO: +// Find heroic sniffs and script spawning Crystal Shards on heroic mode. + +enum Spells +{ + // Corborus intro + SPELL_TWILIGHT_DOCUMENTS = 93167, + SPELL_RING_WYRM_CHARGE = 81237, + SPELL_DOOR_BREAK = 81232, // cast by World Trigger 22515 + + // Corborus boss + SPELL_DAMPENING_WAVE = 82415, + SPELL_CRYSTAL_BARRAGE = 86881, // 81638 triggers 81637 +// SPELL_CRYSTAL_BARRAGE_SHARD = 92012, // heroic only, summons Crystal Shard (TO-DO!) + SPELL_CLEAR_ALL_DEBUFFS = 34098, + SPELL_SUBMERGE = 81629, + SPELL_TRASHING_CHARGE_TELEPORT = 81839, // triggers 81864 +// SPELL_TRASHING_CHARGE_TELEPORT_2= 81838, // dummy, targets all players, threat update packet follows + SPELL_SUMMON_TRASHING_CHARGE = 81816, + SPELL_TRASHING_CHARGE_VISUAL = 81801, // cast time 3.5 sec + SPELL_TRASHING_CHARGE_EFFECT = 81828, // 40 yard radius + SPELL_EMERGE = 81948, + + // Rock Borer npc (43917) + SPELL_ROCK_BORER_EMERGE = 82185, + SPELL_ROCK_BORE = 80028, +}; + +enum NPCs +{ + NPC_TRASHING_CHARGE = 43743, +// NPC_CRYSTAL_SHARD = 49267, // 49473 +}; + +enum Events +{ + EVENT_NONE, + + // Corborus intro + EVENT_CORBORUS_CHARGE, + EVENT_CORBORUS_KNOCKBACK, + EVENT_CORBORUS_FACEPLAYERS, + + // Corborus boss + EVENT_DAMPENING_WAVE, + EVENT_CRYSTAL_BARRAGE, + EVENT_SUBMERGE, + EVENT_TELEPORT, + EVENT_TRASHING_CHARGE, + EVENT_SUMMON_BEETLE, + EVENT_EMERGE, + EVENT_ATTACK, + + // Rock Borer + EVENT_EMERGED, + EVENT_ROCK_BORE, +}; + +class boss_corborus : public CreatureScript +{ + public: + boss_corborus() : CreatureScript("boss_corborus") { } + + struct boss_corborusAI : public BossAI + { + boss_corborusAI(Creature* creature) : BossAI(creature, DATA_CORBORUS) + { + stateIntro = NOT_STARTED; + } + + void Reset() override + { + _Reset(); + countTrashingCharge = 0; + events.ScheduleEvent(EVENT_DAMPENING_WAVE, 10000); + events.ScheduleEvent(EVENT_CRYSTAL_BARRAGE, 15000); + events.ScheduleEvent(EVENT_SUBMERGE, 36000); + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_CORBORUS_INTRO: // Executes Corborus intro event + { + if (stateIntro != NOT_STARTED) + return; + + stateIntro = IN_PROGRESS; + + if (Creature* Millhouse = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MILLHOUSE_MANASTORM))) + { + Millhouse->InterruptNonMeleeSpells(true); + Millhouse->RemoveAllAuras(); + Millhouse->HandleEmoteCommand(EMOTE_ONESHOT_KNOCKDOWN); + } + + events.ScheduleEvent(EVENT_CORBORUS_CHARGE, 1000); + break; + } + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && stateIntro != IN_PROGRESS) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CORBORUS_CHARGE: + // Face Millhouse and other mobs + instance->SetData(DATA_MILLHOUSE_EVENT_FACE, 0); + + // Open rock gate and cast visual from nearby worldtrigger + instance->HandleGameObject(instance->GetGuidData(GAMEOBJECT_CORBORUS_ROCKDOOR), true); + if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 60.0f)) + worldtrigger->CastSpell(worldtrigger, SPELL_DOOR_BREAK, true); + + // Make Corborus charge + me->CastSpell(me, SPELL_RING_WYRM_CHARGE, true); + + events.ScheduleEvent(EVENT_CORBORUS_KNOCKBACK, 1000); + break; + case EVENT_CORBORUS_KNOCKBACK: + // Spawn Twilight Documents (quest gameobject) + if (Creature* Millhouse = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_MILLHOUSE_MANASTORM))) + Millhouse->CastSpell(Millhouse, SPELL_TWILIGHT_DOCUMENTS, true); + + // Knockback Millhouse and other mobs + instance->SetData(DATA_MILLHOUSE_EVENT_KNOCKBACK, 0); + + events.ScheduleEvent(EVENT_CORBORUS_FACEPLAYERS, 2000); + break; + case EVENT_CORBORUS_FACEPLAYERS: + // Face Corborus to players and set new home position + me->SetFacingTo(3.176499f); + me->SetHomePosition(1154.55f, 878.843f, 284.963f, 3.176499f); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + + // Despawn Millhouse and all trash + instance->SetData(DATA_MILLHOUSE_EVENT_DESPAWN, 0); + + stateIntro = DONE; + break; + case EVENT_DAMPENING_WAVE: + DoCastVictim(SPELL_DAMPENING_WAVE); + events.ScheduleEvent(EVENT_DAMPENING_WAVE, 15000); + break; + case EVENT_CRYSTAL_BARRAGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_CRYSTAL_BARRAGE); + events.ScheduleEvent(EVENT_CRYSTAL_BARRAGE, 10000); + break; + case EVENT_SUBMERGE: + events.RescheduleEvent(EVENT_DAMPENING_WAVE, 35000); + events.RescheduleEvent(EVENT_CRYSTAL_BARRAGE, 30000); + events.RescheduleEvent(EVENT_SUBMERGE, 100000); + + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); + me->AttackStop(); + + DoCast(me, SPELL_SUBMERGE); + + countTrashingCharge = 0; + events.ScheduleEvent(EVENT_TELEPORT, 500); + break; + case EVENT_TELEPORT: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_TRASHING_CHARGE_TELEPORT); + countTrashingCharge += 1; + if (countTrashingCharge <= 4) + events.ScheduleEvent(EVENT_TRASHING_CHARGE, 1000); + else + events.ScheduleEvent(EVENT_EMERGE, 2500); + break; + case EVENT_TRASHING_CHARGE: + DoCast(me, SPELL_SUMMON_TRASHING_CHARGE); + DoCast(me, SPELL_TRASHING_CHARGE_VISUAL); + events.ScheduleEvent(EVENT_TELEPORT, 5000); + break; + case EVENT_EMERGE: + me->RemoveAllAuras(); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + DoCast(me, SPELL_EMERGE); + events.ScheduleEvent(EVENT_ATTACK, 2500); + break; + case EVENT_ATTACK: + me->SetReactState(REACT_AGGRESSIVE); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() != NPC_TRASHING_CHARGE) + return; + + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell(summon, SPELL_TRASHING_CHARGE_EFFECT); + summon->DespawnOrUnsummon(6000); + } + + private: + EncounterState stateIntro; + uint32 countTrashingCharge; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 43391 - Rock Borer +class npc_rock_borer : public CreatureScript +{ + public: + npc_rock_borer() : CreatureScript("npc_rock_borer") { } + + struct npc_rock_borerAI : public ScriptedAI + { + npc_rock_borerAI(Creature* creature) : ScriptedAI(creature) + { + me->SetDisableGravity(true); + me->SetReactState(REACT_PASSIVE); + events.ScheduleEvent(EVENT_EMERGED, 1200); + events.ScheduleEvent(EVENT_ROCK_BORE, urand(15000, 20000)); // Need sniffs for this timer + } + + void IsSummonedBy(Unit* summoner) override + { + me->SetInCombatState(false, summoner); + DoCast(SPELL_ROCK_BORER_EMERGE); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && me->GetReactState() != REACT_PASSIVE) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_EMERGED: + me->RemoveAurasDueToSpell(SPELL_ROCK_BORER_EMERGE); + me->SetReactState(REACT_AGGRESSIVE); + break; + case EVENT_ROCK_BORE: + DoCast(SPELL_ROCK_BORE); + events.ScheduleEvent(EVENT_ROCK_BORE, urand(15000, 20000)); // Need sniffs for this timer + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +void AddSC_boss_corborus() +{ + new boss_corborus(); + new npc_rock_borer(); +} diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp new file mode 100644 index 0000000000000..fc14bf7a703a1 --- /dev/null +++ b/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp @@ -0,0 +1,807 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * 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 . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "Vehicle.h" +#include "stonecore.h" + +enum Spells +{ + SPELL_ENERGY_SHIELD = 82858, + + SPELL_CURSE_OF_BLOOD = 79345, + SPELL_FORCE_GRIP = 79351, + SPELL_SUMMON_GRAVITY_WELL = 79340, + SPELL_EARTH_FURY_ENERGY_SHIELD = 79050, + + // Gravity Well + SPELL_GRAVITY_WELL_VISUAL = 79245, + SPELL_GRAVITY_WELL_AURA_DAMAGE = 79244, + SPELL_GRAVITY_WELL_AURA_PULL = 79333, + + SPELL_GRAVITY_WELL_DAMAGE = 79249, + SPELL_GRAVITY_WELL_PULL = 79332, + + // Fury of Earth phase + SPELL_EARTH_FURY_CASTING_VISUAL = 79002, + SPELL_SEISMIC_SHARD_SUMMON_1 = 86860, + SPELL_SEISMIC_SHARD_SUMMON_2 = 86858, + SPELL_SEISMIC_SHARD_SUMMON_3 = 86856, + SPELL_SEISMIC_SHARD_VISUAL = 79009, + SPELL_SEISMIC_SHARD_PREPARE = 86862, + SPELL_SEISMIC_SHARD_TARGETING = 80511, + SPELL_SEISMIC_SHARD_LAUNCH = 79015, + SPELL_SEISMIC_SHARD_MISSLE = 79014, + SPELL_EJECT_ALL_PASSENGERS = 68576, + + // Add wave spells + SPELL_SUMMON_WAVE_SOUTH = 79200, + SPELL_SUMMON_WAVE_WEST = 79196, + SPELL_SUMMON_ADD_SOUTH = 79193, + SPELL_SUMMON_ADD_WEST = 79199, +}; + +enum NPCs +{ + NPC_DEVOUT_FOLLOWER = 42428, + NPC_SEISMIC_SHARD = 42355, +}; + +enum Texts +{ + SAY_AGGRO = 0, + SAY_PHASE_TWO = 1, + SAY_DEATH = 2, +}; + +enum Events +{ + EVENT_NONE, + + EVENT_INTRO_MOVE, + + EVENT_CURSE_OF_BLOOD, + EVENT_FORCE_GRIP, + EVENT_SUMMON_GRAVITY_WELL, + EVENT_ENERGY_SHIELD, + EVENT_EARTH_FURY, + + EVENT_SUMMON_WAVE_SOUTH, + EVENT_SUMMON_WAVE_WEST, + + EVENT_GRAVITY_WELL_AURA_DAMAGE, + EVENT_GRAVITY_WELL_AURA_PULL, + + // Phase 2: Fury of Earth + EVENT_EARTH_FURY_FLY_UP, + EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM, + EVENT_EARTH_FURY_CHECK_SEAT0, + EVENT_EARTH_FURY_LAUNCH_SHARD, + EVENT_EARTH_FURY_FLY_DOWN, + EVENT_START_ATTACK, + + EVENT_LAUNCH, + EVENT_SEISMIC_SHARD_MOUNT +}; + +enum EventGroups +{ + EVENT_GROUP_PHASE_ONE, + EVENT_GROUP_ADDS, +}; + +enum Points +{ + POINT_NONE, + + POINT_INTRO_MOVE, + POINT_FLY_UP, + POINT_ABOVE_PLATFORM, + POINT_PLATFORM, + POINT_GROUND, +}; + +Position const GroundPos = { 1331.82f, 980.314f, 207.542f }; +Position const AbovePlatformPos = { 1336.21f, 960.813f, 215.0f }; + +// TO-DO: +// - Find out why NPCs summoned by boss are usually two times bigger than their normal size. +// - Find more sniffs and script Force Grip spell (79351) + +class boss_high_priestess_azil : public CreatureScript +{ + public: + boss_high_priestess_azil() : CreatureScript("boss_high_priestess_azil") { } + + struct boss_high_priestess_azilAI : public BossAI + { + boss_high_priestess_azilAI(Creature* creature) : BossAI(creature, DATA_HIGH_PRIESTESS_AZIL), vehicle(creature->GetVehicleKit()) + { + ASSERT(vehicle); + } + + Vehicle* vehicle; + + void Reset() override + { + _Reset(); + + me->SetCanFly(false); + me->SetDisableGravity(false); + me->SetReactState(REACT_PASSIVE); + + events.ScheduleEvent(EVENT_INTRO_MOVE, 2000); + events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 6000, EVENT_GROUP_PHASE_ONE); + events.ScheduleEvent(EVENT_FORCE_GRIP, urand(8000,10000), EVENT_GROUP_PHASE_ONE); + events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, 16000, EVENT_GROUP_PHASE_ONE); + events.ScheduleEvent(EVENT_ENERGY_SHIELD, urand(35000,36000)); + events.ScheduleEvent(EVENT_SUMMON_WAVE_SOUTH, 0); + events.ScheduleEvent(EVENT_SUMMON_WAVE_WEST, 40000); + } + + void EnterCombat(Unit* /*victim*/) override + { + _EnterCombat(); + + DoCast(SPELL_ENERGY_SHIELD); + Talk(SAY_AGGRO); + } + + void JustDied(Unit* killer) override + { + me->Say(SAY_DEATH); + } + + /* + void PassengerBoarded(Unit* who, int8 seatId, bool apply) override + { + if (!apply || who->GetEntry() != NPC_SEISMIC_SHARD) + return; + + Movement::MoveSplineInit init(who); + init.DisableTransportPathTransformations(); + if (seatId == 0) + init.MoveTo(12.13748f, 0.0f, 2.442475f); + else if (seatId == 1) + init.MoveTo(12.13748f, 17.5f, 11.19248f); + else + init.MoveTo(12.13748f, -17.5f, 11.19248f); + init.Launch(); + } + */ + + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE && id != POINT_INTRO_MOVE) + return; + + switch (id) + { + case POINT_INTRO_MOVE: + me->RemoveAurasDueToSpell(SPELL_ENERGY_SHIELD); + me->SetReactState(REACT_AGGRESSIVE); + break; + case POINT_FLY_UP: + me->SetCanFly(true); + me->SetDisableGravity(true); + events.ScheduleEvent(EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM, 1000); + break; + case POINT_ABOVE_PLATFORM: + me->SetFacingTo(5.218534f); + DoCast(SPELL_EARTH_FURY_CASTING_VISUAL); + DoCast(SPELL_SEISMIC_SHARD_SUMMON_1); + DoCast(SPELL_SEISMIC_SHARD_SUMMON_2); + DoCast(SPELL_SEISMIC_SHARD_SUMMON_3); + events.ScheduleEvent(EVENT_EARTH_FURY_CHECK_SEAT0, 6700); + break; + case POINT_GROUND: + DoCast(SPELL_EJECT_ALL_PASSENGERS); + me->SetCanFly(false); + me->SetDisableGravity(false); + me->SetReactState(REACT_AGGRESSIVE); + // Find more sniffs to correct these timers, this was copied from Reset() void. + events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 6000, EVENT_GROUP_PHASE_ONE); + events.ScheduleEvent(EVENT_FORCE_GRIP, urand(8000, 10000), EVENT_GROUP_PHASE_ONE); + events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, 16000, EVENT_GROUP_PHASE_ONE); + break; + default: + break; + } + } + + 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_INTRO_MOVE: + me->GetMotionMaster()->MoveJump(GroundPos, me->GetSpeed(MOVE_FLIGHT), 1.918408f, POINT_INTRO_MOVE); + break; + case EVENT_CURSE_OF_BLOOD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_CURSE_OF_BLOOD); + events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, urand(13000, 15000), EVENT_GROUP_PHASE_ONE); + break; + case EVENT_FORCE_GRIP: + DoCastVictim(SPELL_FORCE_GRIP); + events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, urand(13000, 15000), EVENT_GROUP_PHASE_ONE); + break; + case EVENT_SUMMON_GRAVITY_WELL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_SUMMON_GRAVITY_WELL); + events.ScheduleEvent(EVENT_SUMMON_GRAVITY_WELL, urand(13000, 15000), EVENT_GROUP_PHASE_ONE); + break; + case EVENT_ENERGY_SHIELD: + events.CancelEventGroup(EVENT_GROUP_PHASE_ONE); + DoCast(SPELL_EARTH_FURY_ENERGY_SHIELD); + events.ScheduleEvent(EVENT_EARTH_FURY, 0); + break; + case EVENT_EARTH_FURY: + countSeismicShard = 3; + me->SetReactState(REACT_PASSIVE); + me->SetFacingTo(5.862942f); + events.ScheduleEvent(EVENT_EARTH_FURY_FLY_UP, 1600); + break; + case EVENT_EARTH_FURY_FLY_UP: + Talk(SAY_PHASE_TWO); + me->GetMotionMaster()->MovePoint(POINT_FLY_UP, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 5); + break; + case EVENT_EARTH_FURY_FLY_ABOVE_PLATFORM: + me->GetMotionMaster()->MovePoint(POINT_ABOVE_PLATFORM, AbovePlatformPos); + break; + case EVENT_EARTH_FURY_CHECK_SEAT0: + if (!vehicle->GetPassenger(0)) + DoCast(SPELL_SEISMIC_SHARD_PREPARE); + events.ScheduleEvent(EVENT_EARTH_FURY_LAUNCH_SHARD, 1800); + break; + case EVENT_EARTH_FURY_LAUNCH_SHARD: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + { + me->SetFacingToObject(target); + DoCast(target, SPELL_SEISMIC_SHARD_TARGETING); + DoCast(SPELL_SEISMIC_SHARD_LAUNCH); + countSeismicShard -= 1; + } + events.ScheduleEvent(countSeismicShard > 0 ? EVENT_EARTH_FURY_CHECK_SEAT0 : EVENT_EARTH_FURY_FLY_DOWN, 4800); + break; + case EVENT_EARTH_FURY_FLY_DOWN: + { + me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_CASTING_VISUAL); + me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_ENERGY_SHIELD); + Position pos = me->GetPosition(); + pos.m_positionZ = me->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + me->GetMotionMaster()->MovePoint(POINT_GROUND, pos); + break; + } + case EVENT_SUMMON_WAVE_SOUTH: + if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f)) + worldtrigger->CastSpell(worldtrigger, SPELL_SUMMON_WAVE_SOUTH); + events.ScheduleEvent(EVENT_SUMMON_WAVE_SOUTH, 12000); + break; + case EVENT_SUMMON_WAVE_WEST: + if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f)) + worldtrigger->CastSpell(worldtrigger, SPELL_SUMMON_WAVE_WEST); + events.ScheduleEvent(EVENT_SUMMON_WAVE_WEST, 20000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + uint8 countSeismicShard; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 42428 - Devout Follower +class npc_devout_follower : public CreatureScript +{ +public: + npc_devout_follower() : CreatureScript("npc_devout_follower") { } + + struct npc_devout_followerAI : public ScriptedAI + { + npc_devout_followerAI(Creature* creature) : ScriptedAI(creature) { } + + void IsSummonedBy(Unit* summoner) override + { + if (summoner->GetEntry() != NPC_WORLDTRIGGER) + return; + + if (Unit* target = me->SelectNearestPlayer(200.0f)) + { + me->AddThreat(target, 0.0f); + me->SetInCombatWith(target); + target->SetInCombatWith(me); + DoStartMovement(target); + me->Attack(target, true); + } + else + me->GetMotionMaster()->MovePoint(POINT_NONE, summoner->GetPosition()); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 42499 - Gravity Well +class npc_gravity_well : public CreatureScript +{ +public: + npc_gravity_well() : CreatureScript("npc_gravity_well") { } + + struct npc_gravity_wellAI : public ScriptedAI + { + npc_gravity_wellAI(Creature* creature) : ScriptedAI(creature) + { + me->SetReactState(REACT_PASSIVE); + DoCast(SPELL_GRAVITY_WELL_VISUAL); + events.ScheduleEvent(EVENT_GRAVITY_WELL_AURA_DAMAGE, 3200); + events.ScheduleEvent(EVENT_GRAVITY_WELL_AURA_PULL, 4500); + if (!me->GetMap()->IsHeroic()) + me->DespawnOrUnsummon(23200); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetEntry() != NPC_DEVOUT_FOLLOWER) + return; + + me->SetObjectScale(me->GetObjectScale() - 0.25f); + if (me->GetObjectScale() <= 0.0f) + me->DespawnOrUnsummon(1000); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_GRAVITY_WELL_AURA_DAMAGE: + me->RemoveAurasDueToSpell(SPELL_GRAVITY_WELL_VISUAL); + DoCast(SPELL_GRAVITY_WELL_AURA_DAMAGE); + break; + case EVENT_GRAVITY_WELL_AURA_PULL: + DoCast(SPELL_GRAVITY_WELL_AURA_PULL); + break; + default: + break; + } + } + } + + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 42355 - Seismic Shard +class npc_seismic_shard : public CreatureScript +{ +public: + npc_seismic_shard() : CreatureScript("npc_seismic_shard") { } + + struct npc_seismic_shardAI : public ScriptedAI + { + npc_seismic_shardAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + me->SetDisableGravity(true); + me->SetReactState(REACT_PASSIVE); + DoCast(SPELL_SEISMIC_SHARD_VISUAL); + + Movement::MoveSplineInit init(me); + FillPath(me->GetPosition(), init.Path()); + init.SetFly(); + init.Launch(); + + events.ScheduleEvent(EVENT_SEISMIC_SHARD_MOUNT, 2400); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SEISMIC_SHARD_MOUNT: + if (Creature* highPriestAzil = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HIGH_PRIESTESS_AZIL))) + if (Vehicle* vehicle = highPriestAzil->GetVehicleKit()) + me->EnterVehicle(highPriestAzil, vehicle->GetNextEmptySeat(0, false)->first); + break; + default: + break; + } + } + + } + + private: + void FillPath(Position const& pos, Movement::PointsArray& path) + { + G3D::Vector3 point; + + point.x = pos.GetPositionX(); + point.y = pos.GetPositionY(); + point.z = pos.GetPositionZ(); + + point.x -= 1.0f; + path.push_back(point); + + point.x += 1.0f; + path.push_back(point); + + point.z += 25.0f; + path.push_back(point); + + path.push_back(point); + } + + InstanceScript* instance; + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 79200 - Summon Follower +class spell_summon_wave_south : public SpellScriptLoader +{ +public: + spell_summon_wave_south() : SpellScriptLoader("spell_summon_wave_south") { } + + class spell_summon_wave_south_SpellScript : public SpellScript + { + PrepareSpellScript(spell_summon_wave_south_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ADD_SOUTH)) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + for (uint8 i = 0; i < 3; i++) + GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_ADD_SOUTH, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_summon_wave_south_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_summon_wave_south_SpellScript(); + } +}; + +// 79196 - Summon Follower +class spell_summon_wave_west : public SpellScriptLoader +{ +public: + spell_summon_wave_west() : SpellScriptLoader("spell_summon_wave_west") { } + + class spell_summon_wave_west_SpellScript : public SpellScript + { + PrepareSpellScript(spell_summon_wave_west_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_ADD_WEST)) + return false; + return true; + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + for (uint8 i = 0; i < 10; i++) + GetCaster()->CastSpell(GetCaster(), SPELL_SUMMON_ADD_WEST, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_summon_wave_west_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_summon_wave_west_SpellScript(); + } +}; + +// 79251 - Gravity Well (casts damage spell on units within 10 yards) +class PlayerPetOrDevoutFollowerCheck +{ +public: + bool operator()(WorldObject* object) const + { + // Valid targets are players, pets and Devout Followers + if (Creature* creature = object->ToCreature()) + return (!creature->ToPet() && object->GetEntry() != NPC_DEVOUT_FOLLOWER); + return (!object->ToPlayer()); + } +}; + +class spell_gravity_well_damage_nearby : public SpellScriptLoader +{ +public: + spell_gravity_well_damage_nearby() : SpellScriptLoader("spell_gravity_well_damage_nearby") { } + + class spell_gravity_well_damage_nearby_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gravity_well_damage_nearby_SpellScript); + + void SetRadiusMod() + { + GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, int32(GetCaster()->GetObjectScale() * 10000 * 2 / 3)); + } + + void FilterTargets(std::list& unitList) + { + unitList.remove_if(PlayerPetOrDevoutFollowerCheck()); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_GRAVITY_WELL_DAMAGE, true); + } + + void Register() override + { + BeforeCast += SpellCastFn(spell_gravity_well_damage_nearby_SpellScript::SetRadiusMod); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gravity_well_damage_nearby_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_gravity_well_damage_nearby_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_gravity_well_damage_nearby_SpellScript(); + } +}; + +// 79249 - Gravity Well (damage) +class spell_gravity_well_damage : public SpellScriptLoader +{ +public: + spell_gravity_well_damage() : SpellScriptLoader("spell_gravity_well_damage") { } + + class spell_gravity_well_damage_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gravity_well_damage_SpellScript); + + void CalculateDamage(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + if (!target) + return; + + float distance = GetCaster()->GetDistance2d(target); + + if (target->GetEntry() == NPC_DEVOUT_FOLLOWER) + SetHitDamage(int32(200000 - (1000 * distance))); //need more research on this formula, damage values from sniffs: 189264, 190318, 190478, 196134, 197672, 199735 + else + SetHitDamage(int32(4000 - (200 * distance))); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_gravity_well_damage_SpellScript::CalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_gravity_well_damage_SpellScript(); + } +}; + +// 79332 - Gravity Well (pull units within 10 yards) +class PulledRecentlyCheck +{ +public: + bool operator()(WorldObject* object) const + { + return (object->ToUnit() && object->ToUnit()->HasAura(SPELL_GRAVITY_WELL_PULL)); + } +}; + +class spell_gravity_well_pull : public SpellScriptLoader +{ +public: + spell_gravity_well_pull() : SpellScriptLoader("spell_gravity_well_pull") { } + + class spell_gravity_well_pull_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gravity_well_pull_SpellScript); + + void SetRadiusMod() + { + GetSpell()->SetSpellValue(SPELLVALUE_RADIUS_MOD, int32(GetCaster()->GetObjectScale() * 10000 * 2 / 3)); + } + + void FilterTargets(std::list& unitList) + { + unitList.remove_if(PulledRecentlyCheck()); + } + + void Register() override + { + BeforeCast += SpellCastFn(spell_gravity_well_pull_SpellScript::SetRadiusMod); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gravity_well_pull_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_gravity_well_pull_SpellScript(); + } +}; + +// 86862 - Seismic Shard (forces target to cast 86863) +class spell_seismic_shard_prepare : public SpellScriptLoader +{ +public: + spell_seismic_shard_prepare() : SpellScriptLoader("spell_seismic_shard_prepare") { } + + class spell_seismic_shard_prepare_SpellScript : public SpellScript + { + PrepareSpellScript(spell_seismic_shard_prepare_SpellScript); + + void SetTarget(WorldObject*& target) + { + target = GetCaster()->FindNearestCreature(NPC_SEISMIC_SHARD, 50.0f); + } + + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_seismic_shard_prepare_SpellScript::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_seismic_shard_prepare_SpellScript(); + } +}; + +// 86863 - Seismic Shard (moves shard to seat 0) +class spell_seismic_shard_change_seat : public SpellScriptLoader +{ +public: + spell_seismic_shard_change_seat() : SpellScriptLoader("spell_seismic_shard_change_seat") { } + + class spell_seismic_shard_change_seat_SpellScript : public SpellScript + { + PrepareSpellScript(spell_seismic_shard_change_seat_SpellScript); + + void SetTarget(WorldObject*& target) + { + if (InstanceScript* instance = GetCaster()->GetInstanceScript()) + target = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_HIGH_PRIESTESS_AZIL)); + } + + void ChangeSeat(SpellEffIndex /*effIndex*/) + { + GetCaster()->ExitVehicle(); + if (GetHitUnit()->IsVehicle()) + GetCaster()->EnterVehicle(GetHitUnit(), 0); + } + + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_seismic_shard_change_seat_SpellScript::SetTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_seismic_shard_change_seat_SpellScript::ChangeSeat, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_seismic_shard_change_seat_SpellScript(); + } +}; + +// 79015 - Seismic Shard (launches shard) +class spell_seismic_shard : public SpellScriptLoader +{ +public: + spell_seismic_shard() : SpellScriptLoader("spell_seismic_shard") { } + + class spell_seismic_shard_SpellScript : public SpellScript + { + PrepareSpellScript(spell_seismic_shard_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Creature* target = GetHitUnit()->ToCreature(); + if (!target) + return; + + target->ExitVehicle(); + DynamicObject* dynamicObject = GetCaster()->GetDynObject(SPELL_SEISMIC_SHARD_TARGETING); + target->CastSpell(dynamicObject->GetPositionX(), dynamicObject->GetPositionY(), dynamicObject->GetPositionZ(), SPELL_SEISMIC_SHARD_MISSLE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_seismic_shard_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_seismic_shard_SpellScript(); + } +}; + +void AddSC_boss_high_priestess_azil() +{ + new boss_high_priestess_azil(); + new npc_devout_follower(); + new npc_gravity_well(); + new npc_seismic_shard(); + new spell_summon_wave_south(); + new spell_summon_wave_west(); + new spell_gravity_well_damage_nearby(); + new spell_gravity_well_damage(); + new spell_gravity_well_pull(); + new spell_seismic_shard_prepare(); + new spell_seismic_shard_change_seat(); + new spell_seismic_shard(); +} diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp new file mode 100644 index 0000000000000..92c9bba4bc198 --- /dev/null +++ b/src/server/scripts/Maelstrom/Stonecore/boss_ozruk.cpp @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * 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 . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "Vehicle.h" +#include "stonecore.h" + +enum Spells +{ + SPELL_ELEMENTIUM_BULWARK = 78939, + SPELL_GROUND_SLAM = 78903, + SPELL_ELEMENTIUM_SPIKE_SHIELD = 78835, + SPELL_SHATTER = 78807, + SPELL_ENRAGE = 80467, + + // Rupture Controller and Rupture + SPELL_RUPTURE = 92393, +// SPELL_RUPTURE_SUMMON_CENTER? = 95669, // summons rupture 8 yards front +// SPELL_RUPTURE_SUMMON_LEFT? = 95348, // summons rupture 3 yards left? +// SPELL_RUPTURE_SUMMON_RIGHT? = 92383, // summons rupture 3 yards right? + SPELL_RUPTURE_DAMAGE = 92381, +}; + +enum NPCs +{ + NPC_BOUNCER_SPIKE = 42189, + NPC_RUPTURE_CONTROLLER = 49597, + NPC_RUPTURE = 49576, +}; + +enum Texts +{ + SAY_AGGRO = 0, + SAY_ELEMENTIUM_BULWARK = 1, + SAY_ELEMENTIUM_SPIKE_SHIELD = 2, + SAY_ENRAGE = 3, + SAY_DEATH = 4, +}; + +enum Events +{ + EVENT_NONE, + + EVENT_ELEMENTIUM_BULWARK, + EVENT_GROUND_SLAM, + EVENT_ELEMENTIUM_SPIKE_SHIELD, + EVENT_SHATTER, + EVENT_ENRAGE, + + EVENT_START_ATTACK, +}; + +// TO-DO: +// - Find heroic sniffs and spawn Ruptures using spells commented above. +// - Make Bouncer Spikes enter ozruk without jump animation. + +class boss_ozruk : public CreatureScript +{ + public: + boss_ozruk() : CreatureScript("boss_ozruk") { } + + struct boss_ozrukAI : public BossAI + { + boss_ozrukAI(Creature* creature) : BossAI(creature, DATA_OZRUK) { } + + void Reset() override + { + _Reset(); + + me->SetReactState(REACT_AGGRESSIVE); + + events.ScheduleEvent(EVENT_ELEMENTIUM_BULWARK, 5000); + events.ScheduleEvent(EVENT_GROUND_SLAM, 10000); + events.ScheduleEvent(EVENT_ELEMENTIUM_SPIKE_SHIELD, 13000); + + RemoveBouncerSpikes(); + } + + void EnterCombat(Unit* /*victim*/) override + { + _EnterCombat(); + + Talk(SAY_AGGRO); + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() != NPC_RUPTURE_CONTROLLER) + return; + + summon->SetReactState(REACT_PASSIVE); + summon->CastSpell(summon, SPELL_RUPTURE, true); + summon->DespawnOrUnsummon(10000); + } + + void DamageTaken(Unit* /*attacker*/, uint32 &damage) override + { + if (!me->HealthBelowPctDamaged(25, damage) || me->HasAura(SPELL_ENRAGE)) + return; + + DoCast(me, SPELL_ENRAGE); + me->Say(SAY_ENRAGE); + } + + void JustDied(Unit* killer) override + { + me->Say(SAY_DEATH, killer); // receiver is the killer, sniff source! + + RemoveBouncerSpikes(); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_ELEMENTIUM_SPIKE_SHIELD)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ELEMENTIUM_BULWARK: + DoCast(me, SPELL_ELEMENTIUM_BULWARK); + Talk(SAY_ELEMENTIUM_BULWARK); + break; + case EVENT_GROUND_SLAM: + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + DoCast(me, SPELL_GROUND_SLAM); + events.ScheduleEvent(EVENT_START_ATTACK, 4600); + break; + case EVENT_ELEMENTIUM_SPIKE_SHIELD: + DoCast(me, SPELL_ELEMENTIUM_SPIKE_SHIELD); + Talk(SAY_ELEMENTIUM_SPIKE_SHIELD); + events.ScheduleEvent(EVENT_SHATTER, 10000); + break; + case EVENT_SHATTER: + RemoveBouncerSpikes(); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + DoCast(me, SPELL_SHATTER); + events.ScheduleEvent(EVENT_START_ATTACK, 4600); + // Spells are cast in same order everytime after Shatter, so we schedule them here + events.ScheduleEvent(EVENT_ELEMENTIUM_BULWARK, urand(3000,4000)); + events.ScheduleEvent(EVENT_GROUND_SLAM, urand(7000,9000)); + events.ScheduleEvent(EVENT_ELEMENTIUM_SPIKE_SHIELD, urand(10000,12000)); + break; + case EVENT_START_ATTACK: + me->SetReactState(REACT_AGGRESSIVE); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + void RemoveBouncerSpikes() + { + Vehicle* vehicle = me->GetVehicleKit(); + if (!vehicle) + return; + + for (uint8 i = 0; i < vehicle->GetAvailableSeatCount(); i++) + if (Unit* passenger = vehicle->GetPassenger(i)) + if (Creature* creature = passenger->ToCreature()) + creature->RemoveFromWorld(); + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 92393 - Rupture +class spell_rupture : public SpellScriptLoader +{ +public: + spell_rupture() : SpellScriptLoader("spell_rupture") { } + + class spell_rupture_AuraScript : public AuraScript + { + PrepareAuraScript(spell_rupture_AuraScript); + + void HandleEffectPeriodic(AuraEffect const* aurEff) + { + Unit* caster = GetCaster(); + + float dist = aurEff->GetTickNumber() * 8.0f; + + // probably hack, should use spells (see Spells enum above) + Position pos = caster->GetNearPosition(dist, 0.0f); + SummonRupture(caster, pos); + + pos = caster->GetNearPosition(dist, 0.2f); + SummonRupture(caster, pos); + + pos = caster->GetNearPosition(dist, -0.2f); + SummonRupture(caster, pos); + } + + void SummonRupture(Unit* caster, Position pos) + { + Creature* rupture = caster->SummonCreature(NPC_RUPTURE, pos, TEMPSUMMON_TIMED_DESPAWN, 2500); + if (!rupture) + return; + + rupture->SetReactState(REACT_PASSIVE); + rupture->CastSpell(rupture, SPELL_RUPTURE_DAMAGE, true); + } + + void Register() + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_rupture_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_rupture_AuraScript(); + } +}; + +// 78835 - Elementium Spike Shield +class spell_elementium_spike_shield : public SpellScriptLoader +{ +public: + spell_elementium_spike_shield() : SpellScriptLoader("spell_elementium_spike_shield") { } + + class spell_elementium_spike_shield_SpellScript : public SpellScript + { + PrepareSpellScript(spell_elementium_spike_shield_SpellScript); + + void HandleBouncerSpikes() + { + Unit* caster = GetCaster(); + Vehicle* vehicle = caster->GetVehicleKit(); + if (!vehicle) + return; + + for (uint8 i = 0; i < vehicle->GetAvailableSeatCount(); i++) + if (Creature* summon = caster->SummonCreature(NPC_BOUNCER_SPIKE, caster->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 10000)) + summon->EnterVehicle(caster, i); + } + + void Register() override + { + OnCast += SpellCastFn(spell_elementium_spike_shield_SpellScript::HandleBouncerSpikes); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_elementium_spike_shield_SpellScript(); + } +}; + +void AddSC_boss_ozruk() +{ + new boss_ozruk(); + new spell_rupture(); + new spell_elementium_spike_shield(); +} diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp new file mode 100644 index 0000000000000..6827312deef11 --- /dev/null +++ b/src/server/scripts/Maelstrom/Stonecore/boss_slabhide.cpp @@ -0,0 +1,599 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * 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 . + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "stonecore.h" + +enum Spells +{ + SPELL_FACE_RANDOM_PLAYER = 82530, + + // Stalactite Trigger - Trash, On Ground + SPELL_STALACTITE_SUMMON_TRIGGER = 81028, + + // Slabhide + SPELL_LAVA_FISSURE = 80803, + SPELL_SAND_BLAST = 80807, + SPELL_STALACTITE_SUMMON = 80656, +// SPELL_COOLDOWN_5S = 95323, Cooldown: Creature Special 1 (5s)? + SPELL_CRYSTAL_STORM = 92305, + SPELL_CRYSTAL_STORM_TRIGGER = 92265, + + // Lava Fissure + SPELL_LAVA_FISSURE_CRACK = 80798, + SPELL_LAVA_FISSURE_ERUPTION = 80800, + + // Stalactite Trigger - Boss + SPELL_STALACTITE_SHADE = 80654, + SPELL_STALACTITE_MISSLE = 80643, + SPELL_STALACTITE_CREATE = 80647, +}; + +enum Entries +{ + NPC_LAVA_FISSURE = 43242, + NPC_STALACTITE_TRIGGER_GROUND = 43357, + NPC_STALACTITE_TRIGGER = 43159, + GO_STALACTITE = 204337, +}; + +enum Actions +{ + ACTION_STALACTITE_MISSLE, +}; + +enum Events +{ + EVENT_NONE, + + // Intro events + EVENT_ROAR_EMOTE, + + // Slabhide combat + EVENT_HANDLE_ROCK_WALLS, + EVENT_LAVA_FISSURE, + EVENT_SAND_BLAST, + EVENT_AIR_PHASE, + EVENT_TAKEOFF, + EVENT_STALACTITE, + EVENT_LAND, + EVENT_ATTACK, + + // Lava Fissure + EVENT_LAVA_FISSURE_ERUPTION, + + // Stalactite Trigger - Boss + EVENT_STALACTITE_MISSLE, +}; + +enum MovementPoints +{ + POINT_NONE, + + POINT_SLABHIDE_INTRO, + POINT_SLABHIDE_INTRO_LAND, + + POINT_SLABHIDE_MIDDLE, + POINT_SLABHIDE_IN_AIR, + POINT_SLABHIDE_LAND, +}; + +Position const SlabhideIntroPos = { 1292.27f, 1226.16f, 265.573f }; +Position const SlabhideIntroLandPos = { 1292.352f, 1226.478f, 247.6368f, 3.630285f }; + +Position const SlabhideMiddlePos = { 1280.73f, 1212.31f, 247.3837f }; +Position const SlabhideInAirPos = { 1280.73f, 1212.31f, 257.3837f }; +Position const SlabhideLandPos = { 1282.7f, 1229.77f, 247.155f, 3.82227f }; + +class boss_slabhide : public CreatureScript +{ + public: + boss_slabhide() : CreatureScript("boss_slabhide") { } + + struct boss_slabhideAI : public BossAI + { + boss_slabhideAI(Creature* creature) : BossAI(creature, DATA_SLABHIDE) + { + me->setActive(true); + me->SetCanFly(true); + me->SetDisableGravity(true); + me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->SetReactState(REACT_PASSIVE); + instance->SetData(DATA_SLABHIDE_INTRO, NOT_STARTED); + } + + void Reset() + { + if (instance->GetData(DATA_SLABHIDE_INTRO) == NOT_STARTED) + return; + + _Reset(); + DespawnAll(); + + me->SetCanFly(false); + me->SetDisableGravity(false); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->SetReactState(REACT_AGGRESSIVE); + } + + void EnterCombat(Unit* /*victim*/) override + { + _EnterCombat(); + + events.ScheduleEvent(EVENT_HANDLE_ROCK_WALLS, 4000); + events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000)); + events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 10000)); + events.ScheduleEvent(EVENT_AIR_PHASE, 10000); + } + + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + + // Despawn related npcs and gameobjects + DespawnAll(); + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_SLABHIDE_INTRO: + { + if (instance->GetData(DATA_SLABHIDE_INTRO) != NOT_STARTED) + return; + + instance->SetData(DATA_SLABHIDE_INTRO, IN_PROGRESS); + + // Execute Slabhide intro event + me->GetMotionMaster()->MovePoint(POINT_SLABHIDE_INTRO, SlabhideIntroPos); + break; + } + default: + break; + } + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) + return; + + switch (id) + { + case POINT_SLABHIDE_INTRO: + me->SetFacingTo(SlabhideIntroLandPos.GetOrientation()); + me->GetMotionMaster()->MoveLand(POINT_SLABHIDE_INTRO_LAND, SlabhideIntroLandPos); + break; + case POINT_SLABHIDE_INTRO_LAND: + me->SetCanFly(false); + me->SetDisableGravity(false); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->SetHover(false); + me->SetHomePosition(SlabhideIntroLandPos); + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + instance->SetData(DATA_SLABHIDE_INTRO, DONE); + break; + case POINT_SLABHIDE_MIDDLE: + events.ScheduleEvent(EVENT_TAKEOFF, 100); + break; + case POINT_SLABHIDE_IN_AIR: + events.ScheduleEvent(EVENT_STALACTITE, 400); + break; + case POINT_SLABHIDE_LAND: + //DoCast(SPELL_COOLDOWN_5S); // unknown purpose + events.ScheduleEvent(EVENT_ATTACK, 1200); + break; + default: + break; + } + } + + 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_HANDLE_ROCK_WALLS: // Close rock walls + instance->SetData(DATA_SLABHIDE_ROCK_WALL, false); + break; + case EVENT_LAVA_FISSURE: + DoCast(SPELL_LAVA_FISSURE); + events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000)); + break; + case EVENT_SAND_BLAST: + DoCast(SPELL_SAND_BLAST); + events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 11000)); + break; + case EVENT_AIR_PHASE: + events.Reset(); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->GetMotionMaster()->MovePoint(POINT_SLABHIDE_MIDDLE, SlabhideMiddlePos); + events.ScheduleEvent(EVENT_AIR_PHASE, 60000); + break; + case EVENT_TAKEOFF: + me->GetMotionMaster()->MoveTakeoff(POINT_SLABHIDE_IN_AIR, SlabhideInAirPos); + break; + case EVENT_STALACTITE: + me->SetCanFly(true); + me->SetDisableGravity(true); + me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->SetHover(true); + + DoCast(SPELL_STALACTITE_SUMMON); + + events.ScheduleEvent(EVENT_LAND, 8000); + break; + case EVENT_LAND: + { + Position pos = me->GetPosition(); + pos.m_positionZ = me->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); + me->GetMotionMaster()->MoveLand(POINT_SLABHIDE_LAND, pos); + break; + } + case EVENT_ATTACK: + me->SetCanFly(false); + me->SetDisableGravity(false); + me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER); + me->SetHover(false); + + events.ScheduleEvent(EVENT_LAVA_FISSURE, urand(6000, 8000)); + events.ScheduleEvent(EVENT_SAND_BLAST, urand(8000, 10000)); + DoCast(SPELL_CRYSTAL_STORM); + me->SetReactState(REACT_AGGRESSIVE); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + + private: + void DespawnAll() + { + // Despawn stalactite triggers npcs + std::list listStalactiteTrigger; + me->GetCreatureListWithEntryInGrid(listStalactiteTrigger, NPC_STALACTITE_TRIGGER, 200.0f); + if (!listStalactiteTrigger.empty()) + for (std::list::const_iterator itr = listStalactiteTrigger.begin(); itr != listStalactiteTrigger.end(); ++itr) + (*itr)->DespawnOrUnsummon(); + + // Despawn stalactite objects + std::list listStalactite; + me->GetGameObjectListWithEntryInGrid(listStalactite, GO_STALACTITE, 200.0f); + if (!listStalactite.empty()) + for (std::list::const_iterator itr = listStalactite.begin(); itr != listStalactite.end(); ++itr) + (*itr)->Delete(); + } + + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 43242 - Lava Fissure +class npc_lava_fissure : public CreatureScript +{ +public: + npc_lava_fissure() : CreatureScript("npc_lava_fissure") { } + + struct npc_lava_fissureAI : public ScriptedAI + { + npc_lava_fissureAI(Creature* creature) : ScriptedAI(creature) + { + me->SetReactState(REACT_PASSIVE); + me->CastSpell(me, SPELL_LAVA_FISSURE_CRACK, true); + events.ScheduleEvent(EVENT_LAVA_FISSURE_ERUPTION, 6000); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_LAVA_FISSURE_ERUPTION: + me->RemoveAurasDueToSpell(SPELL_LAVA_FISSURE_CRACK); + me->CastSpell(me, SPELL_LAVA_FISSURE_ERUPTION, true); + me->DespawnOrUnsummon(14000); + break; + default: + break; + } + } + } + + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 43159 - Stalactite Trigger - Boss +class npc_stalactite_trigger : public CreatureScript +{ +public: + npc_stalactite_trigger() : CreatureScript("npc_stalactite_trigger") { } + + struct npc_stalactite_triggerAI : public ScriptedAI + { + npc_stalactite_triggerAI(Creature* creature) : ScriptedAI(creature) + { + me->SetReactState(REACT_PASSIVE); + me->SetDisableGravity(true); + me->CastSpell(me, SPELL_STALACTITE_SHADE, true); + events.ScheduleEvent(EVENT_STALACTITE_MISSLE, 5600); + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_STALACTITE_MISSLE: + DoCast(SPELL_STALACTITE_MISSLE); + me->DespawnOrUnsummon(11000); + break; + default: + break; + } + } + } + + private: + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 81035 - Stalactite (check if player is near to summon stalactite) +class NotPlayerCheck +{ + public: + bool operator()(WorldObject* object) const + { + return (object->GetTypeId() != TYPEID_PLAYER); + } +}; + +class spell_s81035_stalactite : public SpellScriptLoader +{ +public: + spell_s81035_stalactite() : SpellScriptLoader("spell_s81035_stalactite") { } + + class spell_s81035_stalactite_SpellScript : public SpellScript + { + PrepareSpellScript(spell_s81035_stalactite_SpellScript); + + void FilterTargets(std::list& targets) + { + targets.remove_if(NotPlayerCheck()); + } + + void SummonStalactiteTrigger() + { + Unit* caster = GetCaster(); + caster->CastSpell(caster, SPELL_STALACTITE_SUMMON_TRIGGER, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_s81035_stalactite_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnHit += SpellHitFn(spell_s81035_stalactite_SpellScript::SummonStalactiteTrigger); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_s81035_stalactite_SpellScript(); + } +}; + +// 81028 - Stalactite (summons "Stalactite Trigger - Boss", 20 yard radius) +// 80650 - Stalactite (summons "Stalactite Trigger - Boss", 40 yard radius) +class spell_s81028_s80650_stalactite : public SpellScriptLoader +{ +public: + spell_s81028_s80650_stalactite() : SpellScriptLoader("spell_s81028_s80650_stalactite") { } + + class spell_s81028_s80650_stalactite_SpellScript : public SpellScript + { + PrepareSpellScript(spell_s81028_s80650_stalactite_SpellScript); + + void ModDestHeight(SpellDestination& dest) + { + // All stalactite triggers should have Z position 301.3837f, but no way to relocate (not relocateoffset!) height only. + Position offset = { 0.0f, 0.0f, 50.0f, 0.0f }; + dest.RelocateOffset(offset); + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_s81028_s80650_stalactite_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER_RANDOM); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_s81028_s80650_stalactite_SpellScript(); + } +}; + +// 80654 - Stalactite (creates visual shade on ground) +// 80643/92653 - Stalactite (launches missle to the ground) +// 80647/92309 - Stalactite (creates stalactite object) +class spell_stalactite_mod_dest_height : public SpellScriptLoader +{ +public: + spell_stalactite_mod_dest_height() : SpellScriptLoader("spell_stalactite_mod_dest_height") { } + + class spell_stalactite_mod_dest_height_SpellScript : public SpellScript + { + PrepareSpellScript(spell_stalactite_mod_dest_height_SpellScript); + + void ModDestHeight(SpellDestination& dest) + { + Unit* caster = GetCaster(); + Position pos = caster->GetPosition(); + pos.m_positionZ = caster->GetMap()->GetHeight(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, 100.0f); + dest.Relocate(pos); + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_stalactite_mod_dest_height_SpellScript::ModDestHeight, EFFECT_0, TARGET_DEST_CASTER); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_stalactite_mod_dest_height_SpellScript(); + } +}; + +// 92306 - Crystal storm (heroic mode check) +class spell_s92306_crystal_storm : public SpellScriptLoader +{ +public: + spell_s92306_crystal_storm() : SpellScriptLoader("spell_s92306_crystal_storm") { } + + class spell_s92306_crystal_storm_SpellScript : public SpellScript + { + PrepareSpellScript(spell_s92306_crystal_storm_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + if (!sSpellMgr->GetSpellInfo(SPELL_CRYSTAL_STORM_TRIGGER)) + return false; + return true; + } + + void HandleDummyEffect(SpellEffIndex /*eff*/) + { + Unit* caster = GetCaster(); + if (caster->GetMap()->IsHeroic()) + caster->CastSpell(caster, SPELL_CRYSTAL_STORM_TRIGGER, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_s92306_crystal_storm_SpellScript::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_s92306_crystal_storm_SpellScript(); + } +}; + +// 92300 - Crystal Storm (damage) +class BehindObjectCheck +{ + public: + BehindObjectCheck(Unit* caster, std::list objectList) : caster(caster), objectList(objectList) { } + + bool operator()(WorldObject* unit) + { + for (std::list::const_iterator itr = objectList.begin(); itr != objectList.end(); ++itr) + if (!(*itr)->IsInvisibleDueToDespawn() && (*itr)->IsInBetween(caster, unit, 1.5f)) + return true; + return false; + } + + private: + Unit* caster; + std::list objectList; +}; + +class spell_s92300_crystal_storm : public SpellScriptLoader +{ +public: + spell_s92300_crystal_storm() : SpellScriptLoader("spell_s92300_crystal_storm") { } + + class spell_s92300_crystal_storm_SpellScript : public SpellScript + { + PrepareSpellScript(spell_s92300_crystal_storm_SpellScript); + + void FilterTargets(std::list& unitList) + { + Unit* caster = GetCaster(); + + std::list goList; + caster->GetGameObjectListWithEntryInGrid(goList, GO_STALACTITE, 40.0f); + if (goList.empty()) + return; + + unitList.remove_if(BehindObjectCheck(caster, goList)); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_s92300_crystal_storm_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_s92300_crystal_storm_SpellScript(); + } +}; + +void AddSC_boss_slabhide() +{ + new boss_slabhide(); + new npc_lava_fissure(); + new npc_stalactite_trigger(); + new spell_s81035_stalactite(); + new spell_s81028_s80650_stalactite(); + new spell_stalactite_mod_dest_height(); + new spell_s92306_crystal_storm(); + new spell_s92300_crystal_storm(); +} diff --git a/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp b/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp new file mode 100644 index 0000000000000..8cb4df0622fca --- /dev/null +++ b/src/server/scripts/Maelstrom/Stonecore/instance_stonecore.cpp @@ -0,0 +1,262 @@ +/* +* Copyright (C) 2008-2014 TrinityCore +* Copyright (C) 2006-2009 ScriptDev2 +* +* 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 . +*/ + +#include "ScriptMgr.h" +#include "Player.h" +#include "CreatureGroups.h" +#include "InstanceScript.h" +#include "stonecore.h" + +#define MAX_ENCOUNTER 4 + +/* Stonecore encounters: +0 - Corborus +1 - Slabhide +2 - Ozruk +3 - High Priestess Azil +*/ + +// TO-DO: +// - Find out spell IDs for both Stonecore Teleporters (spellclick). + +class instance_stonecore : public InstanceMapScript +{ + public: + instance_stonecore() : InstanceMapScript(SCScriptName, 725) { } + + struct instance_stonecore_InstanceScript : public InstanceScript + { + instance_stonecore_InstanceScript(Map* map) : InstanceScript(map) + { + SetHeaders(DataHeader); + SetBossNumber(MAX_ENCOUNTER); + } + + void OnGameObjectCreate(GameObject* go) override + { + switch (go->GetEntry()) + { + case GAMEOBJECT_CORBORUS_ROCKDOOR: + corborusRockDoorGUID = go->GetGUID(); + go->SetGoState(GetBossState(DATA_CORBORUS) != DONE ? GO_STATE_READY : GO_STATE_ACTIVE); + break; + case GAMEOBJECT_SLABHIDE_ROCK_WALL: + slabhideRockWallGUIDs.push_back(go->GetGUID()); + break; + default: + break; + } + } + + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_MILLHOUSE_MANASTORM: + millhouseGUID = creature->GetGUID(); + break; + case NPC_CORBORUS: + corobrusGUID = creature->GetGUID(); + break; + case NPC_SLABHIDE: + slabhideGUID = creature->GetGUID(); + break; + case NPC_HIGH_PRIESTESS_AZIL: + highPriestessAzilGUID = creature->GetGUID(); + break; + case NPC_STONECORE_TELEPORTER: + case NPC_STONECORE_TELEPORTER_2: + if (GetBossState(DATA_SLABHIDE) != DONE) + stonecoreTeleporterGUID[creature->GetEntry() - NPC_STONECORE_TELEPORTER] = creature->GetGUID(); + else // If Slabhide is already dead, no need to store teleporter guids + { + creature->CastSpell(creature, SPELL_TELEPORTER_ACTIVE_VISUAL, true); + creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + } + break; + default: + break; + } + + // Check if creature is part of Millhouse event + creature->SearchFormation(); + if (CreatureGroup* group = creature->GetFormation()) // TO-DO: Fix formations + { + switch (group->GetId()) + { + case CREATURE_FORMATION_MILLHOUSE_EVENT_TRASH: + millhouseTrashGUIDs.push_back(creature->GetGUID()); + break; + case CREATURE_FORMATION_MILLHOUSE_EVENT_LAST_GROUP: + millhouseLastGroupGUIDs.push_back(creature->GetGUID()); + creature->SetReactState(REACT_PASSIVE); + creature->SetMeleeAnimKitId(ANIM_READY2H); + break; + } + } + } + + bool SetBossState(uint32 type, EncounterState state) override + { + switch (type) + { + case DATA_SLABHIDE: + // Open rock walls (Slabhide AI handles closing because it must be delayed) + if (state != IN_PROGRESS) + SetData(DATA_SLABHIDE_ROCK_WALL, true); + + // Activate teleporters + if (state == DONE) + { + for (int8 i = 0; i < MAX_STONECORE_TELEPORTERS; i++) + { + if (Creature* teleporter = GetCreature(stonecoreTeleporterGUID[i])) + { + teleporter->CastSpell(teleporter, SPELL_TELEPORTER_ACTIVE_VISUAL, true); + teleporter->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); + } + } + } + + break; + default: + break; + } + + return InstanceScript::SetBossState(type, state); + } + + uint32 GetData(uint32 type) const override + { + switch (type) + { + case DATA_SLABHIDE_INTRO: + return slabhideIntro; + default: + break; + } + + return 0; + } + + void SetData(uint32 type, uint32 data) override + { + switch (type) + { + case DATA_MILLHOUSE_EVENT_FACE: + MillhouseEvent_Face(); + break; + case DATA_MILLHOUSE_EVENT_KNOCKBACK: + MillhouseEvent_Knockback(); + break; + case DATA_MILLHOUSE_EVENT_DESPAWN: + MillhouseEvent_Despawn(); + break; + case DATA_SLABHIDE_INTRO: + slabhideIntro = EncounterState(data); + break; + case DATA_SLABHIDE_ROCK_WALL: // Handles rock walls + for (std::vector::iterator itr = slabhideRockWallGUIDs.begin(); itr != slabhideRockWallGUIDs.end(); ++itr) + HandleGameObject((*itr), data ? true : false); + break; + default: + break; + } + } + + ObjectGuid GetGuidData(uint32 type) const override + { + switch (type) + { + case DATA_MILLHOUSE_MANASTORM: + return millhouseGUID; + case GAMEOBJECT_CORBORUS_ROCKDOOR: + return corborusRockDoorGUID; + case DATA_CORBORUS: + return corobrusGUID; + case DATA_SLABHIDE: + return slabhideGUID; + case DATA_HIGH_PRIESTESS_AZIL: + return highPriestessAzilGUID; + case NPC_STONECORE_TELEPORTER: + case NPC_STONECORE_TELEPORTER_2: + return stonecoreTeleporterGUID[type - NPC_STONECORE_TELEPORTER]; + default: + break; + } + + return ObjectGuid::Empty; + } + + private: + // Face Millhouse and other nearby mobs to Corborus + void MillhouseEvent_Face() + { + if (Creature* Millhouse = instance->GetCreature(millhouseGUID)) + Millhouse->SetFacingTo(1.570796f); + for (GuidVector::const_iterator i = millhouseLastGroupGUIDs.begin(); i != millhouseLastGroupGUIDs.end(); ++i) + if (Creature* creature = instance->GetCreature(*i)) + creature->SetFacingTo(1.570796f); + } + + // Knock back Millhouse and other mobs + void MillhouseEvent_Knockback() + { + if (Creature* Millhouse = instance->GetCreature(millhouseGUID)) + Millhouse->CastSpell(Millhouse, SPELL_RING_WYRM_KNOCKBACK, true); + for (GuidVector::const_iterator itr = millhouseLastGroupGUIDs.begin(); itr != millhouseLastGroupGUIDs.end(); ++itr) + if (Creature* creature = instance->GetCreature(*itr)) + creature->CastSpell(creature, SPELL_RING_WYRM_KNOCKBACK, true); + } + + // Despawn all mobs + void MillhouseEvent_Despawn() + { + if (Creature* Millhouse = instance->GetCreature(millhouseGUID)) + Millhouse->DespawnOrUnsummon(3000); + for (GuidVector::const_iterator itr = millhouseTrashGUIDs.begin(); itr != millhouseTrashGUIDs.end(); ++itr) + if (Creature* creature = instance->GetCreature(*itr)) + creature->DespawnOrUnsummon(3000); + for (GuidVector::const_iterator itr = millhouseLastGroupGUIDs.begin(); itr != millhouseLastGroupGUIDs.end(); ++itr) + if (Creature* creature = instance->GetCreature(*itr)) + creature->DespawnOrUnsummon(3000); + } + + ObjectGuid millhouseGUID; + GuidVector millhouseTrashGUIDs; + GuidVector millhouseLastGroupGUIDs; + ObjectGuid corborusRockDoorGUID; + ObjectGuid corobrusGUID; + ObjectGuid slabhideGUID; + ObjectGuid highPriestessAzilGUID; + ObjectGuid stonecoreTeleporterGUID[2]; + GuidVector slabhideRockWallGUIDs; + + EncounterState slabhideIntro; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const override + { + return new instance_stonecore_InstanceScript(map); + } +}; + +void AddSC_instance_stonecore() +{ + new instance_stonecore(); +} diff --git a/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp b/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp new file mode 100644 index 0000000000000..2612cd02385fe --- /dev/null +++ b/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp @@ -0,0 +1,440 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * 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 . + */ + +#include "ObjectGuid.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "stonecore.h" + +enum Texts +{ + // Millhouse Manastorm + SAY_MILLHOUSE_EVENT_1 = 0, + SAY_MILLHOUSE_EVENT_2 = 1, +}; + +enum NPCs +{ + NPC_GENERIC_TRIGGER_LAB = 40350, +}; + +enum Spells +{ + // Millhouse Manastorm + SPELL_SHADOW_BOLT = 81439, + SPELL_FROSTBOLT_VOLLEY = 81440, + SPELL_SHADOWFURY = 81441, + SPELL_FEAR = 81442, +// SPELL_MILLHOUSE_SAFE_CHECK = 81213, // unknown purpose + SPELL_CLEAR_ALL_DEBUFFS = 34098, + SPELL_BLUR = 81216, + SPELL_ANCHOR_HERE = 45313, + SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND = 81220, + SPELL_IMPENDING_DOOM = 86838, + SPELL_IMPENDING_DOOM_CHANNEL = 86830, + +// SPELL_PORTAL_VISUAL = 79754, +}; + +enum Events +{ + EVENT_NONE, + + // Millhouse Manastorm + EVENT_FROSTBOLT_VOLLEY, + EVENT_SHADOWFURY, + EVENT_FEAR, + + EVENT_READY_FOR_COMBAT, + EVENT_CAST_IMPENDING_DOOM, + EVENT_INTERRUPT_IMPENDING_DOOM, +}; + +enum Phase +{ + PHASE_NONE, + + PHASE_MILLHOUSE_GROUP_1, + PHASE_MILLHOUSE_GROUP_2, + PHASE_MILLHOUSE_GROUP_3, + PHASE_MILLHOUSE_GROUP_4, + + PHASE_MASK_MILLHOUSE_GROUP_1 = (1 << (PHASE_MILLHOUSE_GROUP_1 - 1)), + PHASE_MASK_MILLHOUSE_GROUP_2 = (1 << (PHASE_MILLHOUSE_GROUP_2 - 1)), + PHASE_MASK_MILLHOUSE_GROUP_3 = (1 << (PHASE_MILLHOUSE_GROUP_3 - 1)), + PHASE_MASK_MILLHOUSE_GROUP_4 = (1 << (PHASE_MILLHOUSE_GROUP_4 - 1)), +}; + +enum MovementPoints +{ + POINT_NONE, + + POINT_MILLHOUSE_GROUP_2, + POINT_MILLHOUSE_GROUP_3, + POINT_MILLHOUSE_GROUP_4, +}; + +// Millhouse trash groups +Position const MillhousePointGroup2 = { 977.3045f, 895.2347f, 306.3298f }; +Position const MillhousePointGroup3 = { 1049.823f, 871.4349f, 295.006f }; +Position const MillhousePointGroup4 = { 1149.04f, 884.431f, 284.9406f }; + +// 43391 - Millhouse Manastorm +class npc_sc_millhouse_manastorm : public CreatureScript +{ + public: + npc_sc_millhouse_manastorm() : CreatureScript("npc_sc_millhouse_manastorm") { } + + struct npc_sc_millhouse_manastormAI : public ScriptedAI + { + npc_sc_millhouse_manastormAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + events.SetPhase(PHASE_MILLHOUSE_GROUP_1); + } + + void ScheduleEvents() + { + events.ScheduleEvent(EVENT_SHADOWFURY, 3000); + events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 5000); + events.ScheduleEvent(EVENT_FEAR, 8000); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + + if (!HealthBelowPct(50) || me->HasAura(SPELL_BLUR)) + return; + + switch (events.GetPhaseMask()) + { + case PHASE_MASK_MILLHOUSE_GROUP_1: + events.Reset(); + events.SetPhase(PHASE_MILLHOUSE_GROUP_2); + me->SetReactState(REACT_PASSIVE); + me->InterruptNonMeleeSpells(true); + DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); + DoCast(me, SPELL_BLUR); + Talk(SAY_MILLHOUSE_EVENT_1); + me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_2, MillhousePointGroup2); + break; + case PHASE_MASK_MILLHOUSE_GROUP_2: + events.Reset(); + events.SetPhase(PHASE_MILLHOUSE_GROUP_3); + me->SetReactState(REACT_PASSIVE); + me->InterruptNonMeleeSpells(true); + DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); + DoCast(me, SPELL_BLUR); + Talk(SAY_MILLHOUSE_EVENT_1); + me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_3, MillhousePointGroup3); + break; + case PHASE_MASK_MILLHOUSE_GROUP_3: + events.Reset(); + events.SetPhase(PHASE_MILLHOUSE_GROUP_4); + me->SetReactState(REACT_PASSIVE); + me->InterruptNonMeleeSpells(true); + DoCast(me, SPELL_CLEAR_ALL_DEBUFFS); + DoCast(me, SPELL_BLUR); + me->GetMotionMaster()->MovePoint(POINT_MILLHOUSE_GROUP_4, MillhousePointGroup4); + break; + default: + break; + } + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE) + return; + + if (pointId < POINT_MILLHOUSE_GROUP_2 || pointId > POINT_MILLHOUSE_GROUP_4) + return; + + me->RemoveAllAuras(); + me->CombatStop(true); + me->DeleteThreatList(); + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + me->SetReactState(REACT_AGGRESSIVE); + + switch (pointId) + { + case POINT_MILLHOUSE_GROUP_2: + if (Creature* worldtrigger = me->FindNearestCreature(NPC_WORLDTRIGGER, 150.0f)) + me->SetFacingToObject(worldtrigger); // o: 5.497359f (sniff data) + me->CastSpell(me, SPELL_ANCHOR_HERE, true); + me->AddAura(SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND, me); + events.ScheduleEvent(EVENT_READY_FOR_COMBAT, 10000); + break; + case POINT_MILLHOUSE_GROUP_3: + me->SetFacingTo(5.931499f); + me->CastSpell(me, SPELL_ANCHOR_HERE, true); + me->AddAura(SPELL_TIGULE_AND_FORORS_SPECIAL_BLEND, me); + events.ScheduleEvent(EVENT_READY_FOR_COMBAT, 10000); + break; + case POINT_MILLHOUSE_GROUP_4: + me->SetFacingTo(3.455752f); + me->CastSpell(me, SPELL_ANCHOR_HERE, true); + Talk(SAY_MILLHOUSE_EVENT_2); + events.ScheduleEvent(EVENT_CAST_IMPENDING_DOOM, 1000); + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + // Only update events if Millhouse is aggressive + if (me->GetReactState() != REACT_AGGRESSIVE) + return; + + events.Update(diff); + + // Impending Doom is exception because it needs to be interrupted. + if (me->HasUnitState(UNIT_STATE_CASTING) && !me->GetCurrentSpell(SPELL_IMPENDING_DOOM)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FROSTBOLT_VOLLEY: + DoCast(SPELL_FROSTBOLT_VOLLEY); + events.ScheduleEvent(EVENT_FROSTBOLT_VOLLEY, 7000); + break; + case EVENT_SHADOWFURY: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_SHADOWFURY); + events.ScheduleEvent(EVENT_SHADOWFURY, 7000); + break; + case EVENT_FEAR: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_FEAR); + events.ScheduleEvent(EVENT_FEAR, 18000); + break; + case EVENT_READY_FOR_COMBAT: + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); + me->SetReactState(REACT_AGGRESSIVE); + ScheduleEvents(); + break; + case EVENT_CAST_IMPENDING_DOOM: + DoCast(SPELL_IMPENDING_DOOM); + DoCast(SPELL_IMPENDING_DOOM_CHANNEL); + events.ScheduleEvent(EVENT_INTERRUPT_IMPENDING_DOOM, urand(15000,20000)); + break; + case EVENT_INTERRUPT_IMPENDING_DOOM: + me->InterruptNonMeleeSpells(true); + me->RemoveAllAuras(); + me->HandleEmoteCommand(EMOTE_ONESHOT_KNOCKDOWN); + events.ScheduleEvent(EVENT_CAST_IMPENDING_DOOM, 3000); + break; + default: + break; + } + } + + DoSpellAttackIfReady(SPELL_SHADOW_BOLT); + } + + private: + InstanceScript* _instance; + EventMap events; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI(creature); + } +}; + +// 81459 - Force of Earth +class spell_force_of_earth : public SpellScriptLoader +{ + public: + spell_force_of_earth() : SpellScriptLoader("spell_force_of_earth") { } + + class spell_force_of_earth_SpellScript : public SpellScript + { + PrepareSpellScript(spell_force_of_earth_SpellScript); + + void DummyEffect(SpellEffIndex /*effIndex*/) + { + GetCaster()->SetDisplayId(26693); // can be moved to SAI part, need sniffs to see what this dummy does (note: npc 43552) + } + + void Register() + { + OnEffectLaunch += SpellEffectFn(spell_force_of_earth_SpellScript::DummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_force_of_earth_SpellScript(); + } +}; + +// 45313 - Anchor Here +class spell_sc_anchor_here : public SpellScriptLoader +{ +public: + spell_sc_anchor_here() : SpellScriptLoader("spell_sc_anchor_here") { } + + class spell_sc_anchor_here_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sc_anchor_here_SpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + if (Creature* creature = GetHitUnit()->ToCreature()) + creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_sc_anchor_here_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_sc_anchor_here_SpellScript(); + } +}; + +// 93167 - Twilight Documents +class spell_sc_twilight_documents : public SpellScriptLoader +{ + public: + spell_sc_twilight_documents() : SpellScriptLoader("spell_sc_twilight_documents") { } + + class spell_sc_twilight_documents_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sc_twilight_documents_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) override + { + if (!sObjectMgr->GetGameObjectTemplate(GAMEOBJECT_TWILIGHT_DOCUMENTS)) + return false; + return true; + } + + void SetTarget(WorldObject*& target) + { + target = GetCaster()->FindNearestCreature(NPC_GENERIC_TRIGGER_LAB, 100.0f); + } + + void SpawnGameObject(SpellEffIndex /*effIndex*/) + { + if (WorldLocation* loc = GetHitDest()) + GetCaster()->SummonGameObject(GAMEOBJECT_TWILIGHT_DOCUMENTS, loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), loc->GetOrientation(), 0, 0, 0, 0, 7200); + } + + void Register() override + { + OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_sc_twilight_documents_SpellScript::SetTarget, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); + OnEffectHit += SpellEffectFn(spell_sc_twilight_documents_SpellScript::SpawnGameObject, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_sc_twilight_documents_SpellScript(); + } +}; + +// 81008 - Quake +class JumpCheck +{ + public: + bool operator()(WorldObject* object) const + { + Player* player = object->ToPlayer(); + return (player && player->HasUnitState(UNIT_STATE_JUMPING)); + } +}; + +class spell_sc_quake : public SpellScriptLoader +{ + public: + spell_sc_quake() : SpellScriptLoader("spell_sc_quake") { } + + class spell_sc_quake_SpellScript : public SpellScript + { + PrepareSpellScript(spell_sc_quake_SpellScript); + + void FilterTargets(std::list& unitList) + { + unitList.remove_if(JumpCheck()); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sc_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_sc_quake_SpellScript(); + } +}; + +class at_sc_corborus_intro : public AreaTriggerScript +{ +public: + at_sc_corborus_intro() : AreaTriggerScript("at_sc_corborus_intro") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + { + if (InstanceScript* instance = player->GetInstanceScript()) + if (Creature* corborus = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_CORBORUS))) + corborus->AI()->DoAction(ACTION_CORBORUS_INTRO); + return true; + } +}; + +class at_sc_slabhide_intro : public AreaTriggerScript +{ +public: + at_sc_slabhide_intro() : AreaTriggerScript("at_sc_slabhide_intro") { } + + bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/) override + { + if (InstanceScript* instance = player->GetInstanceScript()) + if (Creature* slabhide = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_SLABHIDE))) + slabhide->AI()->DoAction(ACTION_SLABHIDE_INTRO); + return true; + } +}; + +void AddSC_stonecore() +{ + new npc_sc_millhouse_manastorm(); + new spell_force_of_earth(); + new spell_sc_anchor_here(); + new spell_sc_twilight_documents(); + new spell_sc_quake(); + new at_sc_corborus_intro(); + new at_sc_slabhide_intro(); +} diff --git a/src/server/scripts/Maelstrom/Stonecore/stonecore.h b/src/server/scripts/Maelstrom/Stonecore/stonecore.h new file mode 100644 index 0000000000000..98a9878e0d3c9 --- /dev/null +++ b/src/server/scripts/Maelstrom/Stonecore/stonecore.h @@ -0,0 +1,72 @@ +/* +* Copyright (C) 2008-2014 TrinityCore +* +* 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 . +*/ + +#ifndef DEF_STONECORE_H +#define DEF_STONECORE_H + +#define SCScriptName "instance_stonecore" +#define DataHeader "SC" + +enum DataTypes +{ + // Encounter States/Boss GUIDs + DATA_CORBORUS, + DATA_SLABHIDE, + DATA_OZRUK, + DATA_HIGH_PRIESTESS_AZIL, + + // Additional Data + DATA_MILLHOUSE_MANASTORM, + DATA_MILLHOUSE_EVENT_FACE, + DATA_MILLHOUSE_EVENT_KNOCKBACK, + DATA_MILLHOUSE_EVENT_DESPAWN, + + DATA_SLABHIDE_INTRO, + DATA_SLABHIDE_ROCK_WALL, +}; + +enum Misc +{ + ACTION_CORBORUS_INTRO, + ACTION_SLABHIDE_INTRO, + + NPC_WORLDTRIGGER = 22515, + NPC_MILLHOUSE_MANASTORM = 43391, + + NPC_CORBORUS = 43438, + NPC_SLABHIDE = 43214, + NPC_OZRUK = 42188, + NPC_HIGH_PRIESTESS_AZIL = 42333, + + // Stonecore Teleporter misc + MAX_STONECORE_TELEPORTERS = 2, + NPC_STONECORE_TELEPORTER = 51396, // Entrance teleporter + NPC_STONECORE_TELEPORTER_2 = 51397, // Slabhide teleporter + SPELL_TELEPORTER_ACTIVE_VISUAL = 95298, + + GAMEOBJECT_TWILIGHT_DOCUMENTS = 207415, + GAMEOBJECT_CORBORUS_ROCKDOOR = 207343, + GAMEOBJECT_SLABHIDE_ROCK_WALL = 204381, + + SPELL_RING_WYRM_KNOCKBACK = 81235, + + // Creature Formation IDs + CREATURE_FORMATION_MILLHOUSE_EVENT_TRASH = 340418, + CREATURE_FORMATION_MILLHOUSE_EVENT_LAST_GROUP = 340492, +}; + +#endif // DEF_STONECORE