fix(Scripts/MoltenCore): rewrite (#8741)

This commit is contained in:
Andrius Peleckas
2021-11-02 11:59:01 +00:00
committed by GitHub
parent 2f25323456
commit 2da923e761
15 changed files with 2441 additions and 1127 deletions
@@ -0,0 +1,311 @@
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1620244782542375889');
-- Added missing aura for Magmadar
UPDATE `creature_template_addon` SET `auras`='19449' WHERE `entry`=11982;
-- 19411 Lava Bomb (used by Magmadar)
DELETE FROM `spell_script_names` WHERE `spell_id` IN (19411, 20474) AND `ScriptName`='spell_magmadar_lava_bomb';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(19411, 'spell_magmadar_lava_bomb'),
(20474, 'spell_magmadar_lava_bomb');
-- Renamed Core Hound script
update `creature_template` SET `ScriptName`='npc_mc_core_hound' WHERE `entry`=11671;
-- Timers update for NPC "Flamewaker Protector"
UPDATE `smart_scripts` SET `event_param1`=5000, `event_param2`=5000, `event_param3`=6500, `event_param4`=6500 WHERE `entryorguid`=12119 AND `source_type`=0 AND `id`=0 AND `link`=0;
UPDATE `smart_scripts` SET `event_param1`=5000, `event_param2`=10000, `event_param3`=7000, `event_param4`=7000 WHERE `entryorguid`=12119 AND `source_type`=0 AND `id`=1 AND `link`=0;
-- Timers update for NPC "Flamewaker"
UPDATE `smart_scripts` SET `event_param1`=3000, `event_param2`=6000, `event_param3`=10000, `event_param4`=13000 WHERE `entryorguid`=11661 AND `source_type`=0 AND `id`=1 AND `link`=0;
UPDATE `smart_scripts` SET `event_param1`=3000, `event_param3`=4000, `event_param4`=6000 WHERE `entryorguid`=11661 AND `source_type`=0 AND `id`=0 AND `link`=0;
UPDATE `smart_scripts` SET `event_param1`=4000, `event_param2`=9000, `event_param3`=5000, `event_param4`=8000 WHERE `entryorguid`=11661 AND `source_type`=0 AND `id`=2 AND `link`=0;
-- Garr texts
DELETE FROM `creature_text` WHERE `CreatureID`=12057 AND `GroupID`=0 AND `ID`=0;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(12057, 0, 0, '%s forces one of his Firesworn minions to erupt!', 41, 0, 100, 0, 0, 0, 8254, 0, 'Garr EMOTE_MASS_ERRUPTION');
-- Garr
-- Firesworn
-- add them immolate and thrash auras
UPDATE `creature_template_addon` SET `auras`='8876 15733' WHERE `entry`=12099;
-- Conditions for spell "21086 Encouragement"
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=21086;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 3, 21086, 0, 0, 31, 0, 3, 11663, 0, 0, 0, 0, '', 'Encouragement Effects 1 and Effect 2 - can target Flamewaker Healer'),
(13, 3, 21086, 0, 1, 31, 0, 3, 11664, 0, 0, 0, 0, '', 'Encouragement Effects 1 and Effect 2 - can target Flamewaker Elite');
-- Conditions for spell "21090 Champion"
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=21090;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 7, 21090, 0, 0, 31, 0, 3, 11663, 0, 0, 0, 0, '', 'Champion - can target Flamewaker Healer'),
(13, 7, 21090, 0, 1, 31, 0, 3, 11664, 0, 0, 0, 0, '', 'Champion - can target Flamewaker Elite');
-- Conditions for spell "21087 Immunity"
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=21087;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 3, 21087, 0, 0, 31, 0, 3, 11663, 0, 0, 0, 0, '', 'Champion - can target Flamewaker Healer');
-- Majordomu summon
DELETE FROM `creature_summon_groups` WHERE `summonerId`=12018;
INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`) VALUES
(12018, 0, 1, 11663, 761.652, -1164.3, -119.533, 3.3919, 8, 10000),
(12018, 0, 1, 11663, 747.323, -1149.24, -120.06, 3.6629, 8, 10000),
(12018, 0, 1, 11663, 766.734, -1183.16, -119.292, 2.9889, 8, 10000),
(12018, 0, 1, 11663, 757.364, -1198.31, -118.652, 2.3095, 8, 10000),
(12018, 0, 1, 11664, 752.349, -1159.19, -119.261, 3.6032, 8, 10000),
(12018, 0, 1, 11664, 738.015, -1152.22, -119.512, 4.0792, 8, 10000),
(12018, 0, 1, 11664, 757.246, -1189.79, -118.633, 2.5333, 8, 10000),
(12018, 0, 1, 11664, 745.916, -1199.35, -118.119, 1.8932, 8, 10000);
-- Molten Giant
UPDATE `creature_template_addon` SET `auras`='18943' WHERE `entry`=11658;
update `creature_addon` set `auras`='18943' where `guid` in (select `guid` from `creature` where `id`=11658);
UPDATE `smart_scripts` SET `event_param1`='6000', `event_param2`='10000', `event_param3`='7000', `event_param4`='10000' WHERE `entryorguid`=11658 AND `source_type`=0 AND `id`=0 AND `link`=0;
UPDATE `smart_scripts` SET `event_param1`='6000', `event_param2`='11000', `event_param3`='12000', `event_param4`='16000' WHERE `entryorguid`=11658 AND `source_type`=0 AND `id`=1 AND `link`=0;
-- Firelord
UPDATE `creature_template_addon` SET `auras`='19396' WHERE `entry`=11668;
update creature_addon set `auras`='19396' where `guid` in (select `guid` from `creature` where `id`=11668);
UPDATE `smart_scripts` SET `event_param1`='4000', `event_param3`='2000', `event_param4`='4000' WHERE `entryorguid`=11668 AND `source_type`=0 AND `id`=0 AND `link`=0;
UPDATE `smart_scripts` SET `event_param2`='15000', `event_param3`='15000', `event_param4`='15000' WHERE `entryorguid`=11668 AND `source_type`=0 AND `id`=1 AND `link`=0;
-- Ancient Core Hound
UPDATE `creature_template_addon` SET `auras`='18950' WHERE `entry`=11658;
update creature_addon set `auras`='18950' where `guid` in (select `guid` from `creature` where `id`=11658);
-- Fire Imp
update `creature_template` set `AIName`='SmartAI' where `entry`=11669;
DELETE FROM `smart_scripts` WHERE `entryorguid`=11669 AND `source_type`=0 AND `id`=0 AND `link`=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`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(11669, 0, 0, 0, 0, 0, 100, 0, 5000, 15000, 4000, 7000, 0, 11, 20602, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Flame Imp - IC - Cast Fire Nova');
-- spell "Play Dead" aura script (used by core hounds)
DELETE FROM `spell_script_names` WHERE `spell_id`=19822 AND `ScriptName`='spell_mc_play_dead';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(19822, 'spell_mc_play_dead');
-- Magmadar linked respawn data
-- set @magmadarGUID := (SELECT `guid` from `creature` WHERE `id` = 11982 AND `map`=409);
SET @magmadarGUID := 56683;
DELETE FROM `linked_respawn` WHERE `guid` IN (SELECT `guid` from `creature` WHERE `id` IN (11671, 11673) AND `map`=409);
INSERT INTO `linked_respawn` (`guid`, `linkedGuid`, `linkType`)
SELECT `guid`, CONCAT(@magmadarGUID), CONCAT(0) from `creature` WHERE `id` IN (11671, 11673) AND `map`=409;
-- Added "18950 Invisibility and Stealth Detection" to Ancient Core Hounds
UPDATE `creature_template_addon` SET `auras`='18950' WHERE `entry`=11673;
-- 19695 Inferno (used by Geddon)
DELETE FROM `spell_script_names` WHERE `spell_id`=19695 AND `ScriptName`='spell_geddon_inferno';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(19695, 'spell_geddon_inferno');
-- Added "Thrash" aura for Core Rager
UPDATE `creature_template_addon` SET `auras`='12787 20553' WHERE `entry`=11672;
-- Added missing auras for Golemagg
UPDATE `creature_template_addon` SET `auras`='13879 18943 20556' WHERE `entry`=11988;
-- spell "Attract Rager"(20544) condition
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=20544;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 7, 20544, 0, 0, 31, 0, 3, 11672, 0, 0, 0, 0, '', 'Spell Attract Rager should target only Core Rager');
-- Core Hound formations
-- GROUP 1
-- 56638, 56635, 56637, 56634, 56636
set @leader := 56638;
DELETE FROM `creature_formations` WHERE `memberGUID` IN (@leader, 56635, 56637, 56634, 56636);
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (@leader, 56635, 56637, 56634, 56636);
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(@leader, @leader, 0, 0, 2, 0, 0),
(@leader, 56635, 0, 0, 3, 0, 0),
(@leader, 56637, 0, 0, 3, 0, 0),
(@leader, 56634, 0, 0, 3, 0, 0),
(@leader, 56636, 0, 0, 3, 0, 0);
-- GROUP 2
-- 56629, 56630, 56632, 56633, 56631
set @leader := 56629;
DELETE FROM `creature_formations` WHERE `memberGUID` IN (@leader, 56630, 56632, 56633, 56631);
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (@leader, 56630, 56632, 56633, 56631);
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(@leader, @leader, 0, 0, 2, 0, 0),
(@leader, 56630, 0, 0, 3, 0, 0),
(@leader, 56632, 0, 0, 3, 0, 0),
(@leader, 56633, 0, 0, 3, 0, 0),
(@leader, 56631, 0, 0, 3, 0, 0);
-- GROUP 3
-- 56639, 56641, 56642, 56643, 56640
set @leader := 56639;
DELETE FROM `creature_formations` WHERE `memberGUID` IN (@leader, 56641, 56642, 56643, 56640);
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (@leader, 56641, 56642, 56643, 56640);
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(@leader, @leader, 0, 0, 2, 0, 0),
(@leader, 56641, 0, 0, 3, 0, 0),
(@leader, 56642, 0, 0, 3, 0, 0),
(@leader, 56643, 0, 0, 3, 0, 0),
(@leader, 56640, 0, 0, 3, 0, 0);
-- GROUP 4
-- 56651, 56650, 56652, 56653, 56654
set @leader := 56651;
DELETE FROM `creature_formations` WHERE `memberGUID` IN (@leader, 56650, 56652, 56653, 56654);
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (@leader, 56650, 56652, 56653, 56654);
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(@leader, @leader, 0, 0, 2, 0, 0),
(@leader, 56650, 0, 0, 3, 0, 0),
(@leader, 56652, 0, 0, 3, 0, 0),
(@leader, 56653, 0, 0, 3, 0, 0),
(@leader, 56654, 0, 0, 3, 0, 0);
-- GROUP 5
-- 56648, 56644, 56646, 56649, 56647
set @leader := 56648;
DELETE FROM `creature_formations` WHERE `memberGUID` IN (@leader, 56644, 56646, 56649, 56647);
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (@leader, 56644, 56646, 56649, 56647);
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(@leader, @leader, 0, 0, 2, 0, 0),
(@leader, 56644, 0, 0, 3, 0, 0),
(@leader, 56646, 0, 0, 3, 0, 0),
(@leader, 56649, 0, 0, 3, 0, 0),
(@leader, 56647, 0, 0, 3, 0, 0);
-- Lucifron Flamewalkers
-- These minions has formation data and they always follows Lucifron
/* ERROR MSG:
WaypointMovementGenerator::LoadPath: creature Flamewaker Protector (GUID Full: 0xf130002f5700006c Type: Creature Entry: 12119 Low: 108) doesn't have waypoint path id: 566060
WaypointMovementGenerator::LoadPath: creature Flamewaker Protector (GUID Full: 0xf130002f5700006d Type: Creature Entry: 12119 Low: 109) doesn't have waypoint path id: 566070
*/
UPDATE `creature_addon` SET `path_id`='0' WHERE `guid` IN (56606, 56607);
update `creature` set `MovementType`=0 where `guid` IN (56606, 56607);
-- Garr's Firesworn
UPDATE `creature_template` SET `ScriptName`='npc_garr_firesworn' WHERE `entry`=12099;
-- Garr's "Separation Anexiety"(23487, server side)
UPDATE `spell_dbc` SET `EffectAura_1`=226, `EffectAuraPeriod_1`=1000 WHERE `Id`=23487;
DELETE FROM `spell_script_names` WHERE `spell_id`=23487 AND `ScriptName`='spell_garr_separation_nexiety';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(23487, 'spell_garr_separation_nexiety');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=23487;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 23487, 0, 0, 31, 0, 3, 12099, 0, 0, 0, 0, '', 'Separation Anexiety (effect 0) - should target only Firesworn');
-- Removed script for "Son of Flame"
update `creature_template` set `ScriptName`='' where `entry`=12143;
-- Garr's linked respawn data
-- set @garrGUID := (SELECT `guid` from `creature` WHERE `id` = 12101 AND `map`=409);
SET @garrGUID := 56683;
DELETE FROM `linked_respawn` WHERE `guid` IN (SELECT `guid` from `creature` WHERE `id` = 12101 AND `map`=409);
INSERT INTO `linked_respawn` (`guid`, `linkedGuid`, `linkType`)
SELECT `guid`, CONCAT(@magmadarGUID), CONCAT(0) from `creature` WHERE `id` = 12101 AND `map`=409;
-- "19515 Frenzy (SERVERSIDE)" used by Garr's Firesworn
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=19515;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 19515, 0, 0, 31, 0, 3, 12057, 0, 0, 0, 0, '', 'Frenzy (SERVERSIDE) - should target only Garr');
-- Allow casting while dead
update `spell_dbc` set `attributes`=`attributes` | 0x00800000 where `id` = 19515;
DELETE FROM `spell_script_names` WHERE `spell_id`=19515 AND `ScriptName`='spell_garr_frenzy';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(19515, 'spell_garr_frenzy');
-- 20482 Firesworn Eruption Trigger (SERVERSIDE)
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=20482;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 3, 20482, 0, 0, 31, 0, 3, 12099, 0, 0, 0, 0, '', 'spell "Firesworn Eruption Trigger" should target only Firesworn');
-- 20482 Firesworn Eruption Trigger (SERVERSIDE)
DELETE FROM `spell_linked_spell` WHERE `spell_trigger`=20482 AND `spell_effect`=20483 AND `type`=1;
INSERT INTO `spell_linked_spell` (`spell_trigger`, `spell_effect`, `type`, `comment`) VALUES
(20482, 20483, 1, 'Firesworn Eruption Trigger - On Hit - Trigger Massive Eruption');
-- Golemagg formation
set @leader := 56684;
DELETE FROM `creature_formations` WHERE `memberGUID` IN (@leader, 56685, 56699);
DELETE FROM `creature_formations` WHERE `leaderGUID` IN (@leader, 56685, 56699);
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
(@leader, @leader, 0, 0, 2, 0, 0),
(@leader, 56685, 0, 0, 3, 0, 0),
(@leader, 56699, 0, 0, 3, 0, 0);
-- Condition for "20553 Golemagg's Trust"
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=20553;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 7, 20553, 0, 0, 31, 0, 3, 11672, 0, 0, 0, 0, '', 'Golemagg\'s Trust spell effects should target only Core Ragers');
-- Condition for "20619 Magic Reflection" (Majordomu)
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=20619;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 20619, 0, 0, 31, 0, 3, 0, 0, 0, 0, 0, '', 'Magic Reflection - Should target only creatures'),
(13, 1, 20619, 0, 0, 34, 1, 0, 1, 0, 0, 0, 0, '', 'Magic Reflection - Should target only friendly creatures');
-- Condition for "21075 Damage Shield" (Majordomou)
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=21075;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 21075, 0, 0, 31, 0, 3, 0, 0, 0, 0, 0, '', 'Damage Shield - Should target only creatures'),
(13, 1, 21075, 0, 0, 34, 1, 0, 1, 0, 0, 0, 0, '', 'Damage Shield - Should target only friendly creatures');
-- Teleport position for spell "20618 Teleport" (Majordomu)
DELETE FROM `spell_target_position` WHERE `id`=20618 AND `EffectIndex`=0;
INSERT INTO `spell_target_position` (`id`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`) VALUES
(20618, 0, 409, 736.516, -1176.35, -119.006, 0);
-- Teleport position for spell "20534 Teleport" (Majordomu)
DELETE FROM `spell_target_position` WHERE `id`=20534 AND `EffectIndex`=0;
INSERT INTO `spell_target_position` (`id`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`) VALUES
(20534, 0, 409, 736.516, -1176.35, -119.006, 0);
-- 20538 Hate to Zero (SERVERSIDE, majordomu)
DELETE FROM `spell_script_names` WHERE `spell_id`=20538 AND `ScriptName`='spell_hate_to_zero';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(20538, 'spell_hate_to_zero');
-- Majordomo texts
UPDATE `creature_template` SET `gossip_menu_id`='4093' WHERE `entry`=12018;
-- Majordomo texts
DELETE FROM `creature_text` WHERE `CreatureID`=12018;
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(12018, 0, 0, 'Reckless mortals! None may challenge the Sons of the Living flame!', 14, 0, 100, 0, 0, 8035, 7612, 0, 'majordomo SAY_AGGRO'),
(12018, 1, 0, 'The runes of warding have been destroyed! Hunt down the infidels, my brethren!', 14, 0, 100, 0, 0, 8039, 7566, 3, 'majordomo SAY_SPAWN'),
(12018, 2, 0, 'Ashes to ashes!', 14, 0, 100, 0, 0, 8037, 9425, 0, 'majordomo SAY_SLAY'),
(12018, 2, 1, 'Burn mortals! Burn for this transgression!', 14, 0, 100, 0, 0, 8036, 0, 0, 'majordomo SAY_SPECIAL'),
(12018, 3, 0, 'Impossible! Stay your attack, mortals... I submit! I submit!', 14, 0, 100, 0, 0, 8038, 7561, 0, 'majordomo SAY_DEFEAT'),
(12018, 4, 0, 'Behold Ragnaros - the Firelord! He who was ancient when this world was young! Bow before him, mortals! Bow before your ending!', 14, 0, 100, 0, 0, 8040, 7657, 0, 'majordomo SAY_SUMMON_MAJ'),
(12018, 5, 0, 'These mortal infidels, my lord! They have invaded your sanctum and seek to steal your secrets!', 14, 0, 100, 0, 0, 8041, 7661, 0, 'majordomo SAY_ARRIVAL2_MAJ'),
(12018, 6, 0, 'You think you\'ve won already? Perhaps you\'ll need another lesson in pain!', 14, 0, 100, 0, 0, 0, 8545, 0, 'majordomo SAY_LAST_ADD'),
(12018, 7, 0, 'Brashly, you have come to wrest the secrets of the Living Flame! You will soon regret the recklessness of your quest.', 14, 0, 100, 0, 0, 0, 7567, 0, 'majordomo SAY_DEFEAT_2'),
(12018, 8, 0, 'I go now to summon the lord whose house this is. Should you seek an audience with him, your paltry lives will surely be forfeit! Nevertheless, seek out his lair, if you dare!', 14, 0, 100, 0, 0, 0, 7568, 0, 'majordomo SAY_DEFEAT_3'),
(12018, 9, 0, 'Very well, $n', 12, 0, 100, 0, 0, 0, 7649, 0, 'majordomo SAY_RAG_SUM_1'),
(12018, 10, 0, 'Impudent whelps! You\'\'ve rushed headlong to your own deaths! See now, the master stirs!', 14, 0, 100, 0, 0, 0, 7655, 0, 'majordomo SAY_RAG_SUM_2');
-- Majordomu "21094 Separation Anxiety (SERVERSIDE)"
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=21094;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 21094, 0, 0, 31, 0, 3, 11663, 0, 0, 0, 0, '', 'Separation Anxiety should target Flamewaker Healer'),
(13, 1, 21094, 0, 1, 31, 0, 3, 11664, 0, 0, 0, 0, '', 'Separation Anxiety should target Flamewaker Elite');
UPDATE `spell_dbc` SET `EffectAura_1`=226, `EffectAuraPeriod_1`=1000 WHERE `Id`=21094;
DELETE FROM `spell_script_names` WHERE `spell_id`=21094 AND `ScriptName`='spell_majordomo_separation_nexiety';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(21094, 'spell_majordomo_separation_nexiety');
-- Ragnaros texts
UPDATE `creature_text` SET `Emote`='15' WHERE `CreatureID`=11502 AND `GroupID`=1 AND `ID`=0;
delete from `gameobject` where `guid`=2135424 and `id`=178107;
INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES
(2135424, 178107, 409, 1, 1, 838.951, -830.383, -230.206, 0.837757, 0, 0, 0, 1, -604800, 255, 1);
delete from `gameobject` where `guid`=2135423 and `id`=178108;
INSERT INTO `gameobject` (`guid`, `id`, `map`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES
(2135423, 178108, 409, 1, 1, 839.279, -831.058, -230.202, -1.37881, 0, 0, 0, 1, -604800, 255, 1);
-- 19774 Summon Ragnaros
DELETE FROM `spell_script_names` WHERE `spell_id`=19774 AND `ScriptName`='spell_summon_ragnaros';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(19774, 'spell_summon_ragnaros');
@@ -15,36 +15,31 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Baron_Geddon
SD%Complete: 100
SDComment:
SDCategory: Molten Core
EndScriptData */
#include "molten_core.h"
#include "ObjectMgr.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "molten_core.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
enum Emotes enum Emotes
{ {
EMOTE_SERVICE = 0 EMOTE_SERVICE = 0
}; };
enum Spells enum Spells
{ {
SPELL_INFERNO = 19695, SPELL_INFERNO = 19695,
SPELL_IGNITE_MANA = 19659, SPELL_INFERNO_DUMMY_EFFECT = 19698, // Server side spell which inflicts damage
SPELL_LIVING_BOMB = 20475, SPELL_IGNITE_MANA = 19659,
SPELL_ARMAGEDDON = 20479, SPELL_LIVING_BOMB = 20475,
SPELL_ARMAGEDDON = 20478,
}; };
enum Events enum Events
{ {
EVENT_INFERNO = 1, EVENT_INFERNO = 1,
EVENT_IGNITE_MANA = 2, EVENT_IGNITE_MANA,
EVENT_LIVING_BOMB = 3, EVENT_LIVING_BOMB,
}; };
class boss_baron_geddon : public CreatureScript class boss_baron_geddon : public CreatureScript
@@ -54,62 +49,75 @@ public:
struct boss_baron_geddonAI : public BossAI struct boss_baron_geddonAI : public BossAI
{ {
boss_baron_geddonAI(Creature* creature) : BossAI(creature, BOSS_BARON_GEDDON) boss_baron_geddonAI(Creature* creature) : BossAI(creature, DATA_GEDDON),
armageddonCasted(false)
{ {
} }
void EnterCombat(Unit* victim) override void Reset() override
{ {
BossAI::EnterCombat(victim); _Reset();
events.ScheduleEvent(EVENT_INFERNO, 45000); armageddonCasted = false;
events.ScheduleEvent(EVENT_IGNITE_MANA, 30000);
events.ScheduleEvent(EVENT_LIVING_BOMB, 35000);
} }
void UpdateAI(uint32 diff) override void EnterCombat(Unit* /*attacker*/) override
{ {
if (!UpdateVictim()) _EnterCombat();
return; events.ScheduleEvent(EVENT_INFERNO, urand(13000, 15000));
events.ScheduleEvent(EVENT_IGNITE_MANA, urand(7000, 19000));
events.ScheduleEvent(EVENT_LIVING_BOMB, urand(11000, 16000));
}
events.Update(diff); void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*dmgType*/, SpellSchoolMask /*school*/) override
{
// If we are <2% hp cast Armageddon // If boss is below 2% hp - cast Armageddon
if (!HealthAbovePct(2)) if (!armageddonCasted && damage < me->GetHealth() && me->HealthBelowPctDamaged(2, damage))
{ {
me->InterruptNonMeleeSpells(true); me->InterruptNonMeleeSpells(true);
DoCast(me, SPELL_ARMAGEDDON); if (me->CastSpell(me, SPELL_ARMAGEDDON) == SPELL_CAST_OK)
Talk(EMOTE_SERVICE);
return;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{ {
case EVENT_INFERNO: Talk(EMOTE_SERVICE);
DoCast(me, SPELL_INFERNO); }
events.ScheduleEvent(EVENT_INFERNO, 45000);
break; armageddonCasted = true;
case EVENT_IGNITE_MANA: }
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_IGNITE_MANA)) }
DoCast(target, SPELL_IGNITE_MANA);
events.ScheduleEvent(EVENT_IGNITE_MANA, 30000); void ExecuteEvent(uint32 eventId) override
break; {
case EVENT_LIVING_BOMB: switch (eventId)
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) {
DoCast(target, SPELL_LIVING_BOMB); case EVENT_INFERNO:
events.ScheduleEvent(EVENT_LIVING_BOMB, 35000); {
break; DoCastSelf(SPELL_INFERNO);
default: events.RepeatEvent(urand(21000, 26000));
break; break;
}
case EVENT_IGNITE_MANA:
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_IGNITE_MANA))
{
DoCast(target, SPELL_IGNITE_MANA);
}
events.RepeatEvent(urand(27000, 32000));
break;
}
case EVENT_LIVING_BOMB:
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{
DoCast(target, SPELL_LIVING_BOMB);
}
events.RepeatEvent(urand(11000, 16000));
break;
} }
} }
DoMeleeAttackIfReady();
} }
private:
bool armageddonCasted;
}; };
CreatureAI* GetAI(Creature* creature) const override CreatureAI* GetAI(Creature* creature) const override
@@ -118,7 +126,68 @@ public:
} }
}; };
// 19695 Inferno
class spell_geddon_inferno : public SpellScriptLoader
{
public:
spell_geddon_inferno() : SpellScriptLoader("spell_geddon_inferno") { }
class spell_geddon_inferno_AuraScript : public AuraScript
{
PrepareAuraScript(spell_geddon_inferno_AuraScript);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_INFERNO_DUMMY_EFFECT });
}
void PeriodicTick(AuraEffect const* aurEff)
{
PreventDefaultAction();
if (Unit* caster = GetUnitOwner())
{
//The pulses come about 1 second apart and last for 10 seconds. Damage starts at 500 damage per pulse and increases by 500 every other pulse (500, 500, 1000, 1000, 1500, etc.). (Source: Wowwiki)
int32 multiplier = 1;
switch (aurEff->GetTickNumber())
{
case 2:
case 3:
multiplier = 2;
break;
case 4:
case 5:
multiplier = 3;
break;
case 6:
case 7:
multiplier = 4;
break;
case 8:
multiplier = 5;
break;
}
caster->CastCustomSpell(SPELL_INFERNO_DUMMY_EFFECT, SPELLVALUE_BASE_POINT0, 500 * multiplier, caster, TRIGGERED_NONE, nullptr, aurEff);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_geddon_inferno_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_geddon_inferno_AuraScript();
}
};
void AddSC_boss_baron_geddon() void AddSC_boss_baron_geddon()
{ {
new boss_baron_geddon(); new boss_baron_geddon();
// Spells
new spell_geddon_inferno();
} }
@@ -15,83 +15,124 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Garr
SD%Complete: 50
SDComment: Adds NYI
SDCategory: Molten Core
EndScriptData */
#include "molten_core.h"
#include "ObjectMgr.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "Containers.h"
#include "ObjectAccessor.h"
#include "ScriptedCreature.h"
#include "SpellAuras.h"
#include "SpellInfo.h"
#include "SpellScript.h"
#include "molten_core.h"
enum Texts
{
EMOTE_MASS_ERRUPTION = 0,
};
enum Spells enum Spells
{ {
// Garr // Garr
SPELL_ANTIMAGIC_PULSE = 19492, SPELL_ANTIMAGIC_PULSE = 19492, // Dispels magic on nearby enemies, removing 1 beneficial spell
SPELL_MAGMA_SHACKLES = 19496, SPELL_MAGMA_SHACKLES = 19496, // Reduces the movement speed of nearby enemies by 60%
SPELL_ENRAGE = 19516, SPELL_SEPARATION_ANXIETY = 23487, // Aura cast on himself by Garr, if adds move out of range, they will cast spell 23492 on themselves (server side)
SPELL_FRENZY = 19516, // Increases the caster's attack speed by 9 + scale. Stacks up to 10 times
// Adds // Fireworn
SPELL_ERUPTION = 19497, SPELL_SEPARATION_ANXIETY_MINION = 23492, // Increases damage done by 300% and applied banish immunity
SPELL_IMMOLATE = 20294, SPELL_ERUPTION = 19497, // Deals fire aoe damage and knockbacks nearby enemies
SPELL_MASSIVE_ERUPTION = 20483, // Deals fire aoe damage, knockbacks nearby enemies and kills caster
SPELL_ERUPTION_TRIGGER = 20482, // Removes banish auras and applied immunity to banish (server side)
SPELL_ENRAGE_TRIGGER = 19515, // Server side. Triggers 19516 on hit
}; };
enum Events enum Events
{ {
EVENT_ANTIMAGIC_PULSE = 1, EVENT_ANTIMAGIC_PULSE = 1,
EVENT_MAGMA_SHACKLES = 2, EVENT_MAGMA_SHACKLES,
}; };
class boss_garr : public CreatureScript class boss_garr : public CreatureScript
{ {
public: public:
boss_garr() : CreatureScript("boss_garr") { } boss_garr() : CreatureScript("boss_garr") {}
struct boss_garrAI : public BossAI struct boss_garrAI : public BossAI
{ {
boss_garrAI(Creature* creature) : BossAI(creature, BOSS_GARR) boss_garrAI(Creature* creature) : BossAI(creature, DATA_GARR),
massEruptionTimer(600000) // 10 mins
{ {
} }
void EnterCombat(Unit* victim) override void Reset() override
{ {
BossAI::EnterCombat(victim); _Reset();
massEruptionTimer = 600000;
}
void EnterCombat(Unit* /*attacker*/) override
{
_EnterCombat();
DoCastSelf(SPELL_SEPARATION_ANXIETY, true);
events.ScheduleEvent(EVENT_ANTIMAGIC_PULSE, 15000); events.ScheduleEvent(EVENT_ANTIMAGIC_PULSE, 15000);
events.ScheduleEvent(EVENT_MAGMA_SHACKLES, 10000); events.ScheduleEvent(EVENT_MAGMA_SHACKLES, 10000);
massEruptionTimer = 600000; // 10 mins
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
if (!UpdateVictim()) if (!UpdateVictim())
{
return; return;
}
// This should always process
if (massEruptionTimer <= diff)
{
Talk(EMOTE_MASS_ERRUPTION, me);
DoCastAOE(SPELL_ERUPTION_TRIGGER, true);
massEruptionTimer = 20000;
}
else
{
massEruptionTimer -= diff;
}
events.Update(diff); events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING)) if (me->HasUnitState(UNIT_STATE_CASTING))
{
return; return;
}
while (uint32 eventId = events.ExecuteEvent()) while (uint32 const eventId = events.ExecuteEvent())
{ {
switch (eventId) switch (eventId)
{ {
case EVENT_ANTIMAGIC_PULSE: case EVENT_ANTIMAGIC_PULSE:
DoCast(me, SPELL_ANTIMAGIC_PULSE); {
events.ScheduleEvent(EVENT_ANTIMAGIC_PULSE, 20000); DoCastSelf(SPELL_ANTIMAGIC_PULSE);
events.RepeatEvent(20000);
break; break;
}
case EVENT_MAGMA_SHACKLES: case EVENT_MAGMA_SHACKLES:
DoCast(me, SPELL_MAGMA_SHACKLES); {
events.ScheduleEvent(EVENT_MAGMA_SHACKLES, 15000); DoCastSelf(SPELL_MAGMA_SHACKLES);
break; events.RepeatEvent(15000);
default:
break; break;
}
}
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
} }
} }
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
private:
uint32 massEruptionTimer;
}; };
CreatureAI* GetAI(Creature* creature) const override CreatureAI* GetAI(Creature* creature) const override
@@ -100,60 +141,115 @@ public:
} }
}; };
class npc_firesworn : public CreatureScript class npc_garr_firesworn : public CreatureScript
{ {
public: public:
npc_firesworn() : CreatureScript("npc_firesworn") { } npc_garr_firesworn() : CreatureScript("npc_garr_firesworn") {}
struct npc_fireswornAI : public ScriptedAI struct npc_garr_fireswornAI : public ScriptedAI
{ {
npc_fireswornAI(Creature* creature) : ScriptedAI(creature) { } npc_garr_fireswornAI(Creature* creature) : ScriptedAI(creature) {}
uint32 immolateTimer; void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/ ) override
void Reset() override
{ {
immolateTimer = 4000; //These times are probably wrong if (damage >= me->GetHealth())
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
uint32 const health10pct = me->CountPctFromMaxHealth(10);
uint32 health = me->GetHealth();
if (int32(health) - int32(damage) < int32(health10pct))
{ {
damage = 0; // Prevent double damage because Firesworn can kill himself with Massive Erruption
DoCastVictim(SPELL_ERUPTION); if (me != attacker)
me->DespawnOrUnsummon(); {
DoCastSelf(SPELL_ERUPTION, true);
}
DoCastAOE(SPELL_ENRAGE_TRIGGER);
} }
} }
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
if (immolateTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_IMMOLATE);
immolateTimer = urand(5000, 10000);
}
else
immolateTimer -= diff;
DoMeleeAttackIfReady();
}
}; };
CreatureAI* GetAI(Creature* creature) const override CreatureAI* GetAI(Creature* creature) const override
{ {
return GetMoltenCoreAI<npc_fireswornAI>(creature); return GetMoltenCoreAI<npc_garr_fireswornAI>(creature);
}
};
// 23487 Separation Anxiety (server side)
class spell_garr_separation_nexiety : public SpellScriptLoader
{
public:
spell_garr_separation_nexiety() : SpellScriptLoader("spell_garr_separation_nexiety") {}
class spell_garr_separation_nexiety_AuraScript : public AuraScript
{
PrepareAuraScript(spell_garr_separation_nexiety_AuraScript);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_SEPARATION_ANXIETY_MINION });
}
void HandlePeriodic(AuraEffect const* aurEff)
{
Unit const* caster = GetCaster();
Unit* target = GetTarget();
if (caster && target && target->GetDistance(caster) > 40.0f && !target->HasAura(SPELL_SEPARATION_ANXIETY_MINION))
{
target->CastSpell(target, SPELL_SEPARATION_ANXIETY_MINION, true, nullptr, aurEff);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_garr_separation_nexiety_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
// Should return a fully valid AuraScript pointer.
AuraScript* GetAuraScript() const override
{
return new spell_garr_separation_nexiety_AuraScript();
}
};
//19515 Frenzy (SERVERSIDE)
class spell_garr_frenzy : public SpellScriptLoader
{
public:
spell_garr_frenzy() : SpellScriptLoader("spell_garr_frenzy") {}
class spell_garr_frenzy_SpellScript : public SpellScript
{
PrepareSpellScript(spell_garr_frenzy_SpellScript);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_FRENZY });
}
void HandleHit(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
{
target->CastSpell(target, SPELL_FRENZY);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_garr_frenzy_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_garr_frenzy_SpellScript();
} }
}; };
void AddSC_boss_garr() void AddSC_boss_garr()
{ {
new boss_garr(); new boss_garr();
new npc_firesworn(); new npc_garr_firesworn();
// Spells
new spell_garr_separation_nexiety();
new spell_garr_frenzy();
} }
@@ -15,13 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Gehennas
SD%Complete: 90
SDComment: Adds MC NYI
SDCategory: Molten Core
EndScriptData */
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h" #include "ScriptedCreature.h"
#include "molten_core.h" #include "molten_core.h"
@@ -48,9 +41,7 @@ public:
struct boss_gehennasAI : public BossAI struct boss_gehennasAI : public BossAI
{ {
boss_gehennasAI(Creature* creature) : BossAI(creature, BOSS_GEHENNAS) boss_gehennasAI(Creature* creature) : BossAI(creature, DATA_GEHENNAS) {}
{
}
void EnterCombat(Unit* /*attacker*/) override void EnterCombat(Unit* /*attacker*/) override
{ {
@@ -60,69 +51,47 @@ public:
events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 5000)); events.ScheduleEvent(EVENT_SHADOW_BOLT, urand(3000, 5000));
} }
void UpdateAI(uint32 diff) override void ExecuteEvent(uint32 eventId) override
{ {
if (!UpdateVictim()) switch (eventId)
{ {
return; case EVENT_GEHENNAS_CURSE:
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 const eventId = events.ExecuteEvent())
{
switch (eventId)
{ {
case EVENT_GEHENNAS_CURSE: DoCastVictim(SPELL_GEHENNAS_CURSE);
events.RepeatEvent(urand(25000, 30000));
break;
}
case EVENT_RAIN_OF_FIRE:
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{ {
DoCastVictim(SPELL_GEHENNAS_CURSE); DoCast(target, SPELL_RAIN_OF_FIRE, true);
events.RepeatEvent(urand(25000, 30000));
break;
} }
case EVENT_RAIN_OF_FIRE: events.RepeatEvent(6000);
break;
}
case EVENT_SHADOW_BOLT:
{
if (urand(0, 1))
{ {
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
{ {
DoCast(target, SPELL_RAIN_OF_FIRE); DoCast(target, SPELL_SHADOW_BOLT_RANDOM);
}
events.RepeatEvent(6000);
break;
}
case EVENT_SHADOW_BOLT:
{
if (urand(0, 1))
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
{
DoCast(target, SPELL_SHADOW_BOLT_RANDOM);
}
else
{
DoCastVictim(SPELL_SHADOW_BOLT_VICTIM);
}
} }
else else
{ {
DoCastVictim(SPELL_SHADOW_BOLT_VICTIM); DoCastVictim(SPELL_SHADOW_BOLT_VICTIM);
} }
events.RepeatEvent(5000);
break;
} }
} else
{
DoCastVictim(SPELL_SHADOW_BOLT_VICTIM);
}
if (me->HasUnitState(UNIT_STATE_CASTING)) events.RepeatEvent(5000);
{ break;
return;
} }
} }
DoMeleeAttackIfReady();
} }
}; };
@@ -15,40 +15,28 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData #include "ScriptMgr.h"
SDName: Boss_Golemagg #include "ScriptedCreature.h"
SD%Complete: 90
SDComment: Timers need to be confirmed, Golemagg's Trust need to be checked
SDCategory: Molten Core
EndScriptData */
#include "molten_core.h" #include "molten_core.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "ScriptedCreature.h" #include "ObjectAccessor.h"
#include "ScriptMgr.h"
enum Texts enum Texts
{ {
EMOTE_LOWHP = 0, EMOTE_LOWHP = 0,
}; };
enum Spells enum Spells
{ {
// Golemagg // Golemagg
SPELL_MAGMASPLASH = 13879, SPELL_PYROBLAST = 20228,
SPELL_PYROBLAST = 20228, SPELL_EARTHQUAKE = 19798,
SPELL_EARTHQUAKE = 19798, SPELL_ENRAGE = 19953,
SPELL_ENRAGE = 19953, SPELL_ATTRACK_RAGER = 20544,
SPELL_GOLEMAGG_TRUST = 20553,
// Core Rager // Core Rager
SPELL_MANGLE = 19820 SPELL_MANGLE = 19820,
}; SPELL_FULL_HEAL = 17683,
enum Events
{
EVENT_PYROBLAST = 1,
EVENT_EARTHQUAKE = 2,
}; };
class boss_golemagg : public CreatureScript class boss_golemagg : public CreatureScript
@@ -58,72 +46,79 @@ public:
struct boss_golemaggAI : public BossAI struct boss_golemaggAI : public BossAI
{ {
boss_golemaggAI(Creature* creature) : BossAI(creature, BOSS_GOLEMAGG_THE_INCINERATOR) boss_golemaggAI(Creature* creature) : BossAI(creature, DATA_GOLEMAGG),
{ earthquakeTimer(0),
} pyroblastTimer(0),
enraged(false)
{}
void Reset() override void Reset() override
{ {
BossAI::Reset(); _Reset();
DoCast(me, SPELL_MAGMASPLASH, true); earthquakeTimer = 0;
pyroblastTimer = urand(3000, 7000);
enraged = false;
} }
void EnterCombat(Unit* victim) override void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{ {
BossAI::EnterCombat(victim); if (!enraged && me->HealthBelowPctDamaged(10, damage))
events.ScheduleEvent(EVENT_PYROBLAST, 7000);
// The two ragers should join the fight alongside me against my foes.
std::list<Creature*> ragers;
me->GetCreaturesWithEntryInRange(ragers, 100, NPC_CORE_RAGER);
for (Creature* i : ragers)
{ {
if (i && i->IsAlive() && !i->IsInCombat()) DoCastSelf(SPELL_ENRAGE, true);
{ DoCastSelf(SPELL_ATTRACK_RAGER, true);
i->AI()->AttackStart(victim); DoCastAOE(SPELL_EARTHQUAKE, true);
} earthquakeTimer = 5000;
enraged = true;
} }
} }
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override
{
if (!HealthBelowPct(10) || me->HasAura(SPELL_ENRAGE))
return;
DoCast(me, SPELL_ENRAGE, true);
events.ScheduleEvent(EVENT_EARTHQUAKE, 3000);
}
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
if (!UpdateVictim()) if (!UpdateVictim())
{
return; return;
}
events.Update(diff); // Should not get impact by cast state (cast should always happen)
if (earthquakeTimer)
{
if (earthquakeTimer <= diff)
{
DoCastAOE(SPELL_EARTHQUAKE, true);
earthquakeTimer = 5000;
}
else
{
earthquakeTimer -= diff;
}
}
if (me->HasUnitState(UNIT_STATE_CASTING)) if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{ {
switch (eventId) return;
}
if (pyroblastTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{ {
case EVENT_PYROBLAST: DoCast(target, SPELL_PYROBLAST);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_PYROBLAST);
events.ScheduleEvent(EVENT_PYROBLAST, 7000);
break;
case EVENT_EARTHQUAKE:
DoCastVictim(SPELL_EARTHQUAKE);
events.ScheduleEvent(EVENT_EARTHQUAKE, 3000);
break;
default:
break;
} }
pyroblastTimer = 7000;
}
else
{
pyroblastTimer -= diff;
} }
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
private:
uint32 earthquakeTimer;
uint32 pyroblastTimer;
bool enraged;
}; };
CreatureAI* GetAI(Creature* creature) const override CreatureAI* GetAI(Creature* creature) const override
@@ -139,45 +134,79 @@ public:
struct npc_core_ragerAI : public ScriptedAI struct npc_core_ragerAI : public ScriptedAI
{ {
npc_core_ragerAI(Creature* creature) : ScriptedAI(creature) npc_core_ragerAI(Creature* creature) : ScriptedAI(creature),
instance(creature->GetInstanceScript()),
mangleTimer(7000),
rangeCheckTimer(1000)
{ {
instance = creature->GetInstanceScript();
} }
void Reset() override void Reset() override
{ {
mangleTimer = 7 * IN_MILLISECONDS; // These times are probably wrong mangleTimer = 7000; // These times are probably wrong
rangeCheckTimer = 1000;
if (instance->GetBossState(DATA_GOLEMAGG) == DONE)
{
DoCastSelf(SPELL_CORE_RAGER_QUIET_SUICIDE, true);
}
} }
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*dmgType*/, SpellSchoolMask /*school*/) override
{ {
if (HealthAbovePct(50) || !instance) // Just in case if something will go bad, let players to kill this creature
return; if (instance->GetBossState(DATA_GOLEMAGG) == DONE)
if (Creature* pGolemagg = instance->instance->GetCreature(instance->GetGuidData(BOSS_GOLEMAGG_THE_INCINERATOR)))
{ {
if (pGolemagg->IsAlive()) return;
{ }
me->AddAura(SPELL_GOLEMAGG_TRUST, me);
Talk(EMOTE_LOWHP); if (me->HealthBelowPctDamaged(50, damage))
me->SetFullHealth(); {
} damage = 0;
DoCastSelf(SPELL_FULL_HEAL, true);
Talk(EMOTE_LOWHP);
} }
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
if (!UpdateVictim()) if (!UpdateVictim())
{
return; return;
}
// Should have no impact from unit state
if (rangeCheckTimer <= diff)
{
Creature const* golemagg = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GEDDON));
if (golemagg && me->GetDistance(golemagg) > 100.0f)
{
instance->DoAction(ACTION_RESET_MAGMADAR_ENCOUNTER);
return;
}
rangeCheckTimer = 1000;
}
else
{
rangeCheckTimer -= diff;
}
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
// Mangle // Mangle
if (mangleTimer <= diff) if (mangleTimer <= diff)
{ {
DoCastVictim(SPELL_MANGLE); DoCastVictim(SPELL_MANGLE);
mangleTimer = 10 * IN_MILLISECONDS; mangleTimer = 10000;
} }
else else
{
mangleTimer -= diff; mangleTimer -= diff;
}
DoMeleeAttackIfReady(); DoMeleeAttackIfReady();
} }
@@ -185,6 +214,7 @@ public:
private: private:
InstanceScript* instance; InstanceScript* instance;
uint32 mangleTimer; uint32 mangleTimer;
uint32 rangeCheckTimer;
}; };
CreatureAI* GetAI(Creature* creature) const override CreatureAI* GetAI(Creature* creature) const override
@@ -15,13 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Lucifron
SD%Complete: 100
SDComment:
SDCategory: Molten Core
EndScriptData */
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h" #include "ScriptedCreature.h"
#include "molten_core.h" #include "molten_core.h"
@@ -47,9 +40,7 @@ public:
struct boss_lucifronAI : public BossAI struct boss_lucifronAI : public BossAI
{ {
boss_lucifronAI(Creature* creature) : BossAI(creature, BOSS_LUCIFRON) boss_lucifronAI(Creature* creature) : BossAI(creature, DATA_LUCIFRON) {}
{
}
void EnterCombat(Unit* /*victim*/) override void EnterCombat(Unit* /*victim*/) override
{ {
@@ -59,46 +50,29 @@ public:
events.ScheduleEvent(EVENT_SHADOW_SHOCK, 5000); events.ScheduleEvent(EVENT_SHADOW_SHOCK, 5000);
} }
void UpdateAI(uint32 diff) override void ExecuteEvent(uint32 eventId) override
{ {
if (!UpdateVictim()) switch (eventId)
{ {
return; case EVENT_IMPENDING_DOOM:
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 const eventId = events.ExecuteEvent())
{
switch (eventId)
{ {
case EVENT_IMPENDING_DOOM: DoCastVictim(SPELL_IMPENDING_DOOM);
{ events.RepeatEvent(20000);
DoCastVictim(SPELL_IMPENDING_DOOM); break;
events.RepeatEvent(20000); }
break; case EVENT_LUCIFRON_CURSE:
} {
case EVENT_LUCIFRON_CURSE: DoCastVictim(SPELL_LUCIFRON_CURSE);
{ events.RepeatEvent(20000);
DoCastVictim(SPELL_LUCIFRON_CURSE); break;
events.RepeatEvent(20000); }
break; case EVENT_SHADOW_SHOCK:
} {
case EVENT_SHADOW_SHOCK: DoCastVictim(SPELL_SHADOW_SHOCK);
{ events.RepeatEvent(5000);
DoCastVictim(SPELL_SHADOW_SHOCK); break;
events.RepeatEvent(5000);
break;
}
} }
} }
DoMeleeAttackIfReady();
} }
}; };
@@ -15,102 +15,98 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Magmadar
SD%Complete: 75
SDComment: Conflag on ground nyi
SDCategory: Molten Core
EndScriptData */
#include "molten_core.h"
#include "ObjectMgr.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "SpellScript.h"
#include "ScriptedCreature.h"
#include "molten_core.h"
enum Texts enum Texts
{ {
EMOTE_FRENZY = 0, EMOTE_FRENZY = 0,
EMOTE_SMOLDERING = 0,
EMOTE_IGNITE = 1,
}; };
enum Spells enum Spells
{ {
SPELL_FRENZY = 19451, SPELL_FRENZY = 19451,
SPELL_MAGMA_SPIT = 19449, SPELL_MAGMA_SPIT = 19449,
SPELL_PANIC = 19408, SPELL_PANIC = 19408,
SPELL_LAVA_BOMB = 19428, SPELL_LAVA_BOMB = 19411, // This calls a dummy server side effect that cast spell 20494 to spawn GO 177704 for 30s
SPELL_SERRATED_BITE = 19771, SPELL_LAVA_BOMB_EFFECT = 20494, // Spawns trap GO 177704 which triggers 19428
SPELL_LAVA_BOMB_RANGED = 20474, // This calls a dummy server side effect that cast spell 20495 to spawn GO 177704 for 60s
SPELL_LAVA_BOMB_RANGED_EFFECT = 20495, // Spawns trap GO 177704 which triggers 19428
}; };
enum Events enum Events
{ {
EVENT_FRENZY = 1, EVENT_FRENZY = 1,
EVENT_PANIC = 2, EVENT_PANIC,
EVENT_LAVA_BOMB = 3, EVENT_LAVA_BOMB,
EVENT_SERRATED_BITE = 1, EVENT_LAVA_BOMB_RANGED,
EVENT_IGNITE = 2,
}; };
constexpr float MELEE_TARGET_LOOKUP_DIST = 10.0f;
class boss_magmadar : public CreatureScript class boss_magmadar : public CreatureScript
{ {
public: public:
boss_magmadar() : CreatureScript("boss_magmadar") { } boss_magmadar() : CreatureScript("boss_magmadar") {}
struct boss_magmadarAI : public BossAI struct boss_magmadarAI : public BossAI
{ {
boss_magmadarAI(Creature* creature) : BossAI(creature, BOSS_MAGMADAR) boss_magmadarAI(Creature* creature) : BossAI(creature, DATA_MAGMADAR) {}
{
}
void Reset() override void EnterCombat(Unit* /*victim*/) override
{ {
BossAI::Reset(); _EnterCombat();
DoCast(me, SPELL_MAGMA_SPIT, true); events.ScheduleEvent(EVENT_FRENZY, 8500);
} events.ScheduleEvent(EVENT_PANIC, 9500);
void EnterCombat(Unit* victim) override
{
BossAI::EnterCombat(victim);
events.ScheduleEvent(EVENT_FRENZY, 30000);
events.ScheduleEvent(EVENT_PANIC, 20000);
events.ScheduleEvent(EVENT_LAVA_BOMB, 12000); events.ScheduleEvent(EVENT_LAVA_BOMB, 12000);
events.ScheduleEvent(EVENT_LAVA_BOMB_RANGED, 15000);
} }
void UpdateAI(uint32 diff) override void ExecuteEvent(uint32 eventId) override
{ {
if (!UpdateVictim()) switch (eventId)
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{ {
switch (eventId) case EVENT_FRENZY:
{ {
case EVENT_FRENZY: Talk(EMOTE_FRENZY);
Talk(EMOTE_FRENZY); DoCastSelf(SPELL_FRENZY);
DoCast(me, SPELL_FRENZY); events.RepeatEvent(urand(15000, 20000));
events.ScheduleEvent(EVENT_FRENZY, 15000); break;
break; }
case EVENT_PANIC: case EVENT_PANIC:
DoCastVictim(SPELL_PANIC); {
events.ScheduleEvent(EVENT_PANIC, 35000); DoCastVictim(SPELL_PANIC);
break; events.RepeatEvent(urand(31000, 38000));
case EVENT_LAVA_BOMB: break;
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_LAVA_BOMB)) }
DoCast(target, SPELL_LAVA_BOMB); case EVENT_LAVA_BOMB:
events.ScheduleEvent(EVENT_LAVA_BOMB, 12000); {
break; if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, MELEE_TARGET_LOOKUP_DIST, true))
default: {
break; DoCast(target, SPELL_LAVA_BOMB);
}
events.RepeatEvent(urand(12000, 15000));
break;
}
case EVENT_LAVA_BOMB_RANGED:
{
std::list<Unit*> targets;
SelectTargetList(targets, [this](Unit* target)
{
return target && target->IsPlayer() && target->GetDistance(me) > MELEE_TARGET_LOOKUP_DIST && target->GetDistance(me) < 100.0f;
}, 1, SELECT_TARGET_RANDOM);
if (!targets.empty())
{
DoCast(targets.front() , SPELL_LAVA_BOMB_RANGED);
}
events.RepeatEvent(urand(12000, 15000));
break;
} }
} }
DoMeleeAttackIfReady();
} }
}; };
@@ -120,142 +116,64 @@ public:
} }
}; };
// Serrated Bites timer may be wrong // 19411 Lava Bomb
class npc_magmadar_core_hound : public CreatureScript // 20474 Lava Bomb
class spell_magmadar_lava_bomb : public SpellScriptLoader
{ {
public: public:
npc_magmadar_core_hound() : CreatureScript("npc_magmadar_core_hound") { } spell_magmadar_lava_bomb() : SpellScriptLoader("spell_magmadar_lava_bomb") {}
struct npc_magmadar_core_houndAI : public CreatureAI class spell_magmadar_lava_bomb_SpellScript : public SpellScript
{ {
npc_magmadar_core_houndAI(Creature* creature) : CreatureAI(creature) PrepareSpellScript(spell_magmadar_lava_bomb_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{ {
return ValidateSpellInfo({ SPELL_LAVA_BOMB_EFFECT, SPELL_LAVA_BOMB_RANGED_EFFECT });
} }
EventMap events; void HandleDummy(SpellEffIndex /*effIndex*/)
std::list<Creature*> hounds;
bool smoldering = false;
Unit* killer;
void removeFeignDeath()
{ {
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT); if (Unit* target = GetHitUnit())
me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
me->ClearUnitState(UNIT_STATE_DIED);
me->ClearUnitState(UNIT_STATE_CANNOT_AUTOATTACK);
me->DisableRotate(false);
}
void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
{
if (me->HealthBelowPctDamaged(0, damage))
{ {
if (!smoldering) uint32 spellId = 0;
switch (m_scriptSpellId)
{ {
killer = attacker; case SPELL_LAVA_BOMB:
events.ScheduleEvent(EVENT_IGNITE, 10000); {
me->SetHealth(1); spellId = SPELL_LAVA_BOMB_EFFECT;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
me->AddUnitState(UNIT_STATE_DIED);
me->AddUnitState(UNIT_STATE_CANNOT_AUTOATTACK);
me->DisableRotate(true);
Talk(EMOTE_SMOLDERING);
}
damage = 0;
smoldering = true;
}
}
void Reset() override
{
removeFeignDeath();
}
void JustDied(Unit* /*killer*/) override
{
removeFeignDeath();
}
void EnterCombat(Unit* /*victim*/) override
{
events.ScheduleEvent(EVENT_SERRATED_BITE, 10000); // timer may be wrong
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim() && !smoldering)
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_SERRATED_BITE:
if (UpdateVictim() && !smoldering)
{
DoCast(me->GetVictim(), SPELL_SERRATED_BITE);
events.ScheduleEvent(EVENT_SERRATED_BITE, 10000); // again, timer may be wrong
}
break; break;
case EVENT_IGNITE: }
smoldering = false; case SPELL_LAVA_BOMB_RANGED:
me->GetCreaturesWithEntryInRange(hounds, 80, NPC_CORE_HOUND); {
for (Creature* i : hounds) spellId = SPELL_LAVA_BOMB_RANGED_EFFECT;
{
if (i && i->IsAlive() && i->IsInCombat() && !i->HasUnitState(UNIT_STATE_DIED))
{
Talk(EMOTE_IGNITE);
me->SetFullHealth();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
me->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
me->ClearUnitState(UNIT_STATE_DIED);
me->ClearUnitState(UNIT_STATE_CANNOT_AUTOATTACK);
me->DisableRotate(false);
me->AI()->AttackStart(i->GetVictim());
return;
}
}
if (me->HasUnitState(UNIT_STATE_DIED))
{
if (killer)
{
me->Kill(killer, me);
}
else
{
me->Kill(me, me);
}
}
break; break;
}
default: default:
break; {
return;
}
} }
target->CastSpell(target, spellId, true, nullptr, nullptr, GetCaster()->GetGUID());
} }
}
DoMeleeAttackIfReady(); void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_magmadar_lava_bomb_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
} }
}; };
CreatureAI* GetAI(Creature* creature) const override SpellScript* GetSpellScript() const override
{ {
return GetMoltenCoreAI<npc_magmadar_core_houndAI>(creature); return new spell_magmadar_lava_bomb_SpellScript();
} }
}; };
void AddSC_boss_magmadar() void AddSC_boss_magmadar()
{ {
new boss_magmadar(); new boss_magmadar();
new npc_magmadar_core_hound();
// Spells
new spell_magmadar_lava_bomb();
} }
@@ -15,192 +15,561 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Majordomo_Executus
SD%Complete: 30
SDComment: Correct spawning and Event NYI
SDCategory: Molten Core
EndScriptData */
#include "molten_core.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "molten_core.h"
#include "Player.h"
#include "ScriptedGossip.h"
#include "ObjectAccessor.h"
#include "SpellScript.h"
enum Texts enum Texts
{ {
SAY_AGGRO = 0, SAY_AGGRO = 0,
SAY_SPAWN = 1, SAY_SPAWN = 1,
SAY_SLAY = 2, SAY_SLAY = 2,
SAY_SPECIAL = 3, SAY_DEFEAT = 3,
SAY_DEFEAT = 4, SAY_SUMMON_MAJ = 4,
SAY_ARRIVAL2_MAJ = 5,
SAY_LAST_ADD = 6,
SAY_SUMMON_MAJ = 5, SAY_DEFEAT_2 = 7,
SAY_ARRIVAL2_MAJ = 6 SAY_DEFEAT_3 = 8,
// Ragnaros event
// Majordomo
SAY_RAG_SUM_1 = 9,
SAY_RAG_SUM_2 = 10,
// Ragnaros
SAY_ARRIVAL1_RAG = 1,
SAY_ARRIVAL3_RAG = 3,
}; };
enum Spells enum Spells
{ {
SPELL_MAGIC_REFLECTION = 20619, SPELL_MAGIC_REFLECTION = 20619,
SPELL_DAMAGE_REFLECTION = 21075, SPELL_DAMAGE_REFLECTION = 21075,
SPELL_BLAST_WAVE = 20229, SPELL_BLAST_WAVE = 20229,
SPELL_AEGIS_OF_RAGNAROS = 20620, SPELL_AEGIS_OF_RAGNAROS = 20620,
SPELL_TELEPORT = 20618, SPELL_TELEPORT_RANDOM = 20618, // Teleport random target
SPELL_SUMMON_RAGNAROS = 19774, SPELL_TELEPORT_TARGET = 20534, // Teleport Victim
}; SPELL_ENCOURAGEMENT = 21086,
SPELL_CHAMPION = 21090, // Server side
SPELL_IMMUNE_POLY = 21087, // Server side
SPELL_HATE_TO_ZERO = 20538, // Threat reset after each teleport. Server side
SPELL_SEPARATION_ANXIETY = 21094, // Aura cast on himself by Majordomo Executus, if adds move out of range, they will cast spell 21095 on themselves
SPELL_SEPARATION_ANXIETY_MINION = 21095,
#define GOSSIP_HELLO 4995 // Outro & Ragnaros intro
SPELL_TELEPORT_SELF = 19484,
SPELL_SUMMON_RAGNAROS = 19774,
SPELL_ELEMENTAL_FIRE = 19773,
SPELL_RAGNA_EMERGE = 20568,
SPELL_RAGNAROS_FADE = 21107,
SPELL_RAGNAROS_SUBMERGE_EFFECT = 21859, // Applies pacify state and applies all schools immunity
};
enum Events enum Events
{ {
EVENT_MAGIC_REFLECTION = 1, EVENT_MAGIC_REFLECTION = 1,
EVENT_DAMAGE_REFLECTION = 2, EVENT_DAMAGE_REFLECTION,
EVENT_BLAST_WAVE = 3, EVENT_BLAST_WAVE,
EVENT_TELEPORT = 4, EVENT_TELEPORT_RANDOM,
EVENT_TELEPORT_TARGET,
EVENT_AEGIS_OF_RAGNAROS,
EVENT_OUTRO_1 = 5, EVENT_DEFEAT_OUTRO_1 = 1,
EVENT_OUTRO_2 = 6, EVENT_DEFEAT_OUTRO_2,
EVENT_OUTRO_3 = 7, EVENT_DEFEAT_OUTRO_3,
EVENT_RAGNAROS_SUMMON_1 = 1,
EVENT_RAGNAROS_SUMMON_2,
EVENT_RAGNAROS_SUMMON_3,
EVENT_RAGNAROS_SUMMON_4,
EVENT_RAGNAROS_SUMMON_5,
EVENT_RAGNAROS_SUMMON_6,
EVENT_RAGNAROS_SUMMON_7,
EVENT_RAGNAROS_EMERGE,
}; };
enum Misc
{
TEXT_ID_SUMMON_1 = 4995,
TEXT_ID_SUMMON_2 = 5011,
TEXT_ID_SUMMON_3 = 5012,
GOSSIP_ITEM_SUMMON_1 = 4093,
GOSSIP_ITEM_SUMMON_2 = 4109,
GOSSIP_ITEM_SUMMON_3 = 4108,
FACTION_MAJORDOMO_FRIENDLY = 1080,
SUMMON_GROUP_ADDS = 1,
// Points
POINT_RAGNAROS_SUMMON = 1,
// Event phases
PHASE_NONE = 1,
PHASE_COMBAT = 2,
PHASE_DEFEAT_OUTRO = 3,
PHASE_RAGNAROS_SUMMONING = 4,
};
Position const MajordomoRagnaros = { 848.933f, -812.875f, -229.601f, 4.046f };
Position const MajordomoSummonPos = {759.542f, -1173.43f, -118.974f, 3.3048f };
Position const MajordomoMoveRagPos = { 830.9636f, -814.7055f, -228.9733f, 0.0f }; // Position used at Ragnaros summoning event
Position const RagnarosSummonPos = { 838.3082f, -831.4665f, -232.1853f, 2.199115f };
class boss_majordomo : public CreatureScript class boss_majordomo : public CreatureScript
{ {
public: public:
boss_majordomo() : CreatureScript("boss_majordomo") { } boss_majordomo() : CreatureScript("boss_majordomo") {}
struct boss_majordomoAI : public BossAI struct boss_majordomoAI : public BossAI
{ {
boss_majordomoAI(Creature* creature) : BossAI(creature, BOSS_MAJORDOMO_EXECUTUS) boss_majordomoAI(Creature* creature) : BossAI(creature, DATA_MAJORDOMO_EXECUTUS), spawnInTextTimer(0) {}
// Disabled events
void JustDied(Unit* /*killer*/) override {}
void JustSummoned(Creature* summon) override
{ {
if (summon->GetEntry() == NPC_RAGNAROS)
{
summon->CastSpell(summon, SPELL_RAGNAROS_FADE);
summon->CastSpell(summon, SPELL_RAGNAROS_SUBMERGE_EFFECT, true);
summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE);
summon->SetReactState(REACT_PASSIVE);
}
} }
void KilledUnit(Unit* /*victim*/) override void InitializeAI() override
{ {
if (urand(0, 99) < 25) BossAI::InitializeAI();
if (instance->GetBossState(DATA_MAJORDOMO_EXECUTUS) != DONE)
{
events.SetPhase(PHASE_COMBAT);
std::list<TempSummon*> p_summons;
me->SummonCreatureGroup(SUMMON_GROUP_ADDS, &p_summons);
if (!p_summons.empty())
{
for (TempSummon const* summon : p_summons)
{
if (summon)
{
static_minionsGUIDS.insert(summon->GetGUID());
}
}
}
spawnInTextTimer = 10000;
}
else
{
events.SetPhase(PHASE_NONE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
me->SetFaction(FACTION_MAJORDOMO_FRIENDLY);
}
}
void Reset() override
{
me->ResetLootMode();
events.Reset();
aliveMinionsGUIDS.clear();
if (instance->GetBossState(DATA_MAJORDOMO_EXECUTUS) != DONE)
{
events.SetPhase(PHASE_COMBAT);
instance->SetBossState(DATA_MAJORDOMO_EXECUTUS, NOT_STARTED);
}
else
{
static_minionsGUIDS.clear();
summons.DespawnAll();
}
}
bool CanAIAttack(Unit const* /*target*/) const override
{
return instance->GetBossState(DATA_MAJORDOMO_EXECUTUS) != DONE;
}
void KilledUnit(Unit* victim) override
{
if (roll_chance_i(25) && victim->IsPlayer())
{
Talk(SAY_SLAY); Talk(SAY_SLAY);
}
} }
void EnterCombat(Unit* who) override void EnterCombat(Unit* /*attacker*/) override
{ {
BossAI::EnterCombat(who); if (!events.IsInPhase(PHASE_COMBAT))
{
return;
}
_EnterCombat();
DoCastAOE(SPELL_SEPARATION_ANXIETY);
spawnInTextTimer = 0;
Talk(SAY_AGGRO); Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_MAGIC_REFLECTION, 30000); DoCastSelf(SPELL_AEGIS_OF_RAGNAROS, true);
events.ScheduleEvent(EVENT_DAMAGE_REFLECTION, 15000);
events.ScheduleEvent(EVENT_BLAST_WAVE, 10000); events.ScheduleEvent(EVENT_MAGIC_REFLECTION, 30000, PHASE_COMBAT, PHASE_COMBAT);
events.ScheduleEvent(EVENT_TELEPORT, 20000); events.ScheduleEvent(EVENT_DAMAGE_REFLECTION, 15000, PHASE_COMBAT, PHASE_COMBAT);
// Call every flamewaker around him events.ScheduleEvent(EVENT_BLAST_WAVE, 10000, PHASE_COMBAT, PHASE_COMBAT);
me->CallForHelp(30); events.ScheduleEvent(EVENT_TELEPORT_RANDOM, 15000, PHASE_COMBAT, PHASE_COMBAT);
events.ScheduleEvent(EVENT_TELEPORT_TARGET, 30000, PHASE_COMBAT, PHASE_COMBAT);
aliveMinionsGUIDS.clear();
aliveMinionsGUIDS = static_minionsGUIDS;
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
aliveMinionsGUIDS.erase(summon->GetGUID());
if (summon->GetEntry() == NPC_FLAMEWAKER_HEALER || summon->GetEntry() == NPC_FLAMEWAKER_ELITE)
{
uint32 const remainingAdds = std::count_if(aliveMinionsGUIDS.begin(), aliveMinionsGUIDS.end(), [](ObjectGuid const& summonGuid)
{
return summonGuid.GetEntry() == NPC_FLAMEWAKER_HEALER || summonGuid.GetEntry() == NPC_FLAMEWAKER_ELITE;
});
// Last remaining add
if (remainingAdds == 1)
{
Talk(SAY_LAST_ADD);
DoCastAOE(SPELL_CHAMPION);
}
// 50% of adds
else if (remainingAdds == 4)
{
DoCastAOE(SPELL_IMMUNE_POLY);
}
else if (!remainingAdds)
{
if (!static_minionsGUIDS.empty())
{
for (ObjectGuid const& guid : static_minionsGUIDS)
{
if (Creature* minion = ObjectAccessor::GetCreature(*me, guid))
{
minion->DespawnOrUnsummon();
}
}
static_minionsGUIDS.clear();
}
instance->SetBossState(DATA_MAJORDOMO_EXECUTUS, DONE);
events.CancelEventGroup(PHASE_COMBAT);
me->GetMap()->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, me->GetEntry(), me);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
me->SetFaction(FACTION_MAJORDOMO_FRIENDLY);
EnterEvadeMode();
Talk(SAY_DEFEAT);
return;
}
DoCastAOE(SPELL_ENCOURAGEMENT);
}
}
void JustReachedHome() override
{
_JustReachedHome();
if (instance->GetBossState(DATA_MAJORDOMO_EXECUTUS) == DONE)
{
events.Reset();
events.SetPhase(PHASE_DEFEAT_OUTRO);
events.ScheduleEvent(EVENT_DEFEAT_OUTRO_1, 7500, PHASE_DEFEAT_OUTRO, PHASE_DEFEAT_OUTRO);
}
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*dmgType*/, SpellSchoolMask /*school*/) override
{
if (events.IsInPhase(PHASE_COMBAT) && me->GetHealth() <= damage)
{
damage = 0;
}
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
if (instance->GetBossState(BOSS_MAJORDOMO_EXECUTUS) != DONE) if (spawnInTextTimer)
{ {
if (!UpdateVictim()) if (spawnInTextTimer <= diff)
return;
events.Update(diff);
if (!me->FindNearestCreature(NPC_FLAMEWAKER_HEALER, 100.0f) && !me->FindNearestCreature(NPC_FLAMEWAKER_ELITE, 100.0f))
{ {
me->GetMap()->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, me->GetEntry(), me); spawnInTextTimer = 0;
me->SetFaction(FACTION_FRIENDLY); Talk(SAY_SPAWN);
EnterEvadeMode();
Talk(SAY_DEFEAT);
_JustDied();
events.ScheduleEvent(EVENT_OUTRO_1, 32000);
return;
} }
else
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (HealthBelowPct(50))
DoCast(me, SPELL_AEGIS_OF_RAGNAROS, true);
while (uint32 eventId = events.ExecuteEvent())
{ {
switch (eventId) spawnInTextTimer -= diff;
{
case EVENT_MAGIC_REFLECTION:
DoCast(me, SPELL_MAGIC_REFLECTION);
events.ScheduleEvent(EVENT_MAGIC_REFLECTION, 30000);
break;
case EVENT_DAMAGE_REFLECTION:
DoCast(me, SPELL_DAMAGE_REFLECTION);
events.ScheduleEvent(EVENT_DAMAGE_REFLECTION, 30000);
break;
case EVENT_BLAST_WAVE:
DoCastVictim(SPELL_BLAST_WAVE);
events.ScheduleEvent(EVENT_BLAST_WAVE, 10000);
break;
case EVENT_TELEPORT:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
DoCast(target, SPELL_TELEPORT);
events.ScheduleEvent(EVENT_TELEPORT, 20000);
break;
default:
break;
}
} }
DoMeleeAttackIfReady();
} }
else
{
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent()) switch (events.GetPhaseMask())
{
case (1 << (PHASE_COMBAT - 1)):
{ {
switch (eventId) if (!UpdateVictim())
{ {
case EVENT_OUTRO_1: return;
me->NearTeleportTo(RagnarosTelePos.GetPositionX(), RagnarosTelePos.GetPositionY(), RagnarosTelePos.GetPositionZ(), RagnarosTelePos.GetOrientation());
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
break;
case EVENT_OUTRO_2:
instance->instance->SummonCreature(NPC_RAGNAROS, RagnarosSummonPos);
break;
case EVENT_OUTRO_3:
Talk(SAY_ARRIVAL2_MAJ);
break;
default:
break;
} }
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 const eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_MAGIC_REFLECTION:
{
DoCastSelf(SPELL_MAGIC_REFLECTION);
events.RepeatEvent(30000);
break;
}
case EVENT_DAMAGE_REFLECTION:
{
DoCastSelf(SPELL_DAMAGE_REFLECTION);
events.RepeatEvent(30000);
break;
}
case EVENT_BLAST_WAVE:
{
DoCastVictim(SPELL_BLAST_WAVE);
events.RepeatEvent(10000);
break;
}
case EVENT_TELEPORT_RANDOM:
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
{
DoCastSelf(SPELL_HATE_TO_ZERO, true);
DoCast(target, SPELL_TELEPORT_RANDOM);
}
events.RepeatEvent(15000);
break;
}
case EVENT_TELEPORT_TARGET:
{
DoCastSelf(SPELL_HATE_TO_ZERO, true);
DoCastAOE(SPELL_TELEPORT_TARGET);
events.RepeatEvent(30000);
break;
}
}
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
}
DoMeleeAttackIfReady();
break;
} }
case (1 << (PHASE_DEFEAT_OUTRO - 1)):
{
events.Update(diff);
while (uint32 const eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_DEFEAT_OUTRO_1:
{
Talk(SAY_DEFEAT_2);
events.ScheduleEvent(EVENT_DEFEAT_OUTRO_2, 8000, PHASE_DEFEAT_OUTRO, PHASE_DEFEAT_OUTRO);
break;
}
case EVENT_DEFEAT_OUTRO_2:
{
Talk(SAY_DEFEAT_3);
events.ScheduleEvent(EVENT_DEFEAT_OUTRO_3, 21500, PHASE_DEFEAT_OUTRO, PHASE_DEFEAT_OUTRO);
break;
}
case EVENT_DEFEAT_OUTRO_3:
{
DoCastSelf(SPELL_TELEPORT_SELF);
break;
}
}
}
break;
}
case (1 << (PHASE_RAGNAROS_SUMMONING - 1)):
{
events.Update(diff);
while (uint32 const eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_RAGNAROS_SUMMON_1:
{
if (GameObject* lavaSplash = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_LAVA_SPLASH)))
{
lavaSplash->SetRespawnTime(900);
lavaSplash->Refresh();
}
if (GameObject* lavaSteam = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_LAVA_STEAM)))
{
lavaSteam->SetRespawnTime(900);
lavaSteam->Refresh();
}
Talk(SAY_RAG_SUM_2);
// Next event will get triggered in MovementInform
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_RAGNAROS_SUMMON, MajordomoMoveRagPos, true, false);
break;
}
case EVENT_RAGNAROS_SUMMON_2:
{
if (GameObject* lavaSteam = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_LAVA_STEAM)))
{
me->SetFacingToObject(lavaSteam);
}
Talk(SAY_SUMMON_MAJ);
events.ScheduleEvent(EVENT_RAGNAROS_SUMMON_3, 16700, PHASE_RAGNAROS_SUMMONING, PHASE_RAGNAROS_SUMMONING);
events.ScheduleEvent(EVENT_RAGNAROS_EMERGE, 15000, PHASE_RAGNAROS_SUMMONING, PHASE_RAGNAROS_SUMMONING);
break;
}
case EVENT_RAGNAROS_SUMMON_3:
{
if (Creature* ragnaros = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAGNAROS)))
{
ragnaros->AI()->Talk(SAY_ARRIVAL1_RAG);
}
events.ScheduleEvent(EVENT_RAGNAROS_SUMMON_4, 11700, PHASE_RAGNAROS_SUMMONING, PHASE_RAGNAROS_SUMMONING);
break;
}
case EVENT_RAGNAROS_SUMMON_4:
{
Talk(SAY_ARRIVAL2_MAJ);
events.ScheduleEvent(EVENT_RAGNAROS_SUMMON_5, 8700, PHASE_RAGNAROS_SUMMONING, PHASE_RAGNAROS_SUMMONING);
break;
}
case EVENT_RAGNAROS_SUMMON_5:
{
if (Creature* ragnaros = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAGNAROS)))
{
ragnaros->AI()->Talk(SAY_ARRIVAL3_RAG);
}
events.ScheduleEvent(EVENT_RAGNAROS_SUMMON_6, 16500, PHASE_RAGNAROS_SUMMONING, PHASE_RAGNAROS_SUMMONING);
break;
}
case EVENT_RAGNAROS_SUMMON_6:
{
if (Creature* ragnaros = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAGNAROS)))
{
ragnaros->CastSpell(me, SPELL_ELEMENTAL_FIRE, true);
ragnaros->AI()->DoAction(ACTION_FINISH_RAGNAROS_INTRO);
}
break;
}
// Additional events
case EVENT_RAGNAROS_EMERGE:
{
if (Creature* ragnaros = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_RAGNAROS)))
{
ragnaros->RemoveAurasDueToSpell(SPELL_RAGNAROS_FADE);
ragnaros->CastSpell(ragnaros, SPELL_RAGNA_EMERGE);
}
}break;
}
}
break;
}
}
}
void MovementInform(uint32 type, uint32 pointId) override
{
if (type == POINT_MOTION_TYPE && pointId == POINT_RAGNAROS_SUMMON)
{
DoCastAOE(SPELL_SUMMON_RAGNAROS);
events.ScheduleEvent(EVENT_RAGNAROS_SUMMON_2, 11500, PHASE_RAGNAROS_SUMMONING, PHASE_RAGNAROS_SUMMONING);
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
if (events.IsInPhase(PHASE_DEFEAT_OUTRO) && spellInfo->Id == SPELL_TELEPORT_SELF)
{
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
me->SetHomePosition(MajordomoRagnaros);
me->NearTeleportTo(MajordomoRagnaros.GetPositionX(), MajordomoRagnaros.GetPositionY(), MajordomoRagnaros.GetPositionZ(), MajordomoRagnaros.GetOrientation());
events.SetPhase(PHASE_NONE);
} }
} }
void DoAction(int32 action) override void DoAction(int32 action) override
{ {
if (action == ACTION_START_RAGNAROS && events.GetNextEventTime(EVENT_OUTRO_2) == 0) if (action == ACTION_START_RAGNAROS_INTRO && !events.IsInPhase(PHASE_RAGNAROS_SUMMONING))
{ {
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); events.SetPhase(PHASE_RAGNAROS_SUMMONING);
Talk(SAY_SUMMON_MAJ); events.ScheduleEvent(EVENT_RAGNAROS_SUMMON_1, 5000, PHASE_RAGNAROS_SUMMONING, PHASE_RAGNAROS_SUMMONING);
events.ScheduleEvent(EVENT_OUTRO_2, 8000);
events.ScheduleEvent(EVENT_OUTRO_3, 24000);
}
else if (action == ACTION_START_RAGNAROS_ALT)
{
me->SetFaction(FACTION_FRIENDLY);
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
} }
} }
private:
GuidSet static_minionsGUIDS; // contained data should be changed on encounter completion
GuidSet aliveMinionsGUIDS; // used for calculations
uint32 spawnInTextTimer;
}; };
bool OnGossipHello(Player* player, Creature* creature) override bool OnGossipHello(Player* player, Creature* creature) override
{ {
AddGossipItemFor(player, 4093, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); AddGossipItemFor(player, GOSSIP_ITEM_SUMMON_1, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
SendGossipMenuFor(player, GOSSIP_HELLO, creature->GetGUID()); SendGossipMenuFor(player, TEXT_ID_SUMMON_1, creature->GetGUID());
return true; return true;
} }
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 /*action*/) override bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{ {
CloseGossipMenuFor(player); ClearGossipMenuFor(player);
creature->AI()->DoAction(ACTION_START_RAGNAROS); switch (action)
{
case GOSSIP_ACTION_INFO_DEF:
{
AddGossipItemFor(player, GOSSIP_ITEM_SUMMON_2, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
SendGossipMenuFor(player, TEXT_ID_SUMMON_2, creature->GetGUID());
break;
}
case GOSSIP_ACTION_INFO_DEF+1:
{
AddGossipItemFor(player, GOSSIP_ITEM_SUMMON_2, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
SendGossipMenuFor(player, TEXT_ID_SUMMON_2, creature->GetGUID());
break;
}
case GOSSIP_ACTION_INFO_DEF+2:
{
AddGossipItemFor(player, GOSSIP_ITEM_SUMMON_3, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
SendGossipMenuFor(player, TEXT_ID_SUMMON_3, creature->GetGUID());
break;
}
case GOSSIP_ACTION_INFO_DEF+3:
{
CloseGossipMenuFor(player);
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
creature->AI()->Talk(SAY_RAG_SUM_1, player);
creature->AI()->DoAction(ACTION_START_RAGNAROS_INTRO);
break;
}
default:
CloseGossipMenuFor(player);
break;
}
return true; return true;
} }
@@ -210,7 +579,118 @@ public:
} }
}; };
// 20538 Hate to Zero (SERVERSIDE)
class spell_hate_to_zero : public SpellScriptLoader
{
public:
spell_hate_to_zero() : SpellScriptLoader("spell_hate_to_zero") {}
class spell_hate_to_zero_SpellScript : public SpellScript
{
PrepareSpellScript(spell_hate_to_zero_SpellScript);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void HandleHit(SpellEffIndex /*effIndex*/)
{
if (Unit* caster = GetCaster())
{
if (Creature* creatureCaster = caster->ToCreature())
{
creatureCaster->getThreatMgr().resetAllAggro();
}
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_hate_to_zero_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_hate_to_zero_SpellScript();
}
};
// 21094 Separation Anxiety (server side)
class spell_majordomo_separation_nexiety : public SpellScriptLoader
{
public:
spell_majordomo_separation_nexiety() : SpellScriptLoader("spell_majordomo_separation_nexiety") {}
class spell_majordomo_separation_nexiety_AuraScript : public AuraScript
{
PrepareAuraScript(spell_majordomo_separation_nexiety_AuraScript);
bool Validate(SpellInfo const* /*spell*/) override
{
return ValidateSpellInfo({ SPELL_SEPARATION_ANXIETY_MINION });
}
void HandlePeriodic(AuraEffect const* aurEff)
{
Unit const* caster = GetCaster();
Unit* target = GetTarget();
if (caster && target && target->GetDistance(caster) > 40.0f && !target->HasAura(SPELL_SEPARATION_ANXIETY_MINION))
{
target->CastSpell(target, SPELL_SEPARATION_ANXIETY_MINION, true, nullptr, aurEff);
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_majordomo_separation_nexiety_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
}
};
// Should return a fully valid AuraScript pointer.
AuraScript* GetAuraScript() const override
{
return new spell_majordomo_separation_nexiety_AuraScript();
}
};
// 19774 Summon Ragnaros
class spell_summon_ragnaros : public SpellScriptLoader
{
public:
spell_summon_ragnaros() : SpellScriptLoader("spell_summon_ragnaros") {}
class spell_summon_ragnaros_SpellScript : public SpellScript
{
PrepareSpellScript(spell_summon_ragnaros_SpellScript);
void HandleHit()
{
if (Unit* caster = GetCaster())
{
caster->SummonCreature(NPC_RAGNAROS, RagnarosSummonPos, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 2 * HOUR * IN_MILLISECONDS);
}
}
void Register() override
{
AfterCast += SpellCastFn(spell_summon_ragnaros_SpellScript::HandleHit);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_summon_ragnaros_SpellScript();
}
};
void AddSC_boss_majordomo() void AddSC_boss_majordomo()
{ {
new boss_majordomo(); new boss_majordomo();
// Spells
new spell_hate_to_zero();
new spell_majordomo_separation_nexiety();
new spell_summon_ragnaros();
} }
@@ -15,289 +15,304 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Ragnaros
SD%Complete: 95
SDComment: some spells doesnt work correctly
SDCategory: Molten Core
EndScriptData */
#include "molten_core.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "molten_core.h"
enum Texts enum Texts
{ {
SAY_SUMMON_MAJ = 0, SAY_SUMMON_MAJ = 0,
SAY_ARRIVAL1_RAG = 1, SAY_ARRIVAL1_RAG = 1,
SAY_ARRIVAL2_MAJ = 2, SAY_ARRIVAL2_MAJ = 2,
SAY_ARRIVAL3_RAG = 3, SAY_ARRIVAL3_RAG = 3,
SAY_ARRIVAL5_RAG = 4, SAY_ARRIVAL5_RAG = 4,
SAY_REINFORCEMENTS1 = 5, SAY_REINFORCEMENTS1 = 5,
SAY_REINFORCEMENTS2 = 6, SAY_REINFORCEMENTS2 = 6,
SAY_HAND = 7, SAY_HAND = 7,
SAY_WRATH = 8, SAY_WRATH = 8,
SAY_KILL = 9, SAY_KILL = 9,
SAY_MAGMABURST = 10 SAY_MAGMABURST = 10
}; };
enum Spells enum Spells
{ {
SPELL_HAND_OF_RAGNAROS = 19780, SPELL_HAND_OF_RAGNAROS = 19780,
SPELL_WRATH_OF_RAGNAROS = 20566, SPELL_WRATH_OF_RAGNAROS = 20566,
SPELL_LAVA_BURST = 21158, SPELL_LAVA_BURST = 21158,
SPELL_MAGMA_BLAST = 20565, // Ranged attack SPELL_MAGMA_BLAST = 20565, // Ranged attack
SPELL_SONS_OF_FLAME_DUMMY = 21108, // Server side effect SPELL_SONS_OF_FLAME_DUMMY = 21108, // Server side effect
SPELL_RAGSUBMERGE = 21107, // Stealth aura SPELL_RAGSUBMERGE = 21107, // Stealth aura
SPELL_RAGEMERGE = 20568, SPELL_RAGNA_SUBMERGE_VISUAL = 20567, // Visual for submerging into lava
SPELL_MELT_WEAPON = 21388, SPELL_RAGEMERGE = 20568,
SPELL_ELEMENTAL_FIRE = 20564, SPELL_MELT_WEAPON = 21387,
SPELL_ERRUPTION = 17731 SPELL_ELEMENTAL_FIRE = 20563,
SPELL_ERRUPTION = 17731,
SPELL_RAGNAROS_SUBMERGE_EFFECT = 21859, // Applies pacify state and applies all schools immunity
}; };
enum Events enum Events
{ {
EVENT_ERUPTION = 1, EVENT_ERUPTION = 1,
EVENT_WRATH_OF_RAGNAROS = 2, EVENT_WRATH_OF_RAGNAROS,
EVENT_HAND_OF_RAGNAROS = 3, EVENT_HAND_OF_RAGNAROS,
EVENT_LAVA_BURST = 4, EVENT_LAVA_BURST,
EVENT_ELEMENTAL_FIRE = 5, EVENT_MAGMA_BLAST,
EVENT_MAGMA_BLAST = 6, EVENT_SUBMERGE,
EVENT_SUBMERGE = 7,
EVENT_INTRO_1 = 8, EVENT_INTRO_1,
EVENT_INTRO_2 = 9, EVENT_INTRO_2,
EVENT_INTRO_3 = 10, EVENT_INTRO_3,
EVENT_INTRO_4 = 11, EVENT_INTRO_4,
EVENT_INTRO_5 = 12 EVENT_INTRO_5,
}; };
enum Creatures
{
NPC_SON_OF_FLAME = 12143,
};
enum Misc
{
MAX_SON_OF_FLAME_COUNT = 8,
};
constexpr float DEATH_ORIENTATION = 4.0f;
class boss_ragnaros : public CreatureScript class boss_ragnaros : public CreatureScript
{ {
public: public:
boss_ragnaros() : CreatureScript("boss_ragnaros") { } boss_ragnaros() : CreatureScript("boss_ragnaros") {}
struct boss_ragnarosAI : public BossAI struct boss_ragnarosAI : public BossAI
{ {
boss_ragnarosAI(Creature* creature) : BossAI(creature, BOSS_RAGNAROS) boss_ragnarosAI(Creature* creature) : BossAI(creature, DATA_RAGNAROS),
attackableTImer(0),
_emergeTimer(90000),
_hasYelledMagmaBurst(false),
_hasSubmergedOnce(false),
_isBanished(false)
{ {
_introState = 0; creature->SetReactState(REACT_PASSIVE);
me->SetReactState(REACT_PASSIVE); creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
} }
void Reset() override void Reset() override
{ {
BossAI::Reset(); _Reset();
_emergeTimer = 90000; _emergeTimer = 90000;
_hasYelledMagmaBurst = false; _hasYelledMagmaBurst = false;
_hasSubmergedOnce = false; _hasSubmergedOnce = false;
_isBanished = false; _isBanished = false;
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
DoCastSelf(SPELL_MELT_WEAPON, true);
DoCastSelf(SPELL_ELEMENTAL_FIRE, true);
} }
void EnterCombat(Unit* victim) override void DoAction(int32 action) override
{ {
BossAI::EnterCombat(victim); if (action == ACTION_FINISH_RAGNAROS_INTRO)
{
attackableTImer = 10000;
}
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
summons.Despawn(summon);
}
void EnterCombat(Unit* /*victim*/) override
{
_EnterCombat();
events.ScheduleEvent(EVENT_ERUPTION, 15000); events.ScheduleEvent(EVENT_ERUPTION, 15000);
events.ScheduleEvent(EVENT_WRATH_OF_RAGNAROS, 30000); events.ScheduleEvent(EVENT_WRATH_OF_RAGNAROS, 30000);
events.ScheduleEvent(EVENT_HAND_OF_RAGNAROS, 25000); events.ScheduleEvent(EVENT_HAND_OF_RAGNAROS, 25000);
events.ScheduleEvent(EVENT_LAVA_BURST, 10000); events.ScheduleEvent(EVENT_LAVA_BURST, 10000);
events.ScheduleEvent(EVENT_ELEMENTAL_FIRE, 3000);
events.ScheduleEvent(EVENT_MAGMA_BLAST, 2000); events.ScheduleEvent(EVENT_MAGMA_BLAST, 2000);
events.ScheduleEvent(EVENT_SUBMERGE, 180000); events.ScheduleEvent(EVENT_SUBMERGE, 180000);
} }
void JustDied(Unit* killer) override void JustDied(Unit* /*killer*/) override
{ {
BossAI::JustDied(killer); _JustDied();
me->SetFacingTo(DEATH_ORIENTATION); me->SetFacingTo(DEATH_ORIENTATION);
} }
void KilledUnit(Unit* /*victim*/) override void KilledUnit(Unit* victim) override
{ {
if (urand(0, 99) < 25) if (roll_chance_i(25) && victim->GetTypeId() == TYPEID_PLAYER)
{
Talk(SAY_KILL); Talk(SAY_KILL);
}
} }
void AttackStart(Unit* target) override void AttackStart(Unit* target) override
{ {
if (target && me->Attack(target, true)) if (target && me->Attack(target, true))
{
DoStartNoMovement(target); DoStartNoMovement(target);
}
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
if (_introState != 2) if (attackableTImer)
{ {
if (!_introState) if (attackableTImer <= diff)
{ {
me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); me->RemoveAurasDueToSpell(SPELL_RAGNAROS_SUBMERGE_EFFECT);
events.ScheduleEvent(EVENT_INTRO_1, 4000); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE);
events.ScheduleEvent(EVENT_INTRO_2, 23000);
events.ScheduleEvent(EVENT_INTRO_3, 42000);
events.ScheduleEvent(EVENT_INTRO_4, 43000);
events.ScheduleEvent(EVENT_INTRO_5, 53000);
_introState = 1;
}
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_INTRO_1:
Talk(SAY_ARRIVAL1_RAG);
break;
case EVENT_INTRO_2:
Talk(SAY_ARRIVAL3_RAG);
break;
case EVENT_INTRO_3:
me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H);
break;
case EVENT_INTRO_4:
Talk(SAY_ARRIVAL5_RAG);
if (Creature* executus = ObjectAccessor::GetCreature(*me, instance->GetGuidData(BOSS_MAJORDOMO_EXECUTUS)))
Unit::Kill(me, executus);
break;
case EVENT_INTRO_5:
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
_introState = 2;
break;
default:
break;
}
}
}
else
{
if (_isBanished && ((_emergeTimer <= diff) || (instance->GetData(DATA_RAGNAROS_ADDS)) > 8))
{
//Become unbanished again
me->SetReactState(REACT_AGGRESSIVE); me->SetReactState(REACT_AGGRESSIVE);
me->SetFaction(FACTION_MONSTER); DoZoneInCombat();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); attackableTImer = 0;
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
AttackStart(target);
instance->SetData(DATA_RAGNAROS_ADDS, 0);
_isBanished = false;
} }
else if (_isBanished) else
{ {
_emergeTimer -= diff; attackableTImer -= diff;
return; }
}
if (_isBanished && (_emergeTimer <= diff || !summons.HasEntry(NPC_SON_OF_FLAME)))
{
//Become unbanished again
me->SetReactState(REACT_AGGRESSIVE);
me->SetFaction(14);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{
AttackStart(target);
} }
if (!UpdateVictim()) _isBanished = false;
return; }
else if (_isBanished)
{
_emergeTimer -= diff;
return;
}
events.Update(diff); if (!UpdateVictim())
{
return;
}
while (uint32 eventId = events.ExecuteEvent()) events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
while (uint32 const eventId = events.ExecuteEvent())
{
switch (eventId)
{ {
switch (eventId) case EVENT_ERUPTION:
{ {
case EVENT_ERUPTION: DoCastVictim(SPELL_ERRUPTION);
DoCastVictim(SPELL_ERRUPTION); events.RepeatEvent(urand(20000, 45000));
events.ScheduleEvent(EVENT_ERUPTION, urand(20000, 45000)); break;
break; }
case EVENT_WRATH_OF_RAGNAROS: case EVENT_WRATH_OF_RAGNAROS:
DoCastVictim(SPELL_WRATH_OF_RAGNAROS); {
if (urand(0, 1)) DoCastVictim(SPELL_WRATH_OF_RAGNAROS);
Talk(SAY_WRATH); if (urand(0, 1))
events.ScheduleEvent(EVENT_WRATH_OF_RAGNAROS, 25000); {
break; Talk(SAY_WRATH);
case EVENT_HAND_OF_RAGNAROS: }
DoCast(me, SPELL_HAND_OF_RAGNAROS); events.RepeatEvent(25000);
if (urand(0, 1)) break;
Talk(SAY_HAND); }
events.ScheduleEvent(EVENT_HAND_OF_RAGNAROS, 20000); case EVENT_HAND_OF_RAGNAROS:
break; {
case EVENT_LAVA_BURST: DoCastSelf(SPELL_HAND_OF_RAGNAROS);
DoCastVictim(SPELL_LAVA_BURST); if (urand(0, 1))
events.ScheduleEvent(EVENT_LAVA_BURST, 10000); {
break; Talk(SAY_HAND);
case EVENT_ELEMENTAL_FIRE: }
DoCastVictim(SPELL_ELEMENTAL_FIRE); events.RepeatEvent(20000);
events.ScheduleEvent(EVENT_ELEMENTAL_FIRE, urand(10000, 14000)); break;
break; }
case EVENT_MAGMA_BLAST: case EVENT_LAVA_BURST:
if (!me->IsWithinMeleeRange(me->GetVictim())) {
DoCastVictim(SPELL_LAVA_BURST);
events.RepeatEvent(10000);
break;
}
case EVENT_MAGMA_BLAST:
{
Unit* victim = me->GetVictim();
if (victim && !me->IsWithinMeleeRange(victim))
{
DoCast(victim, SPELL_MAGMA_BLAST);
if (!_hasYelledMagmaBurst)
{ {
DoCastVictim(SPELL_MAGMA_BLAST); Talk(SAY_MAGMABURST);
if (!_hasYelledMagmaBurst) _hasYelledMagmaBurst = true;
{
Talk(SAY_MAGMABURST);
_hasYelledMagmaBurst = true;
}
} }
events.ScheduleEvent(EVENT_MAGMA_BLAST, 2500); }
break; events.RepeatEvent(2500);
case EVENT_SUBMERGE: break;
{ }
if (!_isBanished) case EVENT_SUBMERGE:
{ {
// TODO: There is a spell to summon him if (!_isBanished)
me->AttackStop(); {
DoResetThreat(); me->InterruptNonMeleeSpells(false);
me->SetReactState(REACT_PASSIVE); me->AttackStop();
me->InterruptNonMeleeSpells(false); DoResetThreat();
me->SetFaction(FACTION_FRIENDLY); me->SetReactState(REACT_PASSIVE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFaction(35);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE); me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED);
instance->SetData(DATA_RAGNAROS_ADDS, 0); DoCastSelf(SPELL_RAGNA_SUBMERGE_VISUAL, true);
//me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE);
if (!_hasSubmergedOnce) SummonMinions();
{ }
Talk(SAY_REINFORCEMENTS1); events.ScheduleEvent(EVENT_SUBMERGE, 180000);
break;
// summon 8 elementals
for (uint8 i = 0; i < 8; ++i)
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
if (Creature* summoned = me->SummonCreature(12143, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 900000))
summoned->AI()->AttackStart(target);
_hasSubmergedOnce = true;
_isBanished = true;
_emergeTimer = 90000;
}
else
{
Talk(SAY_REINFORCEMENTS2);
for (uint8 i = 0; i < 8; ++i)
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
if (Creature* summoned = me->SummonCreature(12143, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 900000))
summoned->AI()->AttackStart(target);
_isBanished = true;
_emergeTimer = 90000;
}
}
events.ScheduleEvent(EVENT_SUBMERGE, 180000);
break;
}
default:
break;
} }
} }
DoMeleeAttackIfReady(); if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
}
} }
DoMeleeAttackIfReady();
} }
private: private:
float const DEATH_ORIENTATION = 4.0f; uint32 attackableTImer; // used after intro
uint32 _emergeTimer; uint32 _emergeTimer;
uint8 _introState;
bool _hasYelledMagmaBurst; bool _hasYelledMagmaBurst;
bool _hasSubmergedOnce; bool _hasSubmergedOnce;
bool _isBanished; bool _isBanished;
void SummonMinions()
{
Talk(_hasSubmergedOnce ? SAY_REINFORCEMENTS2 : SAY_REINFORCEMENTS1);
for (uint8 i = 0; i < MAX_SON_OF_FLAME_COUNT; ++i)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{
if (Creature* summoned = me->SummonCreature(NPC_SON_OF_FLAME, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 900000))
{
summoned->AI()->AttackStart(target);
}
}
}
_isBanished = true;
_emergeTimer = 90000;
if (!_hasSubmergedOnce)
{
_hasSubmergedOnce = true;
}
}
}; };
CreatureAI* GetAI(Creature* creature) const override CreatureAI* GetAI(Creature* creature) const override
@@ -306,40 +321,7 @@ public:
} }
}; };
class npc_son_of_flame : public CreatureScript
{
public:
npc_son_of_flame() : CreatureScript("npc_SonOfFlame") { }
struct npc_son_of_flameAI : public ScriptedAI
{
npc_son_of_flameAI(Creature* creature) : ScriptedAI(creature)
{
instance = me->GetInstanceScript();
}
void JustDied(Unit* /*killer*/) override { instance->SetData(DATA_RAGNAROS_ADDS, 1); }
void UpdateAI(uint32 /*diff*/) override
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
private:
InstanceScript* instance;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetMoltenCoreAI<npc_son_of_flameAI>(creature);
}
};
void AddSC_boss_ragnaros() void AddSC_boss_ragnaros()
{ {
new boss_ragnaros(); new boss_ragnaros();
new npc_son_of_flame();
} }
@@ -15,29 +15,29 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "molten_core.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h" #include "SpellScript.h"
#include "molten_core.h"
#include "Player.h"
enum Spells enum Spells
{ {
SPELL_ARCANE_EXPLOSION = 19712, SPELL_ARCANE_EXPLOSION = 19712,
SPELL_SHAZZRAH_CURSE = 19713, SPELL_SHAZZRAH_CURSE = 19713,
SPELL_MAGIC_GROUNDING = 19714, SPELL_MAGIC_GROUNDING = 19714,
SPELL_COUNTERSPELL = 19715, SPELL_COUNTERSPELL = 19715,
SPELL_SHAZZRAH_GATE_DUMMY = 23138, // Teleports to and attacks a random target. SPELL_SHAZZRAH_GATE_DUMMY = 23138, // Teleports to and attacks a random target. About every 45 seconds Shazzrah will blink to random target causing a wipe of the threat list (source: wowwwiki)
SPELL_SHAZZRAH_GATE = 23139, SPELL_SHAZZRAH_GATE = 23139,
}; };
enum Events enum Events
{ {
EVENT_ARCANE_EXPLOSION = 1, EVENT_ARCANE_EXPLOSION = 1,
EVENT_ARCANE_EXPLOSION_TRIGGERED = 2, EVENT_SHAZZRAH_CURSE,
EVENT_SHAZZRAH_CURSE = 3, EVENT_MAGIC_GROUNDING,
EVENT_MAGIC_GROUNDING = 4, EVENT_COUNTERSPELL,
EVENT_COUNTERSPELL = 5, EVENT_SHAZZRAH_GATE,
EVENT_SHAZZRAH_GATE = 6,
}; };
class boss_shazzrah : public CreatureScript class boss_shazzrah : public CreatureScript
@@ -47,66 +47,57 @@ public:
struct boss_shazzrahAI : public BossAI struct boss_shazzrahAI : public BossAI
{ {
boss_shazzrahAI(Creature* creature) : BossAI(creature, BOSS_SHAZZRAH) { } boss_shazzrahAI(Creature* creature) : BossAI(creature, DATA_SHAZZRAH) {}
void EnterCombat(Unit* target) override void EnterCombat(Unit* /*target*/) override
{ {
BossAI::EnterCombat(target); _EnterCombat();
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, 6000); events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(2000, 4000));
events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, 10000); events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, urand(7000, 11000));
events.ScheduleEvent(EVENT_MAGIC_GROUNDING, 24000); events.ScheduleEvent(EVENT_MAGIC_GROUNDING, urand(14000, 19000));
events.ScheduleEvent(EVENT_COUNTERSPELL, 15000); events.ScheduleEvent(EVENT_COUNTERSPELL, urand(9000, 10000));
events.ScheduleEvent(EVENT_SHAZZRAH_GATE, 45000); events.ScheduleEvent(EVENT_SHAZZRAH_GATE, 30000);
} }
void UpdateAI(uint32 diff) override void ExecuteEvent(uint32 eventId) override
{ {
if (!UpdateVictim()) switch (eventId)
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{ {
switch (eventId) case EVENT_ARCANE_EXPLOSION:
{ {
case EVENT_ARCANE_EXPLOSION: DoCastVictim(SPELL_ARCANE_EXPLOSION);
DoCastVictim(SPELL_ARCANE_EXPLOSION); events.RepeatEvent(urand(4000, 5000));
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(4000, 7000)); break;
break; }
// Triggered subsequent to using "Gate of Shazzrah". case EVENT_SHAZZRAH_CURSE:
case EVENT_ARCANE_EXPLOSION_TRIGGERED: {
DoCastVictim(SPELL_ARCANE_EXPLOSION); if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_SHAZZRAH_CURSE))
break; {
case EVENT_SHAZZRAH_CURSE: DoCast(target, SPELL_SHAZZRAH_CURSE);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_SHAZZRAH_CURSE)) }
DoCast(target, SPELL_SHAZZRAH_CURSE); events.RepeatEvent(urand(23000, 26000));
events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, urand(25000, 30000)); break;
break; }
case EVENT_MAGIC_GROUNDING: case EVENT_MAGIC_GROUNDING:
DoCast(me, SPELL_MAGIC_GROUNDING); {
events.ScheduleEvent(EVENT_MAGIC_GROUNDING, 35000); DoCastSelf(SPELL_MAGIC_GROUNDING);
break; events.RepeatEvent(urand(7000, 9000));
case EVENT_COUNTERSPELL: break;
DoCastVictim(SPELL_COUNTERSPELL); }
events.ScheduleEvent(EVENT_COUNTERSPELL, urand(16000, 20000)); case EVENT_COUNTERSPELL:
break; {
case EVENT_SHAZZRAH_GATE: DoCastAOE(SPELL_COUNTERSPELL);
DoResetThreat(); events.RepeatEvent(urand(15000, 18000));
DoCastAOE(SPELL_SHAZZRAH_GATE_DUMMY); break;
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION_TRIGGERED, 2000); }
events.RescheduleEvent(EVENT_ARCANE_EXPLOSION, urand(3000, 6000)); case EVENT_SHAZZRAH_GATE:
events.ScheduleEvent(EVENT_SHAZZRAH_GATE, 45000); {
break; DoCastAOE(SPELL_SHAZZRAH_GATE_DUMMY);
default: events.RescheduleEvent(EVENT_ARCANE_EXPLOSION, urand(3000, 6000));
break; events.RepeatEvent(45000);
break;
} }
} }
DoMeleeAttackIfReady();
} }
}; };
@@ -120,7 +111,7 @@ public:
class spell_shazzrah_gate_dummy : public SpellScriptLoader class spell_shazzrah_gate_dummy : public SpellScriptLoader
{ {
public: public:
spell_shazzrah_gate_dummy() : SpellScriptLoader("spell_shazzrah_gate_dummy") { } spell_shazzrah_gate_dummy() : SpellScriptLoader("spell_shazzrah_gate_dummy") {}
class spell_shazzrah_gate_dummy_SpellScript : public SpellScript class spell_shazzrah_gate_dummy_SpellScript : public SpellScript
{ {
@@ -133,21 +124,55 @@ public:
void FilterTargets(std::list<WorldObject*>& targets) void FilterTargets(std::list<WorldObject*>& targets)
{ {
if (targets.empty()) Unit* caster = GetCaster();
return; if (!targets.empty())
{
targets.remove_if([caster](WorldObject const* target) -> bool
{
Player const* plrTarget = target->ToPlayer();
// Should not target non player targets
if (!plrTarget)
{
return true;
}
WorldObject* target = Acore::Containers::SelectRandomContainerElement(targets); // Should skip current victim
targets.clear(); if (caster->GetVictim() == plrTarget)
targets.push_back(target); {
return true;
}
// Should not target enemies within melee range
if (plrTarget->IsWithinDistInMap(caster, caster->GetMeleeRange(plrTarget)))
{
return true;
}
return false;
});
}
if (!targets.empty())
{
Acore::Containers::RandomResize(targets, 1);
}
} }
void HandleScript(SpellEffIndex /*effIndex*/) void HandleScript(SpellEffIndex /*effIndex*/)
{ {
if (Unit* target = GetHitUnit()) Unit* caster = GetCaster();
Unit* target = GetHitUnit();
if (!caster || !target)
{ {
target->CastSpell(GetCaster(), SPELL_SHAZZRAH_GATE, true); target->CastSpell(caster, SPELL_SHAZZRAH_GATE, true, nullptr, nullptr, caster->GetGUID());
if (Creature* creature = GetCaster()->ToCreature()) caster->CastSpell(caster, SPELL_ARCANE_EXPLOSION);
creature->AI()->AttackStart(target); // Attack the target which caster will teleport to.
if (Creature* creatureCaster = caster->ToCreature())
{
creatureCaster->getThreatMgr().resetAllAggro();
creatureCaster->AI()->AttackStart(target); // Attack the target which caster will teleport to.
}
} }
} }
@@ -167,5 +192,7 @@ public:
void AddSC_boss_shazzrah() void AddSC_boss_shazzrah()
{ {
new boss_shazzrah(); new boss_shazzrah();
// Spells
new spell_shazzrah_gate_dummy(); new spell_shazzrah_gate_dummy();
} }
@@ -15,17 +15,9 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Sulfuron_Harbringer
SD%Complete: 80
SDComment: Adds NYI
SDCategory: Molten Core
EndScriptData */
#include "molten_core.h"
#include "ObjectMgr.h"
#include "ScriptedCreature.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "molten_core.h"
enum Spells enum Spells
{ {
@@ -45,84 +37,79 @@ enum Spells
enum Events enum Events
{ {
EVENT_DARK_STRIKE = 1, EVENT_DARK_STRIKE = 1,
EVENT_DEMORALIZING_SHOUT = 2, EVENT_DEMORALIZING_SHOUT,
EVENT_INSPIRE = 3, EVENT_INSPIRE,
EVENT_KNOCKDOWN = 4, EVENT_KNOCKDOWN,
EVENT_FLAMESPEAR = 5, EVENT_FLAMESPEAR,
EVENT_HEAL = 6, EVENT_HEAL,
EVENT_SHADOW_WORD_PAIN = 7, EVENT_SHADOW_WORD_PAIN,
EVENT_IMMOLATE = 8, EVENT_IMMOLATE,
}; };
class boss_sulfuron : public CreatureScript class boss_sulfuron : public CreatureScript
{ {
public: public:
boss_sulfuron() : CreatureScript("boss_sulfuron") { } boss_sulfuron() : CreatureScript("boss_sulfuron") {}
struct boss_sulfuronAI : public BossAI struct boss_sulfuronAI : public BossAI
{ {
boss_sulfuronAI(Creature* creature) : BossAI(creature, BOSS_SULFURON_HARBINGER) boss_sulfuronAI(Creature* creature) : BossAI(creature, DATA_SULFURON) {}
{
}
void EnterCombat(Unit* victim) override void EnterCombat(Unit* /*victim*/) override
{ {
BossAI::EnterCombat(victim); _EnterCombat();
events.ScheduleEvent(EVENT_DARK_STRIKE, 10000); events.ScheduleEvent(EVENT_DARK_STRIKE, urand(4000, 7000));
events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, 15000); events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, urand(6000, 20000));
events.ScheduleEvent(EVENT_INSPIRE, 13000); events.ScheduleEvent(EVENT_INSPIRE, urand(7000, 10000));
events.ScheduleEvent(EVENT_KNOCKDOWN, 6000); events.ScheduleEvent(EVENT_KNOCKDOWN, 6000);
events.ScheduleEvent(EVENT_FLAMESPEAR, 2000); events.ScheduleEvent(EVENT_FLAMESPEAR, 2000);
} }
void UpdateAI(uint32 diff) override void ExecuteEvent(uint32 eventId) override
{ {
if (!UpdateVictim()) switch (eventId)
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = events.ExecuteEvent())
{ {
switch (eventId) case EVENT_DARK_STRIKE:
{ {
case EVENT_DARK_STRIKE: DoCastSelf(SPELL_DARK_STRIKE);
DoCast(me, SPELL_DARK_STRIKE); events.RepeatEvent(urand(4000, 7000));
events.ScheduleEvent(EVENT_DARK_STRIKE, urand(15000, 18000)); break;
break; }
case EVENT_DEMORALIZING_SHOUT: case EVENT_DEMORALIZING_SHOUT:
DoCastVictim(SPELL_DEMORALIZING_SHOUT); {
events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, urand(15000, 20000)); DoCastVictim(SPELL_DEMORALIZING_SHOUT);
break; events.RepeatEvent(urand(12000, 18000));
case EVENT_INSPIRE: break;
{ }
std::list<Creature*> healers = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE); case EVENT_INSPIRE:
if (!healers.empty()) {
DoCast(Acore::Containers::SelectRandomContainerElement(healers), SPELL_INSPIRE); std::list<Creature*> healers = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE);
if (!healers.empty())
{
DoCast(Acore::Containers::SelectRandomContainerElement(healers), SPELL_INSPIRE);
}
DoCast(me, SPELL_INSPIRE); DoCastSelf(SPELL_INSPIRE);
events.ScheduleEvent(EVENT_INSPIRE, urand(20000, 26000)); events.RepeatEvent(urand(13000, 20000));
break; break;
} }
case EVENT_KNOCKDOWN: case EVENT_KNOCKDOWN:
DoCastVictim(SPELL_KNOCKDOWN); {
events.ScheduleEvent(EVENT_KNOCKDOWN, urand(12000, 15000)); DoCastVictim(SPELL_KNOCKDOWN);
break; events.RepeatEvent(urand(10000, 20000));
case EVENT_FLAMESPEAR: break;
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) }
DoCast(target, SPELL_FLAMESPEAR); case EVENT_FLAMESPEAR:
events.ScheduleEvent(EVENT_FLAMESPEAR, urand(12000, 16000)); {
break; if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
default: {
break; DoCast(target, SPELL_FLAMESPEAR);
}
events.RepeatEvent(urand(12000, 16000));
break;
} }
} }
DoMeleeAttackIfReady();
} }
}; };
@@ -135,13 +122,11 @@ public:
class npc_flamewaker_priest : public CreatureScript class npc_flamewaker_priest : public CreatureScript
{ {
public: public:
npc_flamewaker_priest() : CreatureScript("npc_flamewaker_priest") { } npc_flamewaker_priest() : CreatureScript("npc_flamewaker_priest") {}
struct npc_flamewaker_priestAI : public ScriptedAI struct npc_flamewaker_priestAI : public ScriptedAI
{ {
npc_flamewaker_priestAI(Creature* creature) : ScriptedAI(creature) npc_flamewaker_priestAI(Creature* creature) : ScriptedAI(creature) {}
{
}
void Reset() override void Reset() override
{ {
@@ -153,45 +138,63 @@ public:
events.Reset(); events.Reset();
} }
void EnterCombat(Unit* victim) override void EnterCombat(Unit* /*victim*/) override
{ {
ScriptedAI::EnterCombat(victim);
events.ScheduleEvent(EVENT_HEAL, urand(15000, 30000)); events.ScheduleEvent(EVENT_HEAL, urand(15000, 30000));
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 2000); events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(2000, 4000));
events.ScheduleEvent(EVENT_IMMOLATE, 8000); events.ScheduleEvent(EVENT_IMMOLATE, urand(3500, 6000));
} }
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
if (!UpdateVictim()) if (!UpdateVictim())
{
return; return;
}
events.Update(diff); events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING)) if (me->HasUnitState(UNIT_STATE_CASTING))
{
return; return;
}
while (uint32 eventId = events.ExecuteEvent()) while (uint32 const eventId = events.ExecuteEvent())
{ {
switch (eventId) switch (eventId)
{ {
case EVENT_HEAL: case EVENT_HEAL:
{
if (Unit* target = DoSelectLowestHpFriendly(60.0f, 1)) if (Unit* target = DoSelectLowestHpFriendly(60.0f, 1))
{
DoCast(target, SPELL_HEAL); DoCast(target, SPELL_HEAL);
events.ScheduleEvent(EVENT_HEAL, urand(15000, 20000)); }
events.RepeatEvent(urand(15000, 20000));
break; break;
}
case EVENT_SHADOW_WORD_PAIN: case EVENT_SHADOW_WORD_PAIN:
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_SHADOWWORDPAIN)) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_SHADOWWORDPAIN))
{
DoCast(target, SPELL_SHADOWWORDPAIN); DoCast(target, SPELL_SHADOWWORDPAIN);
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(18000, 26000)); }
events.RepeatEvent(urand(2500, 5000));
break; break;
}
case EVENT_IMMOLATE: case EVENT_IMMOLATE:
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_IMMOLATE)) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_IMMOLATE))
{
DoCast(target, SPELL_IMMOLATE); DoCast(target, SPELL_IMMOLATE);
events.ScheduleEvent(EVENT_IMMOLATE, urand(15000, 25000)); }
break; events.RepeatEvent(urand(5000, 7000));
default:
break; break;
}
}
if (me->HasUnitState(UNIT_STATE_CASTING))
{
return;
} }
} }
@@ -15,51 +15,64 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData #include "ScriptMgr.h"
SDName: Instance_Molten_Core
SD%Complete: 0
SDComment: Place Holder
SDCategory: Molten Core
EndScriptData */
#include "InstanceScript.h" #include "InstanceScript.h"
#include "molten_core.h"
#include "ObjectMgr.h" #include "ObjectMgr.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "InstanceScript.h"
#include "TemporarySummon.h" #include "TemporarySummon.h"
#include "molten_core.h"
Position const SummonPositions[10] = MinionData const minionData[] =
{ {
{759.542f, -1173.43f, -118.974f, 3.3048f}, { NPC_FIRESWORN, DATA_GARR },
{761.652f, -1164.30f, -119.533f, 3.3919f}, { NPC_FLAMEWALKER, DATA_GEHENNAS },
{747.323f, -1149.24f, -120.060f, 3.6629f}, { NPC_FLAMEWALKER_PROTECTOR, DATA_LUCIFRON },
{766.734f, -1183.16f, -119.292f, 2.9889f}, { NPC_FLAMEWALKER_PRIEST, DATA_SULFURON },
{757.364f, -1198.31f, -118.652f, 2.3095f}, { NPC_FLAMEWALKER_HEALER, DATA_MAJORDOMO_EXECUTUS },
{752.349f, -1159.19f, -119.261f, 3.6032f}, { NPC_FLAMEWALKER_ELITE, DATA_MAJORDOMO_EXECUTUS },
{738.015f, -1152.22f, -119.512f, 4.0792f}, { 0, 0 } // END
{757.246f, -1189.79f, -118.633f, 2.5333f}, };
{745.916f, -1199.35f, -118.119f, 1.8932f},
{838.510f, -829.840f, -232.000f, 2.00000f}, struct MCBossObject
{
uint32 bossId;
uint32 runeId;
uint32 circleId;
};
constexpr uint8 MAX_MC_LINKED_BOSS_OBJ = 7;
MCBossObject const linkedBossObjData[MAX_MC_LINKED_BOSS_OBJ]=
{
{ DATA_MAGMADAR, GO_RUNE_KRESS, GO_CIRCLE_MAGMADAR },
{ DATA_GEHENNAS, GO_RUNE_MOHN, GO_CIRCLE_GEHENNAS },
{ DATA_GARR, GO_RUNE_BLAZ, GO_CIRCLE_GARR },
{ DATA_SHAZZRAH, GO_RUNE_MAZJ, GO_CIRCLE_SHAZZRAH },
{ DATA_GEDDON, GO_RUNE_ZETH, GO_CIRCLE_GEDDON },
{ DATA_GOLEMAGG, GO_RUNE_THERI, GO_CIRCLE_GOLEMAGG },
{ DATA_SULFURON, GO_RUNE_KORO, GO_CIRCLE_SULFURON },
}; };
class instance_molten_core : public InstanceMapScript class instance_molten_core : public InstanceMapScript
{ {
public: public:
instance_molten_core() : InstanceMapScript("instance_molten_core", 409) { } instance_molten_core() : InstanceMapScript(MCScriptName, 409) {}
struct instance_molten_core_InstanceMapScript : public InstanceScript struct instance_molten_core_InstanceMapScript : public InstanceScript
{ {
instance_molten_core_InstanceMapScript(Map* map) : InstanceScript(map) instance_molten_core_InstanceMapScript(Map* map) : InstanceScript(map)
{ {
SetBossNumber(MAX_ENCOUNTER); SetBossNumber(MAX_ENCOUNTER);
_deadBossCount = 0; LoadMinionData(minionData);
_ragnarosAddDeaths = 0;
} }
void OnPlayerEnter(Player* /*player*/) override void OnPlayerEnter(Player* /*player*/) override
{ {
if (CheckMajordomoExecutus()) if (CheckMajordomoExecutus())
{
SummonMajordomoExecutus(); SummonMajordomoExecutus();
}
} }
void OnCreatureCreate(Creature* creature) override void OnCreatureCreate(Creature* creature) override
@@ -67,13 +80,61 @@ public:
switch (creature->GetEntry()) switch (creature->GetEntry())
{ {
case NPC_GOLEMAGG_THE_INCINERATOR: case NPC_GOLEMAGG_THE_INCINERATOR:
_golemaggTheIncineratorGUID = creature->GetGUID(); {
_golemaggGUID = creature->GetGUID();
break; break;
}
case NPC_CORE_RAGER:
{
_golemaggMinionsGUIDS.insert(creature->GetGUID());
break;
}
case NPC_MAJORDOMO_EXECUTUS: case NPC_MAJORDOMO_EXECUTUS:
{
_majordomoExecutusGUID = creature->GetGUID(); _majordomoExecutusGUID = creature->GetGUID();
break; break;
default: }
case NPC_GARR:
{
_garrGUID = creature->GetGUID();
break; break;
}
case NPC_RAGNAROS:
{
_ragnarosGUID = creature->GetGUID();
break;
}
case NPC_FIRESWORN:
case NPC_FLAMEWALKER:
case NPC_FLAMEWALKER_PROTECTOR:
case NPC_FLAMEWALKER_PRIEST:
case NPC_FLAMEWALKER_HEALER:
case NPC_FLAMEWALKER_ELITE:
{
AddMinion(creature, true);
break;
}
}
}
void OnCreatureRemove(Creature* creature) override
{
switch (creature->GetEntry())
{
case NPC_FIRESWORN:
{
AddMinion(creature, false);
break;
}
case NPC_FLAMEWALKER:
case NPC_FLAMEWALKER_PROTECTOR:
case NPC_FLAMEWALKER_PRIEST:
case NPC_FLAMEWALKER_HEALER:
case NPC_FLAMEWALKER_ELITE:
{
AddMinion(creature, false);
break;
}
} }
} }
@@ -82,64 +143,92 @@ public:
switch (go->GetEntry()) switch (go->GetEntry())
{ {
case GO_CACHE_OF_THE_FIRELORD: case GO_CACHE_OF_THE_FIRELORD:
{
_cacheOfTheFirelordGUID = go->GetGUID(); _cacheOfTheFirelordGUID = go->GetGUID();
break; break;
case GO_CIRCLE_BARON: }
_circlesGUIDs[5] = go->GetGUID(); case GO_CIRCLE_GEDDON:
break;
case GO_CIRCLE_GARR: case GO_CIRCLE_GARR:
_circlesGUIDs[3] = go->GetGUID();
break;
case GO_CIRCLE_GEHENNAS: case GO_CIRCLE_GEHENNAS:
_circlesGUIDs[2] = go->GetGUID();
break;
case GO_CIRCLE_GOLEMAGG: case GO_CIRCLE_GOLEMAGG:
_circlesGUIDs[7] = go->GetGUID();
break;
case GO_CIRCLE_MAGMADAR: case GO_CIRCLE_MAGMADAR:
_circlesGUIDs[1] = go->GetGUID();
break;
case GO_CIRCLE_SHAZZRAH: case GO_CIRCLE_SHAZZRAH:
_circlesGUIDs[4] = go->GetGUID();
break;
case GO_CIRCLE_SULFURON: case GO_CIRCLE_SULFURON:
_circlesGUIDs[6] = go->GetGUID(); {
for (uint8 i = 0; i < MAX_MC_LINKED_BOSS_OBJ; ++i)
{
if (linkedBossObjData[i].circleId != go->GetEntry())
{
continue;
}
if (GetBossState(linkedBossObjData[i].bossId) == DONE)
{
go->DespawnOrUnsummon();
}
else
{
_circlesGUIDs[linkedBossObjData[i].bossId] = go->GetGUID();
}
}
break; break;
default: }
case GO_RUNE_KRESS:
case GO_RUNE_MOHN:
case GO_RUNE_BLAZ:
case GO_RUNE_MAZJ:
case GO_RUNE_ZETH:
case GO_RUNE_THERI:
case GO_RUNE_KORO:
{
for (uint8 i = 0; i < MAX_MC_LINKED_BOSS_OBJ; ++i)
{
if (linkedBossObjData[i].runeId != go->GetEntry())
{
continue;
}
if (GetBossState(linkedBossObjData[i].bossId) == DONE)
{
go->SetGoState(GO_STATE_ACTIVE);
}
else
{
_runesGUIDs[linkedBossObjData[i].bossId] = go->GetGUID();
}
}
break; break;
}
case GO_LAVA_STEAM:
{
_lavaSteamGUID = go->GetGUID();
break;
}
case GO_LAVA_SPLASH:
{
_lavaSplashGUID = go->GetGUID();
break;
}
} }
} }
void SetData(uint32 type, uint32 data) override ObjectGuid GetGuidData(uint32 type) const override
{
if (type == DATA_RAGNAROS_ADDS)
{
if (data == 1)
++_ragnarosAddDeaths;
else if (data == 0)
_ragnarosAddDeaths = 0;
}
}
uint32 GetData(uint32 type) const override
{ {
switch (type) switch (type)
{ {
case DATA_RAGNAROS_ADDS: case DATA_GOLEMAGG:
return _ragnarosAddDeaths; return _golemaggGUID;
} case DATA_MAJORDOMO_EXECUTUS:
return 0;
}
ObjectGuid GetGuidData(uint32 type) const override
{
switch (type)
{
case BOSS_GOLEMAGG_THE_INCINERATOR:
return _golemaggTheIncineratorGUID;
case BOSS_MAJORDOMO_EXECUTUS:
return _majordomoExecutusGUID; return _majordomoExecutusGUID;
case DATA_GARR:
return _garrGUID;
case DATA_LAVA_STEAM:
return _lavaSteamGUID;
case DATA_LAVA_SPLASH:
return _lavaSplashGUID;
case DATA_RAGNAROS:
return _ragnarosGUID;
} }
return ObjectGuid::Empty; return ObjectGuid::Empty;
@@ -148,54 +237,153 @@ public:
bool SetBossState(uint32 bossId, EncounterState state) override bool SetBossState(uint32 bossId, EncounterState state) override
{ {
if (!InstanceScript::SetBossState(bossId, state)) if (!InstanceScript::SetBossState(bossId, state))
{
return false; return false;
}
if (state == DONE && bossId < BOSS_MAJORDOMO_EXECUTUS) if (bossId == DATA_MAJORDOMO_EXECUTUS && state == DONE)
if (CheckMajordomoExecutus())
SummonMajordomoExecutus();
if (bossId == BOSS_MAJORDOMO_EXECUTUS && state == DONE)
{ {
DoRespawnGameObject(_cacheOfTheFirelordGUID, 7 * DAY); DoRespawnGameObject(_cacheOfTheFirelordGUID, 7 * DAY);
} }
else if (bossId == DATA_GOLEMAGG)
{
switch (state)
{
case NOT_STARTED:
case FAIL:
{
if (!_golemaggMinionsGUIDS.empty())
{
for (ObjectGuid const& minionGuid : _golemaggMinionsGUIDS)
{
Creature* minion = instance->GetCreature(minionGuid);
if (minion && minion->isDead())
{
minion->Respawn();
}
}
}
break;
}
case IN_PROGRESS:
{
if (!_golemaggMinionsGUIDS.empty())
{
for (ObjectGuid const& minionGuid : _golemaggMinionsGUIDS)
{
if (Creature* minion = instance->GetCreature(minionGuid))
{
minion->AI()->DoZoneInCombat(nullptr, 150.0f);
}
}
}
break;
}
case DONE:
{
if (!_golemaggMinionsGUIDS.empty())
{
for (ObjectGuid const& minionGuid : _golemaggMinionsGUIDS)
{
if (Creature* minion = instance->GetCreature(minionGuid))
{
minion->CastSpell(minion, SPELL_CORE_RAGER_QUIET_SUICIDE, true);
}
}
_golemaggMinionsGUIDS.clear();
}
break;
}
default:
break;
}
}
// Perform needed checks for Majordomu
if (bossId < DATA_MAJORDOMO_EXECUTUS && state == DONE)
{
if (GameObject* circle = instance->GetGameObject(_circlesGUIDs[bossId]))
{
circle->DespawnOrUnsummon();
_circlesGUIDs[bossId].Clear();
}
if (GameObject* rune = instance->GetGameObject(_runesGUIDs[bossId]))
{
rune->SetGoState(GO_STATE_ACTIVE);
_runesGUIDs[bossId].Clear();
}
if (CheckMajordomoExecutus())
{
SummonMajordomoExecutus();
}
}
return true; return true;
} }
void DoAction(int32 action) override
{
if (action == ACTION_RESET_MAGMADAR_ENCOUNTER)
{
if (Creature* golemagg = instance->GetCreature(_golemaggGUID))
{
golemagg->AI()->EnterEvadeMode();
}
if (!_golemaggMinionsGUIDS.empty())
{
for (ObjectGuid const& minionGuid : _golemaggMinionsGUIDS)
{
if (Creature* minion = instance->GetCreature(minionGuid))
{
minion->AI()->EnterEvadeMode();
}
}
}
}
}
void SummonMajordomoExecutus() void SummonMajordomoExecutus()
{ {
if (_majordomoExecutusGUID) if (instance->GetCreature(_majordomoExecutusGUID))
return;
if (GetBossState(BOSS_MAJORDOMO_EXECUTUS) != DONE)
{ {
instance->SummonCreature(NPC_MAJORDOMO_EXECUTUS, SummonPositions[0]); return;
instance->SummonCreature(NPC_FLAMEWAKER_HEALER, SummonPositions[1]);
instance->SummonCreature(NPC_FLAMEWAKER_HEALER, SummonPositions[2]);
instance->SummonCreature(NPC_FLAMEWAKER_HEALER, SummonPositions[3]);
instance->SummonCreature(NPC_FLAMEWAKER_HEALER, SummonPositions[4]);
instance->SummonCreature(NPC_FLAMEWAKER_ELITE, SummonPositions[5]);
instance->SummonCreature(NPC_FLAMEWAKER_ELITE, SummonPositions[6]);
instance->SummonCreature(NPC_FLAMEWAKER_ELITE, SummonPositions[7]);
instance->SummonCreature(NPC_FLAMEWAKER_ELITE, SummonPositions[8]);
} }
else if (TempSummon* summon = instance->SummonCreature(NPC_MAJORDOMO_EXECUTUS, RagnarosTelePos))
summon->AI()->DoAction(ACTION_START_RAGNAROS_ALT); instance->SummonCreature(NPC_MAJORDOMO_EXECUTUS, GetBossState(DATA_MAJORDOMO_EXECUTUS) != DONE ? MajordomoSummonPos : MajordomoRagnaros);
} }
bool CheckMajordomoExecutus() const bool CheckMajordomoExecutus() const
{ {
if (GetBossState(BOSS_RAGNAROS) == DONE) if (GetBossState(DATA_RAGNAROS) == DONE)
{
return false; return false;
}
for (uint8 i = 0; i < DATA_MAJORDOMO_EXECUTUS; ++i)
{
if (i == DATA_LUCIFRON)
{
continue;
}
for (uint8 i = 0; i < BOSS_MAJORDOMO_EXECUTUS; ++i)
if (GetBossState(i) != DONE) if (GetBossState(i) != DONE)
{
return false; return false;
}
}
// Prevent spawning if Ragnaros is present
if (instance->GetCreature(_ragnarosGUID))
{
return false;
}
return true; return true;
} }
std::string GetSaveData() override std::string GetSaveData() override
{ {
OUT_SAVE_INST_DATA; OUT_SAVE_INST_DATA;
@@ -206,7 +394,7 @@ public:
return saveStream.str(); return saveStream.str();
} }
void Load(char const* data) override void Load(char const* data) override
{ {
if (!data) if (!data)
{ {
@@ -228,27 +416,43 @@ public:
uint32 tmpState; uint32 tmpState;
loadStream >> tmpState; loadStream >> tmpState;
if (tmpState == IN_PROGRESS || tmpState > TO_BE_DECIDED) if (tmpState == IN_PROGRESS || tmpState > TO_BE_DECIDED)
{
tmpState = NOT_STARTED; tmpState = NOT_STARTED;
}
SetBossState(i, EncounterState(tmpState)); SetBossState(i, static_cast<EncounterState>(tmpState));
} }
if (CheckMajordomoExecutus()) if (CheckMajordomoExecutus())
{
SummonMajordomoExecutus(); SummonMajordomoExecutus();
}
} }
else else
{
OUT_LOAD_INST_DATA_FAIL; OUT_LOAD_INST_DATA_FAIL;
}
OUT_LOAD_INST_DATA_COMPLETE; OUT_LOAD_INST_DATA_COMPLETE;
} }
private: private:
ObjectGuid _golemaggTheIncineratorGUID; std::unordered_map<uint32/*bossid*/, ObjectGuid/*circleGUID*/> _circlesGUIDs;
std::unordered_map<uint32/*bossid*/, ObjectGuid/*runeGUID*/> _runesGUIDs;
// Golemagg encounter related
ObjectGuid _golemaggGUID;
GuidSet _golemaggMinionsGUIDS;
// Ragnaros encounter related
ObjectGuid _ragnarosGUID;
ObjectGuid _lavaSteamGUID;
ObjectGuid _lavaSplashGUID;
ObjectGuid _majordomoExecutusGUID; ObjectGuid _majordomoExecutusGUID;
ObjectGuid _cacheOfTheFirelordGUID; ObjectGuid _cacheOfTheFirelordGUID;
uint8 _deadBossCount; ObjectGuid _garrGUID;
uint8 _ragnarosAddDeaths; ObjectGuid _magmadarGUID;
std::unordered_map<uint8, ObjectGuid> _circlesGUIDs;
}; };
InstanceScript* GetInstanceScript(InstanceMap* map) const override InstanceScript* GetInstanceScript(InstanceMap* map) const override
@@ -0,0 +1,216 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 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 Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "molten_core.h"
enum Texts
{
EMOTE_SMOLDERING = 0,
EMOTE_IGNITE = 1,
};
enum Spells
{
// Ancient Core Hound
SPELL_SERRATED_BITE = 19771,
SPELL_PLAY_DEAD = 19822,
SPELL_FULL_HEALTH = 17683,
SPELL_FIRE_NOVA_VISUAL = 19823,
SPELL_PLAY_DEAD_PACIFY = 19951, // Server side spell
};
// Serrated Bites timer may be wrong
class npc_mc_core_hound : public CreatureScript
{
public:
npc_mc_core_hound() : CreatureScript("npc_mc_core_hound") {}
struct npc_mc_core_houndAI : public CreatureAI
{
npc_mc_core_houndAI(Creature* creature) :
CreatureAI(creature),
instance(creature->GetInstanceScript()),
serratedBiteTimer(3000)
{
}
void Reset() override
{
serratedBiteTimer = 3000;
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damagetype*/, SpellSchoolMask /*damageSchoolMask*/) override
{
// Prevent receiving any extra damage if Hound is playing dead
if (me->HasAura(SPELL_PLAY_DEAD))
{
damage = 0;
return;
}
else if (me->GetHealth() <= damage)
{
damage = 0;
Talk(EMOTE_SMOLDERING);
DoCastSelf(SPELL_PLAY_DEAD);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
{
return;
}
if (me->HasUnitState(UNIT_STATE_CASTING) || me->HasAura(SPELL_PLAY_DEAD))
{
return;
}
if (serratedBiteTimer <= diff)
{
DoCastVictim(SPELL_SERRATED_BITE);
serratedBiteTimer = urand(5000, 6000);
}
else
{
serratedBiteTimer -= diff;
}
DoMeleeAttackIfReady();
}
private:
InstanceScript* instance;
uint32 serratedBiteTimer;
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetMoltenCoreAI<npc_mc_core_houndAI>(creature);
}
};
// 19822 Play Dead
class spell_mc_play_dead : public SpellScriptLoader
{
public:
spell_mc_play_dead() : SpellScriptLoader("spell_mc_play_dead") { }
class spell_mc_play_dead_AuraScript : public AuraScript
{
PrepareAuraScript(spell_mc_play_dead_AuraScript);
bool Load() override
{
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* creatureTarget = GetTarget()->ToCreature();
if (!creatureTarget)
{
return;
}
creatureTarget->CastSpell(creatureTarget, SPELL_PLAY_DEAD_PACIFY, true);
creatureTarget->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
creatureTarget->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
//creatureTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
creatureTarget->SetReactState(REACT_PASSIVE);
creatureTarget->SetControlled(true, UNIT_STATE_ROOT);
creatureTarget->AttackStop();
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Creature* creatureTarget = GetTarget()->ToCreature();
if (!creatureTarget)
{
return;
}
creatureTarget->RemoveAurasDueToSpell(SPELL_PLAY_DEAD_PACIFY);
creatureTarget->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
creatureTarget->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
//creatureTarget->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
creatureTarget->SetControlled(false, UNIT_STATE_ROOT);
creatureTarget->SetReactState(REACT_AGGRESSIVE);
if (!creatureTarget->IsInCombat())
{
return;
}
bool shouldDie = true;
std::list<Creature*> hounds;
creatureTarget->GetCreaturesWithEntryInRange(hounds, 80.0f, NPC_CORE_HOUND);
// Perform lambda based check to find if there is any nearby
if (!hounds.empty())
{
// Alive hound been found within 80 yards -> cancel suicide
if (std::find_if(hounds.begin(), hounds.end(), [creatureTarget](Creature const* hound)
{
return creatureTarget != hound && creatureTarget->IsWithinLOSInMap(hound) && hound->IsAlive() && hound->IsInCombat() && !hound->HasAura(SPELL_PLAY_DEAD);
}) != hounds.end())
{
shouldDie = false;
}
}
if (!shouldDie)
{
if (CreatureAI* targetAI = creatureTarget->AI())
{
targetAI->DoCastSelf(SPELL_FIRE_NOVA_VISUAL, true);
targetAI->DoCastSelf(SPELL_FULL_HEALTH, true);
targetAI->Talk(EMOTE_IGNITE);
}
}
else
{
Unit::Kill(creatureTarget, creatureTarget);
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_mc_play_dead_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_FEIGN_DEATH, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectApplyFn(spell_mc_play_dead_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_FEIGN_DEATH, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_mc_play_dead_AuraScript();
}
};
void AddSC_molten_core()
{
// Creatures
new npc_mc_core_hound();
// Spells
new spell_mc_play_dead();
}
@@ -15,74 +15,107 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "Player.h"
#ifndef DEF_MOLTEN_CORE_H #ifndef DEF_MOLTEN_CORE_H
#define DEF_MOLTEN_CORE_H #define DEF_MOLTEN_CORE_H
#include "CreatureAIImpl.h"
#define MCScriptName "instance_molten_core" #define MCScriptName "instance_molten_core"
enum Encounters constexpr uint32 MAX_ENCOUNTER = 10;
enum MCData
{ {
BOSS_LUCIFRON = 0, DATA_LUCIFRON = 0,
BOSS_MAGMADAR = 1, DATA_MAGMADAR = 1,
BOSS_GEHENNAS = 2, DATA_GEHENNAS = 2,
BOSS_GARR = 3, DATA_GARR = 3,
BOSS_SHAZZRAH = 4, DATA_SHAZZRAH = 4,
BOSS_BARON_GEDDON = 5, DATA_GEDDON = 5,
BOSS_SULFURON_HARBINGER = 6, DATA_SULFURON = 6,
BOSS_GOLEMAGG_THE_INCINERATOR = 7, DATA_GOLEMAGG = 7,
BOSS_MAJORDOMO_EXECUTUS = 8, DATA_MAJORDOMO_EXECUTUS = 8,
BOSS_RAGNAROS = 9, DATA_RAGNAROS = 9,
MAX_ENCOUNTER,
// Other data
DATA_LAVA_STEAM = 10,
DATA_LAVA_SPLASH = 11,
}; };
enum Actions enum MCActions
{ {
ACTION_START_RAGNAROS = 0, ACTION_START_RAGNAROS_INTRO = -1,
ACTION_START_RAGNAROS_ALT = 1, ACTION_FINISH_RAGNAROS_INTRO = -2,
ACTION_RESET_MAGMADAR_ENCOUNTER = -3, // Used when ragers are pulled far away
ACTION_PREPARE_MAJORDOMO_RAGNA = -4,
}; };
Position const RagnarosTelePos = {829.159f, -815.773f, -228.972f, 5.30500f}; enum MCCreatures
Position const RagnarosSummonPos = {838.510f, -829.840f, -232.000f, 2.00000f};
enum Creatures
{ {
NPC_LUCIFRON = 12118,
NPC_MAGMADAR = 11982, NPC_MAGMADAR = 11982,
NPC_GEHENNAS = 12259,
NPC_GARR = 12057,
NPC_SHAZZRAH = 12264, NPC_SHAZZRAH = 12264,
NPC_BARON_GEDDON = 12056, NPC_BARON_GEDDON = 12056,
NPC_SULFURON_HARBINGER = 12098,
NPC_GOLEMAGG_THE_INCINERATOR = 11988,
NPC_MAJORDOMO_EXECUTUS = 12018,
NPC_RAGNAROS = 11502, NPC_RAGNAROS = 11502,
NPC_FLAMEWAKER_HEALER = 11663, NPC_FLAMEWAKER_HEALER = 11663,
NPC_FLAMEWAKER_ELITE = 11664, NPC_FLAMEWAKER_ELITE = 11664,
NPC_CORE_RAGER = 11672,
NPC_CORE_HOUND = 11671, NPC_CORE_HOUND = 11671,
// Garr
NPC_GARR = 12057,
NPC_FIRESWORN = 12099,
// Gehennas
NPC_GEHENNAS = 12259,
NPC_FLAMEWALKER = 11661,
// Golemagg
NPC_GOLEMAGG_THE_INCINERATOR = 11988,
NPC_CORE_RAGER = 11672,
// Lucifron
NPC_LUCIFRON = 12118,
NPC_FLAMEWALKER_PROTECTOR = 12119,
// Sulfuron
NPC_SULFURON_HARBINGER = 12098,
NPC_FLAMEWALKER_PRIEST = 11662,
// Majordomo
NPC_MAJORDOMO_EXECUTUS = 12018,
NPC_FLAMEWALKER_HEALER = 11663,
NPC_FLAMEWALKER_ELITE = 11664,
}; };
enum GameObjects enum MCGameObjects
{ {
GO_CACHE_OF_THE_FIRELORD = 179703, GO_CACHE_OF_THE_FIRELORD = 179703,
GO_CIRCLE_SULFURON = 178187, GO_CIRCLE_SULFURON = 178187,
GO_CIRCLE_BARON = 178188, GO_CIRCLE_GEDDON = 178188,
GO_CIRCLE_SHAZZRAH = 178189, GO_CIRCLE_SHAZZRAH = 178189,
GO_CIRCLE_GOLEMAGG = 178190, GO_CIRCLE_GOLEMAGG = 178190,
GO_CIRCLE_GARR = 178191, GO_CIRCLE_GARR = 178191,
GO_CIRCLE_MAGMADAR = 178192, GO_CIRCLE_MAGMADAR = 178192,
GO_CIRCLE_GEHENNAS = 178193, GO_CIRCLE_GEHENNAS = 178193,
GO_RUNE_KRESS = 176956, // Magmadar
GO_RUNE_MOHN = 176957, // Gehennas
GO_RUNE_BLAZ = 176955, // Garr
GO_RUNE_MAZJ = 176953, // Shazzrah
GO_RUNE_ZETH = 176952, // Geddon
GO_RUNE_THERI = 176954, // Golemagg
GO_RUNE_KORO = 176951, // Sulfuron
// Ragnaros event related
GO_LAVA_STEAM = 178107,
GO_LAVA_SPLASH = 178108,
}; };
enum Data enum MCSpells
{ {
DATA_RAGNAROS_ADDS = 0, SPELL_CORE_RAGER_QUIET_SUICIDE = 3617, // Server side
}; };
extern Position const MajordomoRagnaros; // Teleport location to Ragnaros summons area
extern Position const MajordomoSummonPos; // Majordomo summon position (battle)
template <class AI, class T> template <class AI, class T>
inline AI* GetMoltenCoreAI(T* obj) inline AI* GetMoltenCoreAI(T* obj)
{ {
@@ -74,7 +74,8 @@ void AddSC_boss_selin_fireheart();
void AddSC_boss_vexallus(); void AddSC_boss_vexallus();
void AddSC_boss_priestess_delrissa(); void AddSC_boss_priestess_delrissa();
void AddSC_instance_magisters_terrace(); void AddSC_instance_magisters_terrace();
void AddSC_boss_lucifron(); //Molten core void AddSC_molten_core(); //Molten core
void AddSC_boss_lucifron();
void AddSC_boss_magmadar(); void AddSC_boss_magmadar();
void AddSC_boss_gehennas(); void AddSC_boss_gehennas();
void AddSC_boss_garr(); void AddSC_boss_garr();
@@ -210,7 +211,8 @@ void AddEasternKingdomsScripts()
AddSC_boss_vexallus(); AddSC_boss_vexallus();
AddSC_boss_priestess_delrissa(); AddSC_boss_priestess_delrissa();
AddSC_instance_magisters_terrace(); AddSC_instance_magisters_terrace();
AddSC_boss_lucifron(); //Molten core AddSC_molten_core(); // Molten core
AddSC_boss_lucifron();
AddSC_boss_magmadar(); AddSC_boss_magmadar();
AddSC_boss_gehennas(); AddSC_boss_gehennas();
AddSC_boss_garr(); AddSC_boss_garr();