Merge branch 'master' into Vmaps

This commit is contained in:
天鹭 2025-10-19 05:29:47 +08:00 committed by GitHub
commit defb2ff5cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
67 changed files with 1279 additions and 1547 deletions

View File

@ -0,0 +1,33 @@
-- DB update 2025_10_16_03 -> 2025_10_16_04
--
-- Argent Dawn Initiate
UPDATE `creature_template` SET `gossip_menu_id` = 7230, `npcflag` = `npcflag` | 1 WHERE (`entry` = 16384);
-- Argent Dawn Cleric
UPDATE `creature_template` SET `gossip_menu_id` = 7231, `npcflag` = `npcflag` | 1 WHERE (`entry` = 16435);
-- Argent Dawn Priest
UPDATE `creature_template` SET `gossip_menu_id` = 7232, `npcflag` = `npcflag` | 1 WHERE (`entry` = 16436);
DELETE FROM `gossip_menu` WHERE `MenuID` IN (7230, 7231, 7232);
INSERT INTO `gossip_menu` (`MenuID`, `TextID`) VALUES
(7230, 8543),
(7231, 8544),
(7232, 8545);
DELETE FROM `npc_text` WHERE (`ID` IN (8543, 8544, 8545));
INSERT INTO `npc_text` (`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `em0_0`, `em0_1`, `em0_2`, `em0_3`, `em0_4`, `em0_5`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `em1_0`, `em1_1`, `em1_2`, `em1_3`, `em1_4`, `em1_5`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `em2_0`, `em2_1`, `em2_2`, `em2_3`, `em2_4`, `em2_5`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `em3_0`, `em3_1`, `em3_2`, `em3_3`, `em3_4`, `em3_5`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `em4_0`, `em4_1`, `em4_2`, `em4_3`, `em4_4`, `em4_5`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `em5_0`, `em5_1`, `em5_2`, `em5_3`, `em5_4`, `em5_5`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `em6_0`, `em6_1`, `em6_2`, `em6_3`, `em6_4`, `em6_5`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `em7_0`, `em7_1`, `em7_2`, `em7_3`, `em7_4`, `em7_5`, `VerifiedBuild`) VALUES
(8543, '', '', 12301, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(8544, '', '', 12300, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(8545, '', '', 12299, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
DELETE FROM `gossip_menu_option` WHERE (`MenuID` IN (7230, 7231, 7232));
INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionIcon`, `OptionText`, `OptionBroadcastTextID`, `OptionType`, `OptionNpcFlag`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
(7230, 0, 0, 'Give me one of your magic items.', 12302, 1, 1, 0, 0, 0, 0, '', 0, 0),
(7231, 0, 0, 'Give me one of your magic items.', 12302, 1, 1, 0, 0, 0, 0, '', 0, 0),
(7232, 0, 0, 'Give me one of your magic items.', 12302, 1, 1, 0, 0, 0, 0, '', 0, 0);
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` IN (16384, 16435, 16436);
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (16384, 16435, 16436) AND (`source_type` = 0);
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `event_param6`, `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
(16384, 0, 0, 0, 62, 0, 100, 0, 7230, 0, 0, 0, 0, 0, 11, 28319, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Dawn Initiate - On Gossip Option 0 Selected - Cast \'Create Lesser Mark of the Dawn\''),
(16435, 0, 0, 0, 62, 0, 100, 0, 7231, 0, 0, 0, 0, 0, 11, 28320, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Dawn Cleric - On Gossip Option 0 Selected - Cast \'Create Mark of the Dawn\''),
(16436, 0, 0, 0, 62, 0, 100, 0, 7232, 0, 0, 0, 0, 0, 11, 28321, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Argent Dawn Priest - On Gossip Option 0 Selected - Cast \'Create Greater Mark of the Dawn\'');

View File

@ -0,0 +1,7 @@
-- DB update 2025_10_16_04 -> 2025_10_16_05
-- Fire Immunity (Unbound Firestorm N/H)
UPDATE `creature_template` SET `spell_school_immune_mask` = `spell_school_immune_mask` |4 WHERE (`entry` IN (28584, 30983));
-- Nature Immunity (Slag H, Storming Vortex N/H, Cyclone H)
UPDATE `creature_template` SET `spell_school_immune_mask` = `spell_school_immune_mask` |8 WHERE (`entry` IN (28547, 30970, 30979, 30965));

View File

@ -0,0 +1,3 @@
-- DB update 2025_10_16_05 -> 2025_10_17_00
--
UPDATE `gameobject` SET `state` = 0 WHERE `guid` IN (65573, 65585) AND `id` IN (191324, 191416);

View File

@ -0,0 +1,7 @@
-- DB update 2025_10_17_00 -> 2025_10_18_00
--
UPDATE `spell_proc_event` SET `SpellFamilyMask2` = 0x00000040 WHERE `entry` = -33191;
DELETE FROM `spell_script_names` WHERE `spell_id` = -33191;
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(-33191, 'spell_gen_proc_on_victim');

View File

@ -0,0 +1,6 @@
-- DB update 2025_10_18_00 -> 2025_10_18_01
DELETE FROM `spelldifficulty_dbc` WHERE `ID` IN (52780, 52658, 52667);
INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`, `DifficultySpellID_3`, `DifficultySpellID_4`) VALUES
(52780, 52780, 59800, 0, 0), -- Ball Lightning
(52658, 52658, 59795, 0, 0), -- Static Overload
(52667, 52667, 59833, 0, 0); -- Spark Visual Trigger

View File

@ -0,0 +1,94 @@
-- DB update 2025_10_18_01 -> 2025_10_18_02
--
UPDATE `creature_template` SET `unit_flags` = `unit_flags`|64|256|512|32768|33554432, `ScriptName` = '' WHERE `entry` IN (28961, 28965, 30980, 30982);
DELETE FROM `areatrigger_scripts` WHERE `entry` IN (5082, 5083, 5084);
INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES
(5082, 'at_hol_hall_of_watchers'),
(5083, 'at_hol_hall_of_watchers'),
(5084, 'at_hol_hall_of_watchers');
DELETE FROM `creature_template_addon` WHERE `entry` IN (28965, 28961, 30980, 30982);
INSERT INTO `creature_template_addon` (`entry`,`path_id`,`bytes1`,`mount`,`auras`) VALUES
(28965, 0, 0, 0, '52881'), -- 28965 - 16245, 52881
(28961, 0, 0, 0, '52898'), -- 28961 - 16245, 52898
(30980, 0, 0, 0, '52898'),
(30982, 0, 0, 0, '52881');
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 28961;
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 28961);
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`, `event_param6`, `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
(28961, 0, 0, 0, 0, 0, 100, 0, 10000, 25000, 10000, 25000, 0, 0, 11, 23600, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - In Combat - Cast \'Piercing Howl\''),
(28961, 0, 1, 0, 0, 0, 100, 0, 5000, 10000, 5000, 10000, 0, 0, 11, 52890, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - In Combat - Cast \'Penetrating Strike\''),
(28961, 0, 2, 0, 0, 0, 100, 0, 12000, 12000, 12000, 12000, 0, 0, 11, 52891, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - In Combat - Cast \'Blade Turning\''),
(28961, 0, 3, 9, 2, 0, 100, 1, 0, 2, 1000, 1000, 0, 0, 11, 19134, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - Between 0-2% Health - Cast \'Frightening Shout\' (No Repeat)'),
(28961, 0, 4, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 16245, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - On Initialize - Cast \'Freeze Anim\''),
(28961, 0, 5, 6, 72, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - On Action 0 Done - Remove Flags Immune To Players & Immune To NPC\'s'),
(28961, 0, 6, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 28, 16245, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - On Action 0 Done - Remove Aura \'Freeze Anim\''),
(28961, 0, 7, 0, 7, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - On Evade - Remove Flags Immune To Players'),
(28961, 0, 8, 0, 25, 0, 100, 0, 0, 0, 0, 0, 0, 0, 42, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - On Reset - Set Invincibility Hp 1%'),
(28961, 0, 9, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 37, 500, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Siegebreaker - Between 0-2% Health - Kill Self (No Repeat)');
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 28965;
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 28965);
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`, `event_param6`, `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
(28965, 0, 0, 0, 0, 0, 100, 0, 10000, 25000, 10000, 25000, 0, 0, 11, 52904, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Thunderer - In Combat - Cast \'Throw\''),
(28965, 0, 1, 0, 0, 0, 100, 0, 15000, 30000, 15000, 30000, 0, 0, 11, 52885, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Thunderer - In Combat - Cast \'Deadly Throw\''),
(28965, 0, 2, 0, 0, 0, 100, 0, 15000, 15000, 15000, 15000, 0, 0, 11, 52879, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Thunderer - In Combat - Cast \'Deflection\''),
(28965, 0, 3, 0, 37, 0, 100, 0, 0, 0, 0, 0, 0, 0, 11, 16245, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Thunderer - On Initialize - Cast \'Freeze Anim\''),
(28965, 0, 4, 5, 72, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 768, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Thunderer - On Action 0 Done - Remove Flags Immune To Players & Immune To NPC\'s'),
(28965, 0, 5, 0, 61, 0, 100, 0, 0, 0, 0, 0, 0, 0, 28, 16245, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Thunderer - On Action 0 Done - Remove Aura \'Freeze Anim\''),
(28965, 0, 6, 0, 7, 0, 100, 0, 0, 0, 0, 0, 0, 0, 19, 256, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Titanium Thunderer - On Evade - Remove Flags Immune To Players');
SET @CGUID := 52885;
DELETE FROM `creature` WHERE `id1` IN (28961, 28965);
DELETE FROM `creature` WHERE `guid` BETWEEN @CGUID+0 AND @CGUID+30;
INSERT INTO `creature` (`guid`, `id1`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `VerifiedBuild`) VALUES
(@CGUID+0, 28961, 602, 4272, 4272, 3, 1, 1, 1259.378173828125, -145.273757934570312, 52.29970932006835937, 4.834561824798583984, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+1, 28961, 602, 4272, 4272, 3, 1, 1, 1264.5328369140625, -145.5595703125, 52.26771926879882812, 4.764749050140380859, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+2, 28965, 602, 4272, 4272, 3, 1, 1, 1224.5123291015625, -145.291229248046875, 52.67881393432617187, 4.694935798645019531, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+3, 28961, 602, 4272, 4272, 3, 1, 1, 1215.1031494140625, -145.157012939453125, 52.66891098022460937, 4.764749050140380859, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+4, 28965, 602, 4272, 4272, 3, 1, 1, 1263.8841552734375, -183.708663940429687, 52.27320098876953125, 1.605702877044677734, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+5, 28965, 602, 4272, 4272, 3, 1, 1, 1259.0084228515625, -183.691726684570312, 52.26767730712890625, 1.605702877044677734, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+6, 28961, 602, 4272, 4272, 3, 1, 1, 1225.5767822265625, -184.354385375976562, 52.68161392211914062, 1.65806281566619873, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+7, 28961, 602, 4272, 4272, 3, 1, 1, 1248.0032958984375, -145.068801879882812, 52.37061309814453125, 4.694935798645019531, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+8, 28965, 602, 4272, 4272, 3, 1, 1, 1253.1517333984375, -183.504989624023437, 52.34642791748046875, 1.623156189918518066, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+9, 28965, 602, 4272, 4272, 3, 1, 1, 1253.5120849609375, -145.027999877929687, 52.33613204956054687, 4.694935798645019531, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+10, 28961, 602, 4272, 4272, 3, 1, 1, 1248.0181884765625, -183.460174560546875, 52.38129043579101562, 1.570796370506286621, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+11, 28965, 602, 4272, 4272, 3, 1, 1, 1220.2291259765625, -145.243927001953125, 52.66761016845703125, 4.764749050140380859, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+12, 28965, 602, 4272, 4272, 3, 1, 1, 1181.0302734375, -146.033523559570312, 52.79578399658203125, 4.729842185974121093, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+13, 28961, 602, 4272, 4272, 3, 1, 1, 1209.4744873046875, -144.967559814453125, 52.67555618286132812, 4.677482128143310546, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+14, 28965, 602, 4272, 4272, 3, 1, 1, 1162.207763671875, -154.09527587890625, 52.79578399658203125, 0, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+15, 28961, 602, 4272, 4272, 3, 1, 1, 1157.05712890625, -199.659942626953125, 52.46372222900390625, 0.03490658476948738, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+16, 28965, 602, 4272, 4272, 3, 1, 1, 1156.6702880859375, -205.869796752929687, 52.49854278564453125, 6.2657318115234375, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+17, 28961, 602, 4272, 4272, 3, 1, 1, 1219.8778076171875, -184.285049438476562, 52.66225814819335937, 1.692969322204589843, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+18, 28961, 602, 4272, 4272, 3, 1, 1, 1175.3406982421875, -146.038192749023437, 52.79578781127929687, 4.660028934478759765, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+19, 28961, 602, 4272, 4272, 3, 1, 1, 1191.956298828125, -212.037765502929687, 52.10306549072265625, 3.228859186172485351, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+20, 28965, 602, 4272, 4272, 3, 1, 1, 1170.35205078125, -145.817596435546875, 52.79578781127929687, 4.764749050140380859, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+21, 28961, 602, 4272, 4272, 3, 1, 1, 1192.097412109375, -206.172744750976562, 52.09882354736328125, 3.246312379837036132, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+22, 28961, 602, 4272, 4272, 3, 1, 1, 1191.9901123046875, -218.161788940429687, 52.5872344970703125, 3.176499128341674804, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+23, 28965, 602, 4272, 4272, 3, 1, 1, 1213.839599609375, -184.1123046875, 52.65846633911132812, 1.675516128540039062, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+24, 28961, 602, 4272, 4272, 3, 1, 1, 1162.1590576171875, -159.638992309570312, 52.79578781127929687, 0, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+25, 28965, 602, 4272, 4272, 3, 1, 1, 1156.6553955078125, -212.220382690429687, 52.53575897216796875, 6.2657318115234375, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+26, 28961, 602, 4272, 4272, 3, 1, 1, 1162.192138671875, -165.84429931640625, 52.79578781127929687, 0.05235987901687622, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+27, 28965, 602, 4272, 4272, 3, 1, 1, 1156.8057861328125, -218.583663940429687, 52.55777740478515625, 0.03490658476948738, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+28, 28961, 602, 4272, 4272, 3, 1, 1, 1209.2860107421875, -184.312179565429687, 52.66295242309570312, 1.640609502792358398, 7200, 0, 0, 5802, 0, 0, 0, 0, 0, 63834),
(@CGUID+29, 28965, 602, 4272, 4272, 3, 1, 1, 1186.61962890625, -146.100265502929687, 52.79578781127929687, 4.764749050140380859, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834),
(@CGUID+30, 28965, 602, 4272, 4272, 3, 1, 1, 1162.243896484375, -171.8046875, 52.79578399658203125, 0, 7200, 0, 0, 6285, 0, 0, 0, 0, 0, 63834);
DELETE FROM `spell_proc_event` WHERE `entry` = 52881;
INSERT INTO `spell_proc_event` (`entry`, `procEx`, `Cooldown`) VALUES
(52881, 0x00000020, 12000);
UPDATE `spell_proc_event` SET `Cooldown` = 6000 WHERE `entry` = 52898;
DELETE FROM `spelldifficulty_dbc` WHERE `ID` IN (52891, 52885, 52879, 52904);
INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`, `DifficultySpellID_3`, `DifficultySpellID_4`) VALUES
(52891, 52891, 59173, 0, 0), -- Blade Turning
(52885, 52885, 59180, 0, 0), -- Deadly Throw
(52879, 52879, 59181, 0, 0), -- Deflection
(52904, 52904, 59179, 0, 0); -- Throw
DELETE FROM `linked_respawn` WHERE `guid` IN (126835, 126837, 126838, 126839, 126840, 126841, 126843, 126844, 126846, 126847, 126849, 126850, 126851, 126852, 126853, 126854, 126855, 126856, 126857, 126860, 126862) AND `linkType` = 0;

View File

@ -75,7 +75,7 @@ void EventProcessor::Update(uint32 p_time)
// Reschedule non deletable events to be checked at
// the next update tick
AddEvent(event, CalculateTime(1), false, 0);
AddEvent(event, CalculateTime(1), false);
}
}
@ -133,13 +133,13 @@ void EventProcessor::CancelEventGroup(uint8 group)
}
}
void EventProcessor::AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime, uint8 eventGroup)
void EventProcessor::AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime /*= true*/, uint8 eventGroup /*= 0*/)
{
if (set_addtime)
Event->m_addTime = m_time;
Event->m_execTime = e_time;
Event->m_eventGroup = eventGroup;
m_events.insert(std::pair<uint64, BasicEvent*>(e_time, Event));
m_events.emplace(e_time, Event);
}
void EventProcessor::ModifyEventTime(BasicEvent* event, Milliseconds newTime)
@ -151,7 +151,7 @@ void EventProcessor::ModifyEventTime(BasicEvent* event, Milliseconds newTime)
event->m_execTime = newTime.count();
m_events.erase(itr);
m_events.insert(std::pair<uint64, BasicEvent*>(newTime.count(), event));
m_events.emplace(newTime.count(), event);
break;
}
}

View File

@ -100,20 +100,19 @@ class EventProcessor
void Update(uint32 p_time);
void KillAllEvents(bool force);
void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true) { AddEvent(Event, e_time, set_addtime, 0); };
void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime, uint8 eventGroup);
void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true, uint8 eventGroup = 0);
template<typename T>
is_lambda_event<T> AddEvent(T&& event, Milliseconds e_time, bool set_addtime = true) { AddEvent(new LambdaBasicEvent<T>(std::move(event)), e_time, set_addtime); }
void AddEventAtOffset(BasicEvent* event, Milliseconds offset) { AddEvent(event, CalculateTime(offset.count()), true, 0); }
void AddEventAtOffset(BasicEvent* event, Milliseconds offset, Milliseconds offset2) { AddEvent(event, CalculateTime(randtime(offset, offset2).count()), true, false); }
is_lambda_event<T> AddEvent(T&& event, Milliseconds e_time, bool set_addtime = true, uint8 eventGroup = 0) { AddEvent(new LambdaBasicEvent<T>(std::move(event)), e_time.count(), set_addtime, eventGroup); }
void AddEventAtOffset(BasicEvent* event, Milliseconds offset, uint8 eventGroup = 0) { AddEvent(event, CalculateTime(offset.count()), true, eventGroup); }
template<typename T>
is_lambda_event<T> AddEventAtOffset(T&& event, Milliseconds offset, uint8 eventGroup) { AddEvent(new LambdaBasicEvent<T>(std::move(event)), CalculateTime(offset.count()), true, eventGroup); };
is_lambda_event<T> AddEventAtOffset(T&& event, Milliseconds offset, uint8 eventGroup = 0) { AddEventAtOffset(new LambdaBasicEvent<T>(std::move(event)), offset, eventGroup); };
void AddEventAtOffset(BasicEvent* event, Milliseconds offset, Milliseconds offset2, uint8 eventGroup = 0) { AddEvent(event, CalculateTime(randtime(offset, offset2).count()), true, eventGroup); }
template<typename T>
is_lambda_event<T> AddEventAtOffset(T&& event, Milliseconds offset, Milliseconds offset2, uint8 eventGroup) { AddEvent(new LambdaBasicEvent<T>(std::move(event)), CalculateTime(randtime(offset, offset2).count()), true, eventGroup); };
template<typename T>
is_lambda_event<T> AddEventAtOffset(T&& event, Milliseconds offset) { AddEventAtOffset(new LambdaBasicEvent<T>(std::move(event)), offset); }
template<typename T>
is_lambda_event<T> AddEventAtOffset(T&& event, Milliseconds offset, Milliseconds offset2) { AddEventAtOffset(new LambdaBasicEvent<T>(std::move(event)), offset, offset2); }
is_lambda_event<T> AddEventAtOffset(T&& event, Milliseconds offset, Milliseconds offset2, uint8 eventGroup = 0) { AddEventAtOffset(new LambdaBasicEvent<T>(std::move(event)), offset, offset2, eventGroup); };
void ModifyEventTime(BasicEvent* event, Milliseconds newTime);
[[nodiscard]] uint64 CalculateTime(uint64 t_offset) const;
@ -121,6 +120,7 @@ class EventProcessor
[[nodiscard]] uint64 CalculateQueueTime(uint64 delay) const;
void CancelEventGroup(uint8 group);
bool HaveEventList() const { return !m_events.empty(); }
protected:
uint64 m_time{0};

View File

@ -366,7 +366,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount)
void BattlegroundQueue::AddEvent(BasicEvent* Event, uint64 e_time)
{
m_events.AddEvent(Event, m_events.CalculateTime(e_time));
m_events.AddEventAtOffset(Event, Milliseconds(e_time));
}
bool BattlegroundQueue::IsPlayerInvitedToRatedArena(ObjectGuid pl_guid)

View File

@ -1508,7 +1508,7 @@ namespace lfg
lockMap.clear();
}
uint8 LFGMgr::CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag /*= true*/)
uint8 LFGMgr::CheckGroupRoles(LfgRolesMap& groles)
{
if (groles.empty())
return 0;
@ -1517,21 +1517,18 @@ namespace lfg
uint8 tank = 0;
uint8 healer = 0;
if (removeLeaderFlag)
for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it)
it->second &= ~PLAYER_ROLE_LEADER;
for (LfgRolesMap::iterator it = groles.begin(); it != groles.end(); ++it)
{
if (it->second == PLAYER_ROLE_NONE)
uint8 const role = it->second & ~PLAYER_ROLE_LEADER;
if (role == PLAYER_ROLE_NONE)
return 0;
if (it->second & PLAYER_ROLE_DAMAGE)
if (role & PLAYER_ROLE_DAMAGE)
{
if (it->second != PLAYER_ROLE_DAMAGE)
if (role != PLAYER_ROLE_DAMAGE)
{
it->second -= PLAYER_ROLE_DAMAGE;
if (uint8 x = CheckGroupRoles(groles, false))
if (uint8 x = CheckGroupRoles(groles))
return x;
it->second += PLAYER_ROLE_DAMAGE;
}
@ -1541,12 +1538,12 @@ namespace lfg
damage++;
}
if (it->second & PLAYER_ROLE_HEALER)
if (role & PLAYER_ROLE_HEALER)
{
if (it->second != PLAYER_ROLE_HEALER)
if (role != PLAYER_ROLE_HEALER)
{
it->second -= PLAYER_ROLE_HEALER;
if (uint8 x = CheckGroupRoles(groles, false))
if (uint8 x = CheckGroupRoles(groles))
return x;
it->second += PLAYER_ROLE_HEALER;
}
@ -1556,12 +1553,12 @@ namespace lfg
healer++;
}
if (it->second & PLAYER_ROLE_TANK)
if (role & PLAYER_ROLE_TANK)
{
if (it->second != PLAYER_ROLE_TANK)
if (role != PLAYER_ROLE_TANK)
{
it->second -= PLAYER_ROLE_TANK;
if (uint8 x = CheckGroupRoles(groles, false))
if (uint8 x = CheckGroupRoles(groles))
return x;
it->second += PLAYER_ROLE_TANK;
}

View File

@ -568,7 +568,7 @@ namespace lfg
/// Checks if all players are queued
bool AllQueued(Lfg5Guids const& check);
/// Checks if given roles match, modifies given roles map with new roles
static uint8 CheckGroupRoles(LfgRolesMap& groles, bool removeLeaderFlag = true);
static uint8 CheckGroupRoles(LfgRolesMap& groles);
/// Checks if given players are ignoring each other
static bool HasIgnore(ObjectGuid guid1, ObjectGuid guid2);
/// Sends queue status to player

View File

@ -2159,12 +2159,12 @@ void Creature::Respawn(bool force)
}
}
void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
void Creature::ForcedDespawn(Milliseconds timeMSToDespawn, Seconds forceRespawnTimer)
{
if (timeMSToDespawn)
if (timeMSToDespawn > 0ms)
{
ForcedDespawnDelayEvent* pEvent = new ForcedDespawnDelayEvent(*this, forceRespawnTimer);
m_Events.AddEvent(pEvent, m_Events.CalculateTime(timeMSToDespawn));
m_Events.AddEventAtOffset(pEvent, timeMSToDespawn);
return;
}
@ -2182,9 +2182,9 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
void Creature::DespawnOrUnsummon(Milliseconds msTimeToDespawn /*= 0ms*/, Seconds forcedRespawnTimer /*= 0s*/)
{
if (TempSummon* summon = this->ToTempSummon())
summon->UnSummon(msTimeToDespawn.count());
summon->UnSummon(msTimeToDespawn);
else
ForcedDespawn(msTimeToDespawn.count(), forcedRespawnTimer);
ForcedDespawn(msTimeToDespawn, forcedRespawnTimer);
}
void Creature::DespawnOnEvade(Seconds respawnDelay)
@ -2464,7 +2464,7 @@ void Creature::CallAssistance(Unit* target /*= nullptr*/)
e->AddAssistant((*assistList.begin())->GetGUID());
assistList.pop_front();
}
m_Events.AddEvent(e, m_Events.CalculateTime(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY)));
m_Events.AddEventAtOffset(e, Milliseconds(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY)));
}
}
}
@ -3762,7 +3762,7 @@ void Creature::ModifyThreatPercentTemp(Unit* victim, int32 percent, Milliseconds
}
TemporaryThreatModifierEvent* pEvent = new TemporaryThreatModifierEvent(*this, victim->GetGUID(), currentThreat);
m_Events.AddEvent(pEvent, m_Events.CalculateTime(duration.count()));
m_Events.AddEventAtOffset(pEvent, duration);
}
}

View File

@ -505,7 +505,7 @@ protected:
bool IsAlwaysDetectableFor(WorldObject const* seer) const override;
private:
void ForcedDespawn(uint32 timeMSToDespawn = 0, Seconds forcedRespawnTimer = 0s);
void ForcedDespawn(Milliseconds timeMSToDespawn = 0ms, Seconds forcedRespawnTimer = 0s);
[[nodiscard]] bool CanPeriodicallyCallForAssistance() const;

View File

@ -284,13 +284,12 @@ void TempSummon::SetTempSummonType(TempSummonType type)
m_type = type;
}
void TempSummon::UnSummon(uint32 msTime)
void TempSummon::UnSummon(Milliseconds msTime)
{
if (msTime)
if (msTime > 0ms)
{
ForcedUnsummonDelayEvent* pEvent = new ForcedUnsummonDelayEvent(*this);
m_Events.AddEvent(pEvent, m_Events.CalculateTime(msTime));
m_Events.AddEventAtOffset(pEvent, msTime);
return;
}

View File

@ -44,7 +44,7 @@ public:
void Update(uint32 time) override;
virtual void InitStats(uint32 lifetime);
virtual void InitSummon();
virtual void UnSummon(uint32 msTime = 0);
virtual void UnSummon(Milliseconds msTime = 0ms);
void UpdateObjectVisibilityOnCreate() override;
void RemoveFromWorld() override;
void SetTempSummonType(TempSummonType type);
@ -133,4 +133,5 @@ public:
private:
TempSummon& m_owner;
};
#endif

View File

@ -76,10 +76,10 @@ enum ActionFeedback
FEEDBACK_CANT_ATT_TARGET = 3
};
enum PetTalk
enum PetAction : int32
{
PET_TALK_SPECIAL_SPELL = 0,
PET_TALK_ATTACK = 1
PET_ACTION_SPECIAL_SPELL = 0,
PET_ACTION_ATTACK = 1
};
enum PetLoadState

View File

@ -14374,6 +14374,12 @@ bool Player::CanSeeSpellClickOn(Creature const* c) const
*/
bool Player::AnyVendorOptionAvailable(uint32 menuId, Creature const* creature) const
{
{
GossipMenuItemsMapBounds menuItemBounds = sObjectMgr->GetGossipMenuItemsMapBounds(menuId);
if (menuItemBounds.first == menuItemBounds.second)
return true;
}
std::set<uint32> visitedMenus;
std::queue<uint32> menusToCheck;
menusToCheck.push(menuId);

View File

@ -119,11 +119,11 @@ void Totem::InitSummon()
}
}
void Totem::UnSummon(uint32 msTime)
void Totem::UnSummon(Milliseconds msTime)
{
if (msTime)
if (msTime > 0ms)
{
m_Events.AddEvent(new ForcedUnsummonDelayEvent(*this), m_Events.CalculateTime(msTime));
m_Events.AddEventAtOffset(new ForcedUnsummonDelayEvent(*this), msTime);
return;
}

View File

@ -55,7 +55,7 @@ public:
void Update(uint32 time) override;
void InitStats(uint32 duration) override;
void InitSummon() override;
void UnSummon(uint32 msTime = 0) override;
void UnSummon(Milliseconds msTime = 0ms) override;
uint32 GetSpell(uint8 slot = 0) const { return m_spells[slot]; }
uint32 GetTotemDuration() const { return m_duration; }
void SetTotemDuration(uint32 duration) { m_duration = duration; }

View File

@ -50,6 +50,7 @@
#include "PassiveAI.h"
#include "Pet.h"
#include "PetAI.h"
#include "PetPackets.h"
#include "Player.h"
#include "ReputationMgr.h"
#include "ScriptMgr.h"
@ -11071,7 +11072,7 @@ int32 Unit::DealHeal(Unit* healer, Unit* victim, uint32 addhealth)
return gain;
}
bool RedirectSpellEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
bool RedirectSpellEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
if (Unit* auraOwner = ObjectAccessor::GetUnit(_self, _auraOwnerGUID))
{
@ -16672,7 +16673,7 @@ Player* Unit::GetSpellModOwner() const
}
///----------Pet responses methods-----------------
void Unit::SendPetActionFeedback(uint8 msg)
void Unit::SendPetActionFeedback(uint8 msg) const
{
Unit* owner = GetOwner();
if (!owner || !owner->IsPlayer())
@ -16683,19 +16684,18 @@ void Unit::SendPetActionFeedback(uint8 msg)
owner->ToPlayer()->GetSession()->SendPacket(&data);
}
void Unit::SendPetTalk(uint32 pettalk)
void Unit::SendPetActionSound(PetAction action) const
{
Unit* owner = GetOwner();
if (!owner || !owner->IsPlayer())
return;
WorldPacket data(SMSG_PET_ACTION_SOUND, 8 + 4);
data << GetGUID();
data << uint32(pettalk);
owner->ToPlayer()->GetSession()->SendPacket(&data);
SendMessageToSet(WorldPackets::Pet::PetActionSound(GetGUID(), static_cast<int32>(action)).Write(), false);
}
void Unit::SendPetAIReaction(ObjectGuid guid)
void Unit::SendPetDismissSound() const
{
if (CreatureDisplayInfoEntry const* displayInfo = sCreatureDisplayInfoStore.LookupEntry(GetNativeDisplayId()))
SendMessageToSet(WorldPackets::Pet::PetDismissSound(static_cast<int32>(displayInfo->ModelId), GetPosition()).Write(), false);
}
void Unit::SendPetAIReaction(ObjectGuid guid) const
{
Unit* owner = GetOwner();
if (!owner || !owner->IsPlayer())
@ -19572,7 +19572,7 @@ void Unit::ExitVehicle(Position const* /*exitPosition*/)
}
}
bool VehicleDespawnEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
bool VehicleDespawnEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
Position pos = _self;
_self.MovePositionToFirstCollision(pos, 20.0f, M_PI);
@ -19699,7 +19699,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
setDeathState(DeathState::JustDied);
// If for other reason we as minion are exiting the vehicle (ejected, master dismounted) - unsummon
else
ToTempSummon()->UnSummon(2000); // Approximation
ToTempSummon()->UnSummon(2s); // Approximation
}
if (player)
@ -20086,7 +20086,7 @@ class AuraMunchingQueue : public BasicEvent
public:
AuraMunchingQueue(Unit& owner, ObjectGuid targetGUID, int32 basePoints, uint32 spellId, AuraEffect* aurEff, AuraType auraType) : _owner(owner), _targetGUID(targetGUID), _basePoints(basePoints), _spellId(spellId), _aurEff(aurEff), _auraType(auraType) { }
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
bool Execute(uint64 /*e_time*/, uint32 /*p_time*/) override
{
if (_owner.IsInWorld() && _owner.FindMap())
if (Unit* target = ObjectAccessor::GetUnit(_owner, _targetGUID))
@ -20115,24 +20115,6 @@ private:
AuraType _auraType;
};
class ResetToHomeOrientation : public BasicEvent
{
public:
ResetToHomeOrientation(Creature& self) : _self(self) { }
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/) override
{
if (_self.IsInWorld() && _self.FindMap() && _self.IsAlive() && !_self.IsInCombat())
{
_self.SetFacingTo(_self.GetHomePosition().GetOrientation());
}
return true;
}
private:
Creature& _self;
};
void Unit::CastDelayedSpellWithPeriodicAmount(Unit* caster, uint32 spellId, AuraType auraType, int32 addAmount, uint8 effectIndex)
{
AuraEffect* aurEff = nullptr;
@ -20358,7 +20340,7 @@ void Unit::SetFacingTo(float ori)
init.Launch();
}
void Unit::SetFacingToObject(WorldObject* object)
void Unit::SetFacingToObject(WorldObject* object, Milliseconds timed /*= 0ms*/)
{
// never face when already moving
if (!IsStopped())
@ -20369,24 +20351,20 @@ void Unit::SetFacingToObject(WorldObject* object)
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ());
init.SetFacing(GetAngle(object)); // when on transport, GetAngle will still return global coordinates (and angle) that needs transforming
init.Launch();
}
void Unit::SetTimedFacingToObject(WorldObject* object, uint32 time)
{
// never face when already moving
if (!IsStopped() || !time)
return;
/// @todo figure out under what conditions creature will move towards object instead of facing it where it currently is.
Movement::MoveSplineInit init(this);
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZ());
init.SetFacing(GetAngle(object)); // when on transport, GetAngle will still return global coordinates (and angle) that needs transforming
init.Launch();
if (Creature* c = ToCreature())
c->m_Events.AddEvent(new ResetToHomeOrientation(*c), c->m_Events.CalculateTime(time));
else
LOG_ERROR("entities.unit", "Unit::SetTimedFacingToObject called on non-creature unit {}. This should never happen.", GetEntry());
if (timed > 0ms)
{
if (Creature* c = ToCreature())
{
c->m_Events.AddEventAtOffset([c]()
{
if (c->IsInWorld() && c->FindMap() && c->IsAlive() && !c->IsInCombat())
c->SetFacingTo(c->GetHomePosition().GetOrientation());
}, timed);
}
else
LOG_ERROR("entities.unit", "Unit::SetFacingToObject called on non-creature unit {}. This should never happen.", GetEntry());
}
}
bool Unit::SetWalk(bool enable)

View File

@ -26,6 +26,7 @@
#include "ItemTemplate.h"
#include "MotionMaster.h"
#include "Object.h"
#include "PetDefines.h"
#include "SharedDefines.h"
#include "SpellAuraDefines.h"
#include "SpellDefines.h"
@ -1919,8 +1920,8 @@ public:
void SetInFront(WorldObject const* target);
void SetFacingTo(float ori);
void SetFacingToObject(WorldObject* object);
void SetTimedFacingToObject(WorldObject* object, uint32 time); // Reset to home orientation after given time
// <timed>Reset to home orientation after given time
void SetFacingToObject(WorldObject* object, Milliseconds timed = 0ms);
bool isInAccessiblePlaceFor(Creature const* c) const;
bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const;
@ -1962,9 +1963,10 @@ public:
void SendPlaySpellVisual(uint32 id);
void SendPlaySpellImpact(ObjectGuid guid, uint32 id);
void SendPetActionFeedback (uint8 msg);
void SendPetTalk (uint32 pettalk);
void SendPetAIReaction(ObjectGuid guid);
void SendPetActionFeedback(uint8 msg) const;
void SendPetActionSound(PetAction action) const;
void SendPetDismissSound() const;
void SendPetAIReaction(ObjectGuid guid) const;
void SendPeriodicAuraLog(SpellPeriodicAuraLogInfo* pInfo);

View File

@ -262,8 +262,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
pet->ToCreature()->AI()->AttackStart(TargetUnit);
//10% chance to play special pet attack talk, else growl
if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
pet->SendPetTalk((uint32)PET_TALK_ATTACK);
if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
pet->SendPetActionSound(PET_ACTION_ATTACK);
else
{
// 90% chance for pet and 100% chance for charmed creature
@ -297,8 +297,11 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
if (pet->ToPet()->getPetType() == HUNTER_PET)
GetPlayer()->RemovePet(pet->ToPet(), PET_SAVE_AS_DELETED);
else
{
pet->SendPetDismissSound();
//dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
pet->setDeathState(DeathState::Corpse);
}
}
else if (pet->HasUnitTypeMask(UNIT_MASK_MINION | UNIT_MASK_SUMMON | UNIT_MASK_GUARDIAN | UNIT_MASK_CONTROLLABLE_GUARDIAN))
{
@ -413,8 +416,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
//10% chance to play special pet attack talk, else growl
//actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (pet->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
if (pet->IsPet() && (pet->ToPet()->getPetType() == SUMMON_PET) && (pet != unit_target) && roll_chance_i(10))
pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL);
else
{
pet->SendPetAIReaction(guid1);
@ -509,8 +512,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
pet->ToCreature()->AI()->AttackStart(TargetUnit);
if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && urand(0, 100) < 10)
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid1);
}
@ -558,8 +561,8 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
pet->GetMotionMaster()->MoveFollow(unit_target, PET_FOLLOW_DIST, rand_norm() * 2 * M_PI);
if (pet->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != unit_target && urand(0, 100) < 10)
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != unit_target && roll_chance_i(10))
pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL);
else
{
pet->SendPetAIReaction(guid1);
@ -1059,8 +1062,8 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
// 10% chance to play special pet attack talk, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (pet->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk(PET_TALK_SPECIAL_SPELL);
if (pet->getPetType() == SUMMON_PET && roll_chance_i(10))
pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid);
}

View File

@ -50,3 +50,19 @@ WorldPacket const* WorldPackets::Pet::PetUnlearnedSpell::Write()
_worldPacket << uint32(SpellID);
return &_worldPacket;
}
WorldPacket const* WorldPackets::Pet::PetActionSound::Write()
{
_worldPacket << UnitGUID;
_worldPacket << int32(Action);
return &_worldPacket;
}
WorldPacket const* WorldPackets::Pet::PetDismissSound::Write()
{
_worldPacket << int32(ModelId);
_worldPacket << float(ModelPosition.x);
_worldPacket << float(ModelPosition.y);
_worldPacket << float(ModelPosition.z);
return &_worldPacket;
}

View File

@ -20,6 +20,7 @@
#include "ObjectGuid.h"
#include "Packet.h"
#include "G3D/Vector3.h"
namespace WorldPackets
{
@ -94,6 +95,30 @@ namespace WorldPackets
void Read() override { }
};
class PetActionSound final : public ServerPacket
{
public:
PetActionSound(ObjectGuid unitGUID, int32 action)
: ServerPacket(SMSG_PET_ACTION_SOUND, 8 + 4), UnitGUID(unitGUID), Action(action) { }
WorldPacket const* Write() override;
ObjectGuid UnitGUID;
int32 Action = 0;
};
class PetDismissSound final : public ServerPacket
{
public:
PetDismissSound(int32 modelId, G3D::Vector3 modelPosition)
: ServerPacket(SMSG_PET_DISMISS_SOUND, 4 + 12), ModelId(modelId), ModelPosition(modelPosition) { }
WorldPacket const* Write() override;
int32 ModelId = 0;
G3D::Vector3 ModelPosition;
};
}
}

View File

@ -2392,7 +2392,7 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
targetInfo.reflectResult = SPELL_MISS_PARRY;
// Increase time interval for reflected spells by 1.5
m_caster->m_Events.AddEvent(new ReflectEvent(m_caster, targetInfo.targetGUID, m_spellInfo), m_caster->m_Events.CalculateTime(targetInfo.timeDelay));
m_caster->m_Events.AddEventAtOffset(new ReflectEvent(m_caster, targetInfo.targetGUID, m_spellInfo), Milliseconds(targetInfo.timeDelay));
targetInfo.timeDelay += targetInfo.timeDelay >> 1;
m_spellFlags |= SPELL_FLAG_REFLECTED;
@ -3439,7 +3439,7 @@ SpellCastResult Spell::prepare(SpellCastTargets const* targets, AuraEffect const
// create and add update event for this spell
_spellEvent = new SpellEvent(this);
m_caster->m_Events.AddEvent(_spellEvent, m_caster->m_Events.CalculateTime(1));
m_caster->m_Events.AddEventAtOffset(_spellEvent, 1ms);
if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
{
@ -8166,7 +8166,7 @@ bool SpellEvent::IsDeletable() const
return m_Spell->IsDeletable();
}
bool ReflectEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
bool ReflectEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
Unit* target = ObjectAccessor::GetUnit(*_caster, _targetGUID);
if (target && _caster->IsInMap(target))

View File

@ -606,7 +606,7 @@ public:
if (Creature* argelmach = instance->GetCreature(ArgelmachGUID))
{
argelmach->HandleEmoteCommand(EMOTE_ONESHOT_SHOUT);
argelmach->m_Events.AddEvent(new RestoreAttack(argelmach), argelmach->m_Events.CalculateTime(3000));
argelmach->m_Events.AddEventAtOffset(new RestoreAttack(argelmach), 3s);
for (ObjectGuid const& argelmachAddGUID : ArgelmachAdds)
{

View File

@ -157,8 +157,8 @@ public:
orc->AI()->Talk(SAY_BLACKHAND_DOOMED);
}
orc->m_Events.AddEvent(new OrcMoveEvent(orc), me->m_Events.CalculateTime(3 * IN_MILLISECONDS));
orc->m_Events.AddEvent(new OrcDeathEvent(orc), me->m_Events.CalculateTime(9 * IN_MILLISECONDS));
orc->m_Events.AddEventAtOffset(new OrcMoveEvent(orc), 3s);
orc->m_Events.AddEventAtOffset(new OrcDeathEvent(orc), 9s);
}
}
}

View File

@ -473,7 +473,7 @@ public:
if (battleStarted != ENCOUNTER_STATE_FIGHT)
return;
me->m_Events.AddEvent(new DelayedSummonEvent(me, creature->GetEntry(), *creature), me->m_Events.CalculateTime(3000));
me->m_Events.AddEventAtOffset(new DelayedSummonEvent(me, creature->GetEntry(), *creature), 3s);
if (creature->GetEntry() >= NPC_RAMPAGING_ABOMINATION)
{
--scourgeRemaining;
@ -1269,7 +1269,7 @@ class spell_chapter5_return_to_capital : public SpellScript
if (creature)
{
creature->PauseMovement(5000);
creature->SetTimedFacingToObject(player, 30000);
creature->SetFacingToObject(player, 30s);
if (roll_chance_i(30))
{

View File

@ -319,9 +319,10 @@ struct boss_felmyst : public BossAI
break;
case POINT_LANE:
Talk(EMOTE_BREATH);
me->m_Events.AddEventAtOffset([&] {
me->m_Events.AddEventAtOffset([this]()
{
for (uint8 i = 0; i < 16; ++i)
me->m_Events.AddEvent(new CorruptTriggers(me, _currentLane), me->m_Events.CalculateTime(i*250));
me->m_Events.AddEventAtOffset(new CorruptTriggers(me, _currentLane), Milliseconds(i * 250));
}, 5s);
me->m_Events.AddEventAtOffset([&] {

View File

@ -554,7 +554,7 @@ struct boss_kiljaeden : public BossAI
summon->SetDisableGravity(true);
summon->CastSpell(summon, SPELL_ARMAGEDDON_VISUAL, true);
summon->SetPosition(summon->GetPositionX(), summon->GetPositionY(), summon->GetPositionZ() + 20.0f, 0.0f);
summon->m_Events.AddEvent(new CastArmageddon(summon), summon->m_Events.CalculateTime(6000));
summon->m_Events.AddEventAtOffset(new CastArmageddon(summon), 6s);
summon->DespawnOrUnsummon(randtime(8s, 10s));
}
}
@ -787,8 +787,8 @@ struct npc_kalecgos_kj : public NullCreatureAI
case EVENT_SCENE_05:
if (Creature* first = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f, 640.49f, 28.06f, 3.49f))
{
first->m_Events.AddEvent(new MoveDelayed(first, 1718.70f, 607.78f, 28.06f, 2.323f), first->m_Events.CalculateTime(5000));
first->m_Events.AddEvent(new FixOrientation(first), first->m_Events.CalculateTime(12000));
first->m_Events.AddEventAtOffset(new MoveDelayed(first, 1718.70f, 607.78f, 28.06f, 2.323f), 5s);
first->m_Events.AddEventAtOffset(new FixOrientation(first), 12s);
for (uint8 i = 0; i < 9; ++i)
if (Creature* follower = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f + 5 * cos(i * 2.0f * M_PI / 9), 640.49f + 5 * std::sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f))
follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first));
@ -798,8 +798,8 @@ struct npc_kalecgos_kj : public NullCreatureAI
case EVENT_SCENE_06:
if (Creature* first = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f, 640.49f, 28.06f, 3.49f))
{
first->m_Events.AddEvent(new MoveDelayed(first, 1678.69f, 649.27f, 28.06f, 5.46f), first->m_Events.CalculateTime(5000));
first->m_Events.AddEvent(new FixOrientation(first), first->m_Events.CalculateTime(14500));
first->m_Events.AddEventAtOffset(new MoveDelayed(first, 1678.69f, 649.27f, 28.06f, 5.46f), 5s);
first->m_Events.AddEventAtOffset(new FixOrientation(first), 14500ms);
for (uint8 i = 0; i < 9; ++i)
if (Creature* follower = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f + 5 * cos(i * 2.0f * M_PI / 9), 640.49f + 5 * std::sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f))
follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first));

View File

@ -199,19 +199,19 @@ struct npc_medivh_bm : public ScriptedAI
events.ScheduleEvent(EVENT_OUTRO_3, 2s);
break;
case EVENT_OUTRO_3:
SummonOrcs(-2046.158f, -3.0f, 37s, 30000, true);
SummonOrcs(-2046.158f, -3.0f, 37s, 30s, true);
events.ScheduleEvent(EVENT_OUTRO_4, 2s);
break;
case EVENT_OUTRO_4:
SummonOrcs(-2055.97f, -2.0f, 33s, 28000, false);
SummonOrcs(-2055.97f, -2.0f, 33s, 28s, false);
events.ScheduleEvent(EVENT_OUTRO_5, 2s);
break;
case EVENT_OUTRO_5:
SummonOrcs(-2064.0f, -1.5f, 29s, 26000, false);
SummonOrcs(-2064.0f, -1.5f, 29s, 26s, false);
events.ScheduleEvent(EVENT_OUTRO_6, 2s);
break;
case EVENT_OUTRO_6:
SummonOrcs(-2074.35f, -0.1f, 26s, 24000, false);
SummonOrcs(-2074.35f, -0.1f, 26s, 24s, false);
events.ScheduleEvent(EVENT_OUTRO_7, 7s);
break;
case EVENT_OUTRO_7:
@ -228,14 +228,14 @@ struct npc_medivh_bm : public ScriptedAI
}
}
void SummonOrcs(float x, float y, Milliseconds duration, uint32 homeTime, bool first)
void SummonOrcs(float x, float y, Milliseconds duration, Milliseconds homeTime, bool first)
{
for (uint8 i = 0; i < 6; ++i)
{
if (Creature* cr = me->SummonCreature(NPC_SHADOW_COUNCIL_ENFORCER, -2091.731f, 7133.083f - 3.0f * i, 34.589f, 0.0f))
{
cr->GetMotionMaster()->MovePoint(0, (first && i == 3) ? x + 2.0f : x, cr->GetPositionY() + y, cr->GetMapHeight(x, cr->GetPositionY() + y, cr->GetPositionZ(), true));
cr->m_Events.AddEvent(new NpcRunToHome(*cr), cr->m_Events.CalculateTime(homeTime + urand(0, 2000)));
cr->m_Events.AddEventAtOffset(new NpcRunToHome(*cr), homeTime + randtime(0ms, 2s));
cr->DespawnOrUnsummon(duration + randtime(0ms, 2s));
}
}

View File

@ -1174,7 +1174,7 @@ public:
summons->SetLootRecipient(player);
summons->CastSpell(summons, SPELL_SPAWN_IN, false);
summons->AI()->Talk(SAY_ON_SPAWN_IN, player);
summons->m_Events.AddEvent(new DelayedWindstoneSummonEvent(summons, player->GetGUID()), summons->m_Events.CalculateTime(5200));
summons->m_Events.AddEventAtOffset(new DelayedWindstoneSummonEvent(summons, player->GetGUID()), 5200ms);
_creatureGuid = summons->GetGUID();
}
}

View File

@ -152,7 +152,7 @@ public:
if (action == ACTION_INTRO_BALTHARUS && !_introDone)
{
_introDone = true;
me->m_Events.AddEvent(new DelayedTalk(me, SAY_BALTHARUS_INTRO), me->m_Events.CalculateTime(6000));
me->m_Events.AddEventAtOffset(new DelayedTalk(me, SAY_BALTHARUS_INTRO), 6s);
}
else if (action == ACTION_CLONE)
{
@ -204,7 +204,7 @@ public:
summon->SetHealth(me->GetHealth());
summon->CastSpell(summon, SPELL_SPAWN_EFFECT, true);
summon->SetReactState(REACT_PASSIVE);
summon->m_Events.AddEvent(new RestoreFight(summon), summon->m_Events.CalculateTime(2000));
summon->m_Events.AddEventAtOffset(new RestoreFight(summon), 2s);
}
void UpdateAI(uint32 diff) override

View File

@ -1120,7 +1120,7 @@ class spell_halion_twilight_realm_aura : public AuraScript
target->RemoveAurasDueToSpell(SPELL_FIERY_COMBUSTION, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL);
if (!GetTarget()->IsPlayer())
return;
GetTarget()->m_Events.AddEvent(new SendEncounterUnit(GetTarget()->ToPlayer()), GetTarget()->m_Events.CalculateTime(500));
GetTarget()->m_Events.AddEventAtOffset(new SendEncounterUnit(GetTarget()->ToPlayer()), 500ms);
}
void Register() override
@ -1153,7 +1153,7 @@ class spell_halion_leave_twilight_realm_aura : public AuraScript
if (!GetTarget()->IsPlayer())
return;
GetTarget()->m_Events.AddEvent(new SendEncounterUnit(GetTarget()->ToPlayer()), GetTarget()->m_Events.CalculateTime(500));
GetTarget()->m_Events.AddEventAtOffset(new SendEncounterUnit(GetTarget()->ToPlayer()), 500ms);
}
void Register() override

View File

@ -502,7 +502,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
me->CastSpell(me, RAID_MODE(SPELL_TRAITOR_KING_10, SPELL_TRAITOR_KING_25, SPELL_TRAITOR_KING_10, SPELL_TRAITOR_KING_25), true);
me->m_Events.AddEvent(new HideNpcEvent(*me), me->m_Events.CalculateTime(5000));
me->m_Events.AddEventAtOffset(new HideNpcEvent(*me), 5s);
}
bool CanAIAttack(Unit const* target) const override
@ -710,7 +710,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
me->m_Events.AddEvent(new HideNpcEvent(*me), me->m_Events.CalculateTime(5000));
me->m_Events.AddEventAtOffset(new HideNpcEvent(*me), 5s);
}
bool CanAIAttack(Unit const* target) const override

View File

@ -38,7 +38,7 @@ public:
_owner.GetMotionMaster()->Clear();
_owner.SetVisible(true);
_owner.NearTeleportTo(5300.53f, 1987.80f, 707.70f, 3.89f);
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, 2), _owner.m_Events.CalculateTime(1000));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, 2), 1s);
break;
case 2:
_owner.AI()->Talk(SAY_BATTERED_HILT_HALT);
@ -52,12 +52,12 @@ public:
{
quel->AI()->Talk(EMOTE_QUEL_SPAWN);
}
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, 4), _owner.m_Events.CalculateTime(3500));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, 4), 3500ms);
break;
case 4:
_owner.SetWalk(false);
_owner.GetMotionMaster()->MovePoint(0, 5337.53f, 1981.21f, 709.32f);
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, 5), _owner.m_Events.CalculateTime(6000));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, 5), 6s);
break;
case 5:
_owner.SetFacingTo(2.82f);
@ -66,7 +66,7 @@ public:
case 6:
if (InstanceScript* instance = _owner.GetInstanceScript())
instance->SetData(DATA_BATTERED_HILT, 6);
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, 7), _owner.m_Events.CalculateTime(2000));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, 7), 2s);
break;
case 7:
if (InstanceScript* instance = _owner.GetInstanceScript())
@ -77,7 +77,7 @@ public:
{
quel->AI()->Talk(EMOTE_QUEL_PREPARE);
}
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, 8), _owner.m_Events.CalculateTime(4000));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, 8), 4s);
break;
case 8:
_owner.SetReactState(REACT_AGGRESSIVE);
@ -87,23 +87,23 @@ public:
break;
case 9:
_owner.AI()->Talk(SAY_BATTERED_HILT_OUTRO1);
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, _eventId + 1), _owner.m_Events.CalculateTime(11000));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, _eventId + 1), 11s);
break;
case 10:
_owner.AI()->Talk(SAY_BATTERED_HILT_OUTRO2);
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, _eventId + 1), _owner.m_Events.CalculateTime(7500));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, _eventId + 1), 7500ms);
break;
case 11:
_owner.AI()->Talk(SAY_BATTERED_HILT_OUTRO3);
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, _eventId + 1), _owner.m_Events.CalculateTime(8000));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, _eventId + 1), 8s);
break;
case 12:
_owner.AI()->Talk(SAY_BATTERED_HILT_OUTRO4);
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, _eventId + 1), _owner.m_Events.CalculateTime(5000));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, _eventId + 1), 5s);
break;
case 13:
_owner.CastSpell((Unit*)nullptr, 73036, true);
_owner.m_Events.AddEvent(new UtherBatteredHiltEvent(_owner, _eventId + 1), _owner.m_Events.CalculateTime(3000));
_owner.m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(_owner, _eventId + 1), 3s);
break;
case 14:
{
@ -594,7 +594,7 @@ public:
if (Creature* c = instance->GetCreature(NPC_AltarBunnyGUID))
c->CastSpell(c, 70720, true);
if (Creature* c = instance->GetCreature(NPC_UtherGUID))
c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 1), c->m_Events.CalculateTime(3000));
c->m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(*c, 1), 3s);
break;
case 3:
if ((BatteredHiltStatus & BHSF_STARTED) == 0 || (BatteredHiltStatus & BHSF_THROWN))
@ -602,7 +602,7 @@ public:
BatteredHiltStatus |= BHSF_THROWN;
if (Creature* c = instance->GetCreature(NPC_UtherGUID))
{
c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 3), c->m_Events.CalculateTime(5500));
c->m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(*c, 3), 5500ms);
}
break;
case 4:
@ -614,7 +614,7 @@ public:
break;
case 5:
if (Creature* c = instance->GetCreature(NPC_UtherGUID))
c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 6), c->m_Events.CalculateTime(3000));
c->m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(*c, 6), 3s);
break;
case 6:
if (Creature* c = instance->GetCreature(NPC_QuelDelarGUID))
@ -726,7 +726,7 @@ public:
c->SetStandState(UNIT_STAND_STATE_STAND);
c->SetWalk(false);
c->GetMotionMaster()->MovePoint(0, 5313.92f, 1989.36f, 707.70f);
c->m_Events.AddEvent(new UtherBatteredHiltEvent(*c, 9), c->m_Events.CalculateTime(7000));
c->m_Events.AddEventAtOffset(new UtherBatteredHiltEvent(*c, 9), 7s);
}
}

View File

@ -1383,7 +1383,7 @@ class spell_pos_slave_trigger_closest : public SpellScript
{
c->DespawnOrUnsummon(7s);
c->AI()->Talk(0, p);
c->m_Events.AddEvent(new SlaveRunEvent(*c), c->m_Events.CalculateTime(3000));
c->m_Events.AddEventAtOffset(new SlaveRunEvent(*c), 3s);
}
}
}

View File

@ -160,7 +160,7 @@ public:
{
summon->SetRegeneratingHealth(false);
summon->SetReactState(REACT_PASSIVE);
summon->m_Events.AddEvent(new RestoreFight(summon), summon->m_Events.CalculateTime(3000));
summon->m_Events.AddEventAtOffset(new RestoreFight(summon), 3s);
if (!events.HasTimeUntilEvent(EVENT_COLOSSUS_HEALTH_2))
{
summon->SetHealth(summon->GetMaxHealth() / 2);

View File

@ -375,7 +375,7 @@ public:
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetReactState(REACT_AGGRESSIVE);
me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why
me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
me->m_Events.AddEventAtOffset(new StandUpEvent(*me), 1s);
DoAction(ACTION_REMOVE_INVOCATION);
me->SetHealth(1);
break;
@ -645,7 +645,7 @@ public:
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetReactState(REACT_AGGRESSIVE);
me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why
me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
me->m_Events.AddEventAtOffset(new StandUpEvent(*me), 1s);
DoAction(ACTION_REMOVE_INVOCATION);
me->SetHealth(1);
break;
@ -889,7 +889,7 @@ public:
summon->CastSpell(summon, SPELL_KINETIC_BOMB, true, nullptr, nullptr, me->GetGUID());
break;
case NPC_SHOCK_VORTEX:
summon->m_Events.AddEvent(new ShockVortexExplodeEvent(*summon), summon->m_Events.CalculateTime(4500));
summon->m_Events.AddEventAtOffset(new ShockVortexExplodeEvent(*summon), 4500ms);
break;
default:
break;
@ -939,7 +939,7 @@ public:
me->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
me->SetReactState(REACT_AGGRESSIVE);
me->ForceValuesUpdateAtIndex(UNIT_NPC_FLAGS); // was in sniff. don't ask why
me->m_Events.AddEvent(new StandUpEvent(*me), me->m_Events.CalculateTime(1000));
me->m_Events.AddEventAtOffset(new StandUpEvent(*me), 1s);
me->SetHealth(me->GetMaxHealth());
DoAction(ACTION_CAST_INVOCATION);
break;

View File

@ -373,7 +373,7 @@ class BattleExperienceEvent : public BasicEvent
{
public:
static uint32 const ExperiencedSpells[5];
static uint32 const ExperiencedTimes[5];
static Milliseconds const ExperiencedTimes[5];
BattleExperienceEvent(Creature* creature) : _creature(creature), _level(0) { }
@ -388,7 +388,8 @@ public:
_creature->CastSpell(_creature, ExperiencedSpells[_level], true);
if (_level < (_creature->GetMap()->IsHeroic() ? 4 : 3))
{
_creature->m_Events.AddEvent(this, timer + ExperiencedTimes[_level]);
Milliseconds nextExperienceEventTime = Milliseconds(timer) + ExperiencedTimes[_level];
_creature->m_Events.AddEventAtOffset(this, nextExperienceEventTime);
return false;
}
@ -401,7 +402,7 @@ private:
};
uint32 const BattleExperienceEvent::ExperiencedSpells[5] = { 0, SPELL_EXPERIENCED, SPELL_VETERAN, SPELL_ELITE, SPELL_ADDS_BERSERK };
uint32 const BattleExperienceEvent::ExperiencedTimes[5] = { 100000, 70000, 60000, 90000, 0 };
Milliseconds const BattleExperienceEvent::ExperiencedTimes[5] = { 100s, 70s, 60s, 90s, 0ms };
class PassengerController
{
@ -675,7 +676,7 @@ public:
else
{
uint32 teleportSpellId = _teamIdInInstance == TEAM_HORDE ? SPELL_TELEPORT_PLAYERS_ON_RESET_H : SPELL_TELEPORT_PLAYERS_ON_RESET_A;
me->m_Events.AddEvent(new ResetEncounterEvent(me, teleportSpellId, _instance->GetGuidData(DATA_ENEMY_GUNSHIP)), me->m_Events.CalculateTime(8000));
me->m_Events.AddEventAtOffset(new ResetEncounterEvent(me, teleportSpellId, _instance->GetGuidData(DATA_ENEMY_GUNSHIP)), 8s);
}
}
@ -1544,7 +1545,7 @@ struct gunship_npc_AI : public ScriptedAI
if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH && Slot)
{
me->SetFacingTo(Slot->TargetPosition.GetOrientation());
me->m_Events.AddEvent(new BattleExperienceEvent(me), me->m_Events.CalculateTime(BattleExperienceEvent::ExperiencedTimes[0]));
me->m_Events.AddEventAtOffset(new BattleExperienceEvent(me), BattleExperienceEvent::ExperiencedTimes[0]);
me->CastSpell(me, SPELL_BATTLE_EXPERIENCE, true);
me->SetReactState(REACT_AGGRESSIVE);
}
@ -1579,7 +1580,7 @@ struct npc_gunship_boarding_addAI : public ScriptedAI
{
SetSlotInfo(data);
me->SetReactState(REACT_PASSIVE);
me->m_Events.AddEvent(new DelayedMovementEvent(me, Slot->TargetPosition), me->m_Events.CalculateTime(3000 * (Index - SLOT_MARINE_1)));
me->m_Events.AddEventAtOffset(new DelayedMovementEvent(me, Slot->TargetPosition), Milliseconds(3000 * (Index - SLOT_MARINE_1)));
}
}
@ -1608,7 +1609,7 @@ struct npc_gunship_boarding_addAI : public ScriptedAI
if (type == POINT_MOTION_TYPE && pointId == EVENT_CHARGE_PREPATH && Slot)
{
me->SetFacingTo(Slot->TargetPosition.GetOrientation());
me->m_Events.AddEvent(new BattleExperienceEvent(me), me->m_Events.CalculateTime(BattleExperienceEvent::ExperiencedTimes[0]));
me->m_Events.AddEventAtOffset(new BattleExperienceEvent(me), BattleExperienceEvent::ExperiencedTimes[0]);
me->CastSpell(me, SPELL_BATTLE_EXPERIENCE, true);
me->SetReactState(REACT_AGGRESSIVE);

View File

@ -522,7 +522,7 @@ public:
darnavan->GetMotionMaster()->MoveIdle();
darnavan->StopMoving();
darnavan->SetReactState(REACT_PASSIVE);
darnavan->m_Events.AddEvent(new DaranavanMoveEvent(*darnavan), darnavan->m_Events.CalculateTime(10000));
darnavan->m_Events.AddEventAtOffset(new DaranavanMoveEvent(*darnavan), 10s);
darnavan->AI()->Talk(SAY_DARNAVAN_RESCUED);
if (Player* owner = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
{

View File

@ -384,7 +384,7 @@ public:
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetSpeed(MOVE_RUN, 4.28571f);
float moveTime = me->GetExactDist(&SindragosaFlyInPos) / (me->GetSpeed(MOVE_RUN) * 0.001f);
me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SindragosaLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250));
me->m_Events.AddEventAtOffset(new FrostwyrmLandEvent(*me, SindragosaLandPos), Milliseconds(uint32(moveTime) + 250));
me->GetMotionMaster()->MovePoint(POINT_FROSTWYRM_FLY_IN, SindragosaFlyInPos);
if (!instance->GetData(DATA_SINDRAGOSA_INTRO))
@ -478,7 +478,7 @@ public:
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_FROST_BOMB)
summon->m_Events.AddEvent(new FrostBombExplosion(summon, me->GetGUID()), summon->m_Events.CalculateTime(5500));
summon->m_Events.AddEventAtOffset(new FrostBombExplosion(summon, me->GetGUID()), 5500ms);
}
void SummonedCreatureDespawn(Creature* summon) override
@ -1079,7 +1079,7 @@ class spell_sindragosa_ice_tomb_trap_aura : public AuraScript
void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* c = GetCaster())
GetTarget()->m_Events.AddEvent(new IceTombSummonEvent(GetTarget(), c->GetGUID()), GetTarget()->m_Events.CalculateTime(500));
GetTarget()->m_Events.AddEventAtOffset(new IceTombSummonEvent(GetTarget(), c->GetGUID()), 500ms);
}
void ExtraRemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
@ -1245,7 +1245,7 @@ public:
me->setActive(true);
me->SetImmuneToPC(true);
float moveTime = me->GetExactDist(&SpinestalkerFlyPos) / (me->GetSpeed(MOVE_RUN) * 0.001f);
me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SpinestalkerLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250));
me->m_Events.AddEventAtOffset(new FrostwyrmLandEvent(*me, SpinestalkerLandPos), Milliseconds(uint32(moveTime) + 250));
me->SetDefaultMovementType(IDLE_MOTION_TYPE);
me->GetMotionMaster()->MoveIdle();
me->StopMoving();
@ -1376,7 +1376,7 @@ public:
me->setActive(true);
me->SetImmuneToPC(true);
float moveTime = me->GetExactDist(&RimefangFlyPos) / (me->GetSpeed(MOVE_RUN) * 0.001f);
me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, RimefangLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250));
me->m_Events.AddEventAtOffset(new FrostwyrmLandEvent(*me, RimefangLandPos), Milliseconds(uint32(moveTime) + 250));
me->SetDefaultMovementType(IDLE_MOTION_TYPE);
me->GetMotionMaster()->MoveIdle();
me->StopMoving();

View File

@ -552,7 +552,7 @@ public:
if (--_counter)
{
_owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(3000));
_owner->m_Events.AddEventAtOffset(this, 3s);
return false;
}
@ -830,8 +830,8 @@ public:
if (Creature* terenas = me->FindNearestCreature(NPC_TERENAS_MENETHIL_OUTRO, 50.0f))
terenas->DespawnOrUnsummon(1ms);
me->m_Events.AddEvent(new LichKingDeathEvent(*me), me->m_Events.CalculateTime(2500)); // die after spinning anim is over, so death anim is visible
me->m_Events.AddEvent(new LichKingMovieEvent(*me), me->m_Events.CalculateTime(11500));
me->m_Events.AddEventAtOffset(new LichKingDeathEvent(*me), 2500ms); // die after spinning anim is over, so death anim is visible
me->m_Events.AddEventAtOffset(new LichKingMovieEvent(*me), 11500ms);
}
if (!_bFordringMustFallYell && me->GetHealth() < 500000)
@ -862,7 +862,7 @@ public:
summon->CastSpell(summon, SPELL_RISEN_WITCH_DOCTOR_SPAWN, true);
summon->SetReactState(REACT_PASSIVE);
summon->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE);
summon->m_Events.AddEvent(new StartMovementEvent(me, summon), summon->m_Events.CalculateTime(5000));
summon->m_Events.AddEventAtOffset(new StartMovementEvent(me, summon), 5s);
break;
case NPC_RAGING_SPIRIT:
summon->SetHomePosition(CenterPosition);
@ -872,7 +872,7 @@ public:
summon->SetReactState(REACT_PASSIVE);
summon->GetMotionMaster()->MoveRandom(10.0f);
if (_phase == PHASE_THREE)
summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000));
summon->m_Events.AddEventAtOffset(new VileSpiritActivateEvent(summon), 15s);
break;
}
case NPC_STRANGULATE_VEHICLE:
@ -1189,7 +1189,7 @@ public:
if (summon->GetEntry() == NPC_VILE_SPIRIT)
{
summon->m_Events.KillAllEvents(true);
summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(55000));
summon->m_Events.AddEventAtOffset(new VileSpiritActivateEvent(summon), 55s);
summon->GetMotionMaster()->Clear(true);
summon->StopMoving();
summon->SetReactState(REACT_PASSIVE);
@ -1213,7 +1213,7 @@ public:
{
spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true); // summons bombs randomly
spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players
spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3000));
spawner->m_Events.AddEventAtOffset(new TriggerWickedSpirit(spawner), 3s);
terenas->SetImmuneToAll(true); // to avoid being healed by player trinket procs. terenas' health doesn't matter on heroic
}
}

View File

@ -417,13 +417,13 @@ public:
{
if (summon->GetEntry() == NPC_DREAM_PORTAL_PRE_EFFECT)
{
summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_DREAM_PORTAL, me->GetGUID(), 6s), summon->m_Events.CalculateTime(15000));
summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_DREAM_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000));
summon->m_Events.AddEventAtOffset(new DelayedCastEvent(summon, SPELL_SUMMON_DREAM_PORTAL, me->GetGUID(), 6s), 15s);
summon->m_Events.AddEventAtOffset(new AuraRemoveEvent(summon, SPELL_DREAM_PORTAL_VISUAL_PRE), 15s);
}
else if (summon->GetEntry() == NPC_NIGHTMARE_PORTAL_PRE_EFFECT)
{
summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_SUMMON_NIGHTMARE_PORTAL, me->GetGUID(), 6s), summon->m_Events.CalculateTime(15000));
summon->m_Events.AddEvent(new AuraRemoveEvent(summon, SPELL_NIGHTMARE_PORTAL_VISUAL_PRE), summon->m_Events.CalculateTime(15000));
summon->m_Events.AddEventAtOffset(new DelayedCastEvent(summon, SPELL_SUMMON_NIGHTMARE_PORTAL, me->GetGUID(), 6s), 15s);
summon->m_Events.AddEventAtOffset(new AuraRemoveEvent(summon, SPELL_NIGHTMARE_PORTAL_VISUAL_PRE), 15s);
}
}
@ -579,7 +579,7 @@ public:
void DoAction(int32 action) override
{
if (action == ACTION_DEATH)
me->m_Events.AddEvent(new ValithriaDespawner(me), me->m_Events.CalculateTime(5000));
me->m_Events.AddEventAtOffset(new ValithriaDespawner(me), 5s);
else if (action == ACTION_ENTER_COMBAT)
{
if (!me->IsInCombat())
@ -750,7 +750,7 @@ public:
void JustSummoned(Creature* summon) override
{
if (summon->GetEntry() == NPC_COLUMN_OF_FROST)
summon->m_Events.AddEvent(new DelayedCastEvent(summon, SPELL_COLUMN_OF_FROST_DAMAGE, ObjectGuid::Empty, 8s), summon->m_Events.CalculateTime(2000));
summon->m_Events.AddEventAtOffset(new DelayedCastEvent(summon, SPELL_COLUMN_OF_FROST_DAMAGE, ObjectGuid::Empty, 8s), 2s);
else if (summon->GetEntry() == NPC_MANA_VOID)
summon->DespawnOrUnsummon(36s);
}

View File

@ -1017,15 +1017,15 @@ public:
if (Creature* crok = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_CROK_SCOURGEBANE))) // _isEventDone = true, setActive(false)
crok->AI()->DoAction(ACTION_RESET_EVENT);
uint64 delay = 6000;
Milliseconds delay = 6s;
for (uint32 i = 0; i < 4; ++i)
if (Creature* crusader = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_CAPTAIN_ARNATH + i)))
if (crusader->IsAlive())
{
if (crusader->GetEntry() == crusader->GetCreatureData()->id1)
{
crusader->m_Events.AddEvent(new CaptainSurviveTalk(*crusader), crusader->m_Events.CalculateTime(delay));
delay += 6000;
crusader->m_Events.AddEventAtOffset(new CaptainSurviveTalk(*crusader), delay);
delay += 6s;
}
else
Unit::Kill(crusader, crusader);

View File

@ -513,7 +513,7 @@ public:
spellId = BLOOD_BEAM_VISUAL_LLEG;
else
spellId = BLOOD_BEAM_VISUAL_RLEG;
creature->m_Events.AddEvent(new DelayedCastMincharEvent(creature, spellId), creature->m_Events.CalculateTime(1000));
creature->m_Events.AddEventAtOffset(new DelayedCastMincharEvent(creature, spellId), 1s);
}
break;
case NPC_SKYBREAKER_DECKHAND:
@ -608,7 +608,7 @@ public:
std::string name2("Kor'kron ");
if (!creature->GetTransport() && creature->GetPositionZ() <= 205.0f && creature->GetExactDist2d(-439.0f, 2210.0f) <= 150.0f && (creature->GetEntry() == 37544 || creature->GetEntry() == 37545 || creature->GetName().compare(0, name1.length(), name1) == 0 || creature->GetName().compare(0, name2.length(), name2) == 0))
if (!creature->GetLootRecipient())
creature->m_Events.AddEvent(new RespawnEvent(*creature), creature->m_Events.CalculateTime(3000));
creature->m_Events.AddEventAtOffset(new RespawnEvent(*creature), 3s);
switch (creature->GetEntry())
{

View File

@ -727,7 +727,7 @@ public:
{
c->SetFaction(pPlayer->GetFaction());
//pPlayer->CastCustomSpell(60683, SPELLVALUE_BASE_POINT0, 1, c, true);
c->m_Events.AddEvent(new EoEDrakeEnterVehicleEvent(*c, pPlayer->GetGUID()), c->m_Events.CalculateTime(500));
c->m_Events.AddEventAtOffset(new EoEDrakeEnterVehicleEvent(*c, pPlayer->GetGUID()), 500ms);
AttackStart(c);
}
}

View File

@ -89,7 +89,7 @@ public:
c->SetCanFly(true);
c->SetFaction(pPlayer->GetFaction());
//pPlayer->CastCustomSpell(60683, SPELLVALUE_BASE_POINT0, 1, c, true);
c->m_Events.AddEvent(new EoEDrakeEnterVehicleEvent(*c, pPlayer->GetGUID()), c->m_Events.CalculateTime(500));
c->m_Events.AddEventAtOffset(new EoEDrakeEnterVehicleEvent(*c, pPlayer->GetGUID()), 500ms);
}
}
}

View File

@ -171,7 +171,7 @@ struct boss_anomalus : public BossAI
me->CastSpell(me, SPELL_CREATE_RIFT, false);
me->CastSpell(me, SPELL_RIFT_SHIELD, true);
me->m_Events.AddEvent(new ChargeRifts(me), me->m_Events.CalculateTime(1000));
me->m_Events.AddEventAtOffset(new ChargeRifts(me), 1s);
events.DelayEvents(46s);
//As we just spawned an empowered spawn a normal one
events.ScheduleEvent(EVENT_ANOMALUS_SPAWN_RIFT, IsHeroic() ? 15s : 25s);

View File

@ -106,338 +106,310 @@ enum Yells
EMOTE_BERSEKER_STANCE = 8,
};
class boss_bjarngrim : public CreatureScript
struct boss_bjarngrim : public npc_escortAI
{
public:
boss_bjarngrim() : CreatureScript("boss_bjarngrim") { }
CreatureAI* GetAI(Creature* creature) const override
boss_bjarngrim(Creature* creature) : npc_escortAI(creature), summons(creature)
{
return GetHallsOfLightningAI<boss_bjarngrimAI>(creature);
m_pInstance = creature->GetInstanceScript();
// Init waypoints
AddWaypoint(1, 1262.18f, 99.3f, 33.5f, 0);
AddWaypoint(2, 1281.6f, 99.5f, 33.5f, 0);
AddWaypoint(3, 1311.7f, 99.4f, 40.1f, 0);
AddWaypoint(4, 1332.5f, 99.7f, 40.18f, 0);
AddWaypoint(5, 1311.7f, 99.4f, 40.1f, 0);
AddWaypoint(6, 1281.6f, 99.5f, 33.5f, 0);
AddWaypoint(7, 1262.18f, 99.3f, 33.5f, 0);
AddWaypoint(8, 1262, -26.9f, 33.5f, 0);
AddWaypoint(9, 1281.2f, -26.8f, 33.5f, 0);
AddWaypoint(10, 1311.3f, -26.9f, 40.03f, 0);
AddWaypoint(11, 1332, -26.6f, 40.18f, 0);
AddWaypoint(12, 1311.3f, -26.9f, 40.03f, 0);
AddWaypoint(13, 1281.2f, -26.8f, 33.5f, 0);
AddWaypoint(14, 1262, -26.9f, 33.5f, 0);
Start(true, ObjectGuid::Empty, nullptr, false, true);
}
struct boss_bjarngrimAI : public npc_escortAI
void Reset() override
{
boss_bjarngrimAI(Creature* creature) : npc_escortAI(creature), summons(creature)
events.Reset();
summons.DespawnAll();
for (uint8 i = 0; i < 2; ++i)
if (Creature* dwarf = me->SummonCreature(NPC_STORMFORGED_LIEUTENANT, me->GetPositionX() + urand(4, 12), me->GetPositionY() + urand(4, 12), me->GetPositionZ()))
{
dwarf->GetMotionMaster()->MoveFollow(me, 3, rand_norm() * 2 * 3.14f);
summons.Summon(dwarf);
}
me->RemoveAllAuras();
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
if (m_pInstance)
m_pInstance->SetBossState(DATA_BJARNGRIM, NOT_STARTED);
DoCastSelf(SPELL_BATTLE_STANCE, true);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
}
void JustEngagedWith(Unit*) override
{
me->SetInCombatWithZone();
Talk(SAY_AGGRO);
RollStance(STANCE_BATTLE);
events.ScheduleEvent(EVENT_BJARNGRIM_CHANGE_STANCE, 20s, 0);
// DEFENSIVE STANCE
events.ScheduleEvent(EVENT_BJARNGRIM_REFLECTION, 8s, STANCE_DEFENSIVE);
events.ScheduleEvent(EVENT_BJARNGRIM_KNOCK, 16s, STANCE_DEFENSIVE);
events.ScheduleEvent(EVENT_BJARNGRIM_IRONFORM, 12s, STANCE_DEFENSIVE);
// BERSERKER STANCE
events.ScheduleEvent(EVENT_BJARNGRIM_INTERCEPT, 23s, STANCE_BERSERKER);
events.ScheduleEvent(EVENT_BJARNGRIM_CLEAVE, 25s, STANCE_BERSERKER);
events.ScheduleEvent(EVENT_BJARNGRIM_WHIRLWIND, 26s, STANCE_BERSERKER);
// BATTLE STANCE
events.ScheduleEvent(EVENT_BJARNGRIM_PUMMEL, 5s, STANCE_BATTLE);
events.ScheduleEvent(EVENT_BJARNGRIM_MORTAL_STRIKE, 24s, STANCE_BATTLE);
events.ScheduleEvent(EVENT_BJARNGRIM_SLAM, 30s, STANCE_BATTLE);
if (m_pInstance)
{
m_pInstance = creature->GetInstanceScript();
m_pInstance->SetBossState(DATA_BJARNGRIM, IN_PROGRESS);
m_pInstance->SetData(DATA_BJARNGRIM_ACHIEVEMENT, me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE));
}
}
// Init waypoints
AddWaypoint(1, 1262.18f, 99.3f, 33.5f, 0);
AddWaypoint(2, 1281.6f, 99.5f, 33.5f, 0);
AddWaypoint(3, 1311.7f, 99.4f, 40.1f, 0);
AddWaypoint(4, 1332.5f, 99.7f, 40.18f, 0);
AddWaypoint(5, 1311.7f, 99.4f, 40.1f, 0);
AddWaypoint(6, 1281.6f, 99.5f, 33.5f, 0);
AddWaypoint(7, 1262.18f, 99.3f, 33.5f, 0);
AddWaypoint(8, 1262, -26.9f, 33.5f, 0);
AddWaypoint(9, 1281.2f, -26.8f, 33.5f, 0);
AddWaypoint(10, 1311.3f, -26.9f, 40.03f, 0);
AddWaypoint(11, 1332, -26.6f, 40.18f, 0);
AddWaypoint(12, 1311.3f, -26.9f, 40.03f, 0);
AddWaypoint(13, 1281.2f, -26.8f, 33.5f, 0);
AddWaypoint(14, 1262, -26.9f, 33.5f, 0);
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Start(true, ObjectGuid::Empty, nullptr, false, true);
Talk(SAY_SLAY);
}
void JustDied(Unit*) override
{
Talk(SAY_DEATH);
if (m_pInstance)
m_pInstance->SetBossState(DATA_BJARNGRIM, DONE);
}
void RemoveStanceAura(uint8 stance)
{
switch (stance)
{
case STANCE_DEFENSIVE:
me->RemoveAura(SPELL_DEFENSIVE_STANCE);
me->RemoveAura(SPELL_DEFENSIVE_AURA);
break;
case STANCE_BERSERKER:
me->RemoveAura(SPELL_BERSERKER_STANCE);
me->RemoveAura(SPELL_BERSERKER_AURA);
break;
case STANCE_BATTLE:
me->RemoveAura(SPELL_BATTLE_STANCE);
me->RemoveAura(SPELL_BATTLE_AURA);
break;
}
}
void RollStance(uint8 stance, uint8 force = 0)
{
if (urand(0, 1))
stance = (++stance == 4 ? 1 : stance);
else
stance = (--stance == 0 ? 3 : stance);
if (force)
stance = force;
switch (stance)
{
case STANCE_DEFENSIVE:
Talk(SAY_DEFENSIVE_STANCE);
DoCastSelf(SPELL_DEFENSIVE_STANCE, true);
DoCastSelf(SPELL_DEFENSIVE_AURA, true);
events.DelayEvents(20s, STANCE_BERSERKER);
events.DelayEvents(20s, STANCE_BATTLE);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
break;
case STANCE_BERSERKER:
Talk(SAY_BERSERKER_STANCE);
DoCastSelf(SPELL_BERSERKER_STANCE, true);
DoCastSelf(SPELL_BERSERKER_AURA, true);
events.DelayEvents(20s, STANCE_DEFENSIVE);
events.DelayEvents(20s, STANCE_BATTLE);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
break;
case STANCE_BATTLE:
Talk(SAY_BATTLE_STANCE);
DoCastSelf(SPELL_BATTLE_STANCE, true);
DoCastSelf(SPELL_BATTLE_AURA, true);
events.DelayEvents(20s, STANCE_BERSERKER);
events.DelayEvents(20s, STANCE_DEFENSIVE);
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
break;
}
m_uiStance = stance;
}
void WaypointReached(uint32 Point) override
{
if (Point == 1 || Point == 8)
DoCastSelf(SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
else if (Point == 7 || Point == 14)
me->RemoveAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE);
}
void UpdateEscortAI(uint32 diff) override
{
if (!me->IsInCombat())
return;
// Return since we have no target
if (!UpdateVictim())
{
Reset();
return;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_BJARNGRIM_CHANGE_STANCE:
// roll new stance
RemoveStanceAura(m_uiStance);
RollStance(m_uiStance);
events.Repeat(20s);
break;
// DEFENSIVE STANCE
case EVENT_BJARNGRIM_REFLECTION:
DoCastSelf(SPELL_BJARNGRIM_REFLETION, true);
events.Repeat(8s, 9s);
break;
case EVENT_BJARNGRIM_PUMMEL:
DoCastVictim(SPELL_PUMMEL);
events.Repeat(10s, 11s);
break;
case EVENT_BJARNGRIM_KNOCK:
DoCastAOE(SPELL_KNOCK_AWAY);
events.Repeat(20s, 21s);
break;
case EVENT_BJARNGRIM_IRONFORM:
DoCastSelf(SPELL_IRONFORM, true);
events.Repeat(18s, 23s);
break;
// BERSERKER STANCE
case EVENT_BJARNGRIM_MORTAL_STRIKE:
DoCastVictim(SPELL_MORTAL_STRIKE);
events.Repeat(10s);
break;
case EVENT_BJARNGRIM_WHIRLWIND:
DoCastSelf(SPELL_WHIRLWIND, true);
events.Repeat(25s);
break;
// BATTLE STANCE
case EVENT_BJARNGRIM_INTERCEPT:
DoCastRandomTarget(SPELL_INTERCEPT, 0, 40.0f, false, true);
events.Repeat(30s);
break;
case EVENT_BJARNGRIM_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
events.Repeat(25s);
break;
case EVENT_BJARNGRIM_SLAM:
DoCastVictim(SPELL_SLAM);
events.Repeat(10s, 12s);
break;
}
DoMeleeAttackIfReady();
}
private:
InstanceScript* m_pInstance;
EventMap events;
SummonList summons;
uint8 m_uiStance;
void Reset() override
{
events.Reset();
summons.DespawnAll();
for (uint8 i = 0; i < 2; ++i)
if (Creature* dwarf = me->SummonCreature(NPC_STORMFORGED_LIEUTENANT, me->GetPositionX() + urand(4, 12), me->GetPositionY() + urand(4, 12), me->GetPositionZ()))
{
dwarf->GetMotionMaster()->MoveFollow(me, 3, rand_norm() * 2 * 3.14f);
summons.Summon(dwarf);
}
me->RemoveAllAuras();
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
if (m_pInstance)
m_pInstance->SetData(TYPE_BJARNGRIM, NOT_STARTED);
me->CastSpell(me, SPELL_BATTLE_STANCE, true);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
}
void JustEngagedWith(Unit*) override
{
me->SetInCombatWithZone();
Talk(SAY_AGGRO);
RollStance(STANCE_BATTLE);
events.ScheduleEvent(EVENT_BJARNGRIM_CHANGE_STANCE, 20s, 0);
// DEFENSIVE STANCE
events.ScheduleEvent(EVENT_BJARNGRIM_REFLECTION, 8s, STANCE_DEFENSIVE);
events.ScheduleEvent(EVENT_BJARNGRIM_KNOCK, 16s, STANCE_DEFENSIVE);
events.ScheduleEvent(EVENT_BJARNGRIM_IRONFORM, 12s, STANCE_DEFENSIVE);
// BERSERKER STANCE
events.ScheduleEvent(EVENT_BJARNGRIM_INTERCEPT, 23s, STANCE_BERSERKER);
events.ScheduleEvent(EVENT_BJARNGRIM_CLEAVE, 25s, STANCE_BERSERKER);
events.ScheduleEvent(EVENT_BJARNGRIM_WHIRLWIND, 26s, STANCE_BERSERKER);
// BATTLE STANCE
events.ScheduleEvent(EVENT_BJARNGRIM_PUMMEL, 5s, STANCE_BATTLE);
events.ScheduleEvent(EVENT_BJARNGRIM_MORTAL_STRIKE, 24s, STANCE_BATTLE);
events.ScheduleEvent(EVENT_BJARNGRIM_SLAM, 30s, STANCE_BATTLE);
if (m_pInstance)
{
m_pInstance->SetData(TYPE_BJARNGRIM, IN_PROGRESS);
m_pInstance->SetData(DATA_BJARNGRIM_ACHIEVEMENT, me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE));
}
}
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Talk(SAY_SLAY);
}
void JustDied(Unit*) override
{
Talk(SAY_DEATH);
if (m_pInstance)
m_pInstance->SetData(TYPE_BJARNGRIM, DONE);
}
void RemoveStanceAura(uint8 stance)
{
switch (stance)
{
case STANCE_DEFENSIVE:
me->RemoveAura(SPELL_DEFENSIVE_STANCE);
me->RemoveAura(SPELL_DEFENSIVE_AURA);
break;
case STANCE_BERSERKER:
me->RemoveAura(SPELL_BERSERKER_STANCE);
me->RemoveAura(SPELL_BERSERKER_AURA);
break;
case STANCE_BATTLE:
me->RemoveAura(SPELL_BATTLE_STANCE);
me->RemoveAura(SPELL_BATTLE_AURA);
break;
}
}
void RollStance(uint8 stance, uint8 force = 0)
{
if (urand(0, 1))
stance = (++stance == 4 ? 1 : stance);
else
stance = (--stance == 0 ? 3 : stance);
if (force)
stance = force;
switch (stance)
{
case STANCE_DEFENSIVE:
Talk(SAY_DEFENSIVE_STANCE);
me->CastSpell(me, SPELL_DEFENSIVE_STANCE, true);
me->CastSpell(me, SPELL_DEFENSIVE_AURA, true);
events.DelayEvents(20s, STANCE_BERSERKER);
events.DelayEvents(20s, STANCE_BATTLE);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
break;
case STANCE_BERSERKER:
Talk(SAY_BERSERKER_STANCE);
me->CastSpell(me, SPELL_BERSERKER_STANCE, true);
me->CastSpell(me, SPELL_BERSERKER_AURA, true);
events.DelayEvents(20s, STANCE_DEFENSIVE);
events.DelayEvents(20s, STANCE_BATTLE);
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
break;
case STANCE_BATTLE:
Talk(SAY_BATTLE_STANCE);
me->CastSpell(me, SPELL_BATTLE_STANCE, true);
me->CastSpell(me, SPELL_BATTLE_AURA, true);
events.DelayEvents(20s, STANCE_BERSERKER);
events.DelayEvents(20s, STANCE_DEFENSIVE);
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
break;
}
m_uiStance = stance;
}
void WaypointReached(uint32 Point) override
{
if (Point == 1 || Point == 8)
me->CastSpell(me, SPELL_TEMPORARY_ELECTRICAL_CHARGE, true);
else if (Point == 7 || Point == 14)
me->RemoveAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE);
}
void UpdateEscortAI(uint32 diff) override
{
if (!me->IsInCombat())
return;
// Return since we have no target
if (!UpdateVictim())
{
Reset();
return;
}
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_BJARNGRIM_CHANGE_STANCE:
// roll new stance
RemoveStanceAura(m_uiStance);
RollStance(m_uiStance);
events.Repeat(20s);
break;
///////////////////////////////////////////////////////
///// DEFENSIVE STANCE
///////////////////////////////////////////////////////
case EVENT_BJARNGRIM_REFLECTION:
me->CastSpell(me, SPELL_BJARNGRIM_REFLETION, true);
events.Repeat(8s, 9s);
break;
case EVENT_BJARNGRIM_PUMMEL:
me->CastSpell(me->GetVictim(), SPELL_PUMMEL, false);
events.Repeat(10s, 11s);
break;
case EVENT_BJARNGRIM_KNOCK:
me->CastSpell(me, SPELL_KNOCK_AWAY, false);
events.Repeat(20s, 21s);
break;
case EVENT_BJARNGRIM_IRONFORM:
me->CastSpell(me, SPELL_IRONFORM, true);
events.Repeat(18s, 23s);
break;
///////////////////////////////////////////////////////
///// BERSERKER STANCE
///////////////////////////////////////////////////////
case EVENT_BJARNGRIM_MORTAL_STRIKE:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
events.Repeat(10s);
break;
case EVENT_BJARNGRIM_WHIRLWIND:
me->CastSpell(me, SPELL_WHIRLWIND, true);
events.Repeat(25s);
break;
///////////////////////////////////////////////////////
///// BATTLE STANCE
///////////////////////////////////////////////////////
case EVENT_BJARNGRIM_INTERCEPT:
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
me->CastSpell(target, SPELL_INTERCEPT, true);
events.Repeat(30s);
break;
case EVENT_BJARNGRIM_CLEAVE:
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
events.Repeat(25s);
break;
case EVENT_BJARNGRIM_SLAM:
me->CastSpell(me->GetVictim(), SPELL_SLAM, false);
events.Repeat(10s, 12s);
break;
}
DoMeleeAttackIfReady();
}
};
};
class npc_stormforged_lieutenant : public CreatureScript
struct npc_stormforged_lieutenant : public ScriptedAI
{
public:
npc_stormforged_lieutenant() : CreatureScript("npc_stormforged_lieutenant") { }
npc_stormforged_lieutenant(Creature* creature) : ScriptedAI(creature) { }
CreatureAI* GetAI(Creature* creature) const override
void Reset() override
{
return GetHallsOfLightningAI<npc_stormforged_lieutenantAI>(creature);
if (me->IsSummon())
BjarngrimGUID = me->ToTempSummon()->GetSummonerGUID();
else
BjarngrimGUID.Clear();
}
struct npc_stormforged_lieutenantAI : public ScriptedAI
void JustEngagedWith(Unit*) override
{
npc_stormforged_lieutenantAI(Creature* creature) : ScriptedAI(creature) { }
events.ScheduleEvent(EVENT_ARC_WELD, 2s);
events.ScheduleEvent(EVENT_RENEW_STEEL, 10s, 11s);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_ARC_WELD:
me->CastSpell(me->GetVictim(), SPELL_ARC_WELD, true);
events.Repeat(20s);
break;
case EVENT_RENEW_STEEL:
if (Creature* bjarngrim = ObjectAccessor::GetCreature(*me, BjarngrimGUID))
if (bjarngrim->IsAlive())
me->CastSpell(bjarngrim, me->GetMap()->IsHeroic() ? SPELL_RENEW_STEEL_H : SPELL_RENEW_STEEL_N, true);
events.Repeat(10s, 14s);
break;
}
DoMeleeAttackIfReady();
}
private:
EventMap events;
ObjectGuid BjarngrimGUID;
void Reset() override
{
if (me->IsSummon())
BjarngrimGUID = me->ToTempSummon()->GetSummonerGUID();
else
BjarngrimGUID.Clear();
}
void JustEngagedWith(Unit*) override
{
events.ScheduleEvent(EVENT_ARC_WELD, 2s);
events.ScheduleEvent(EVENT_RENEW_STEEL, 10s, 11s);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_ARC_WELD:
me->CastSpell(me->GetVictim(), SPELL_ARC_WELD, true);
events.Repeat(20s);
break;
case EVENT_RENEW_STEEL:
if (Creature* bjarngrim = ObjectAccessor::GetCreature(*me, BjarngrimGUID))
if (bjarngrim->IsAlive())
me->CastSpell(bjarngrim, me->GetMap()->IsHeroic() ? SPELL_RENEW_STEEL_H : SPELL_RENEW_STEEL_N, true);
events.Repeat(10s, 14s);
break;
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_bjarngrim()
{
new boss_bjarngrim();
new npc_stormforged_lieutenant();
RegisterHallOfLightningCreatureAI(boss_bjarngrim);
RegisterHallOfLightningCreatureAI(npc_stormforged_lieutenant);
}

View File

@ -25,10 +25,8 @@
enum IonarSpells
{
SPELL_BALL_LIGHTNING_N = 52780,
SPELL_BALL_LIGHTNING_H = 59800,
SPELL_STATIC_OVERLOAD_N = 52658,
SPELL_STATIC_OVERLOAD_H = 59795,
SPELL_BALL_LIGHTNING = 52780,
SPELL_STATIC_OVERLOAD = 52658,
SPELL_STATIC_OVERLOAD_KNOCK = 53337,
SPELL_DISPERSE = 52770,
@ -36,8 +34,7 @@ enum IonarSpells
SPELL_SPARK_DESPAWN = 52776,
//Spark of Ionar
SPELL_SPARK_VISUAL_TRIGGER_N = 52667,
SPELL_SPARK_VISUAL_TRIGGER_H = 59833,
SPELL_SPARK_VISUAL_TRIGGER = 52667,
SPELL_RANDOM_LIGHTNING = 52663,
};
@ -68,211 +65,160 @@ enum IonarEvents
EVENT_RESTORE = 5,
};
class boss_ionar : public CreatureScript
struct boss_ionar : public BossAI
{
public:
boss_ionar() : CreatureScript("boss_ionar") { }
boss_ionar(Creature* creature) : BossAI(creature, DATA_IONAR) { }
CreatureAI* GetAI(Creature* creature) const override
void Reset() override
{
return GetHallsOfLightningAI<boss_ionarAI>(creature);
_Reset();
me->SetVisible(true);
ScheduleHealthCheckEvent(50, [&] {
DoCastSelf(SPELL_DISPERSE);
});
}
struct boss_ionarAI : public ScriptedAI
void ScheduleEvents(bool spark)
{
boss_ionarAI(Creature* creature) : ScriptedAI(creature), summons(creature)
events.SetPhase(1);
if (!spark)
events.RescheduleEvent(EVENT_CHECK_HEALTH, 1s, 0, 1);
events.RescheduleEvent(EVENT_BALL_LIGHTNING, 10s, 0, 1);
events.RescheduleEvent(EVENT_STATIC_OVERLOAD, 5s, 0, 1);
}
void JustEngagedWith(Unit*) override
{
_JustEngagedWith();
Talk(SAY_AGGRO);
ScheduleEvents(false);
}
void JustDied(Unit*) override
{
_JustDied();
Talk(SAY_DEATH);
}
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Talk(SAY_SLAY);
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
if (spell->Id == SPELL_DISPERSE)
Split();
}
void Split()
{
Talk(SAY_SPLIT);
for (uint8 i = 0; i < 5; ++i)
{
m_pInstance = creature->GetInstanceScript();
}
InstanceScript* m_pInstance;
EventMap events;
SummonList summons;
uint8 HealthCheck;
void Reset() override
{
HealthCheck = 50;
events.Reset();
summons.DespawnAll();
me->SetVisible(true);
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, NOT_STARTED);
}
void ScheduleEvents(bool spark)
{
events.SetPhase(1);
if (!spark)
events.RescheduleEvent(EVENT_CHECK_HEALTH, 1s, 0, 1);
events.RescheduleEvent(EVENT_BALL_LIGHTNING, 10s, 0, 1);
events.RescheduleEvent(EVENT_STATIC_OVERLOAD, 5s, 0, 1);
}
void JustEngagedWith(Unit*) override
{
me->SetInCombatWithZone();
Talk(SAY_AGGRO);
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, IN_PROGRESS);
ScheduleEvents(false);
}
void JustDied(Unit*) override
{
Talk(SAY_DEATH);
summons.DespawnAll();
if (m_pInstance)
m_pInstance->SetData(TYPE_IONAR, DONE);
}
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Talk(SAY_SLAY);
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
if (spell->Id == SPELL_DISPERSE)
Split();
}
void Split()
{
Talk(SAY_SPLIT);
Creature* spark;
for (uint8 i = 0; i < 5; ++i)
if (Creature* spark = me->SummonCreature(NPC_SPARK_OF_IONAR, me->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 20000))
{
if ((spark = me->SummonCreature(NPC_SPARK_OF_IONAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 20000)))
spark->CastSpell(spark, SPELL_SPARK_VISUAL_TRIGGER, true);
spark->CastSpell(spark, SPELL_RANDOM_LIGHTNING, true);
spark->SetUnitFlag(UNIT_FLAG_PACIFIED | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
spark->SetHomePosition(me->GetPosition());
if (Player* tgt = SelectTargetFromPlayerList(100))
spark->GetMotionMaster()->MoveFollow(tgt, 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
}
}
me->SetVisible(false);
me->SetControlled(true, UNIT_STATE_STUNNED);
events.SetPhase(2);
events.ScheduleEvent(EVENT_CALL_SPARKS, 15s, 0, 2);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_BALL_LIGHTNING:
DoCastRandomTarget(SPELL_BALL_LIGHTNING, 1, 0.0f, false);
events.Repeat(10s, 11s);
break;
case EVENT_STATIC_OVERLOAD:
DoCastRandomTarget(SPELL_STATIC_OVERLOAD);
events.Repeat(5s, 6s);
break;
case EVENT_CALL_SPARKS:
{
summons.Summon(spark);
spark->CastSpell(spark, me->GetMap()->IsHeroic() ? SPELL_SPARK_VISUAL_TRIGGER_H : SPELL_SPARK_VISUAL_TRIGGER_N, true);
spark->CastSpell(spark, SPELL_RANDOM_LIGHTNING, true);
spark->SetUnitFlag(UNIT_FLAG_PACIFIED | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_NON_ATTACKABLE);
spark->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0);
if (Player* tgt = SelectTargetFromPlayerList(100))
spark->GetMotionMaster()->MoveFollow(tgt, 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
}
}
me->SetVisible(false);
me->SetControlled(true, UNIT_STATE_STUNNED);
events.SetPhase(2);
events.ScheduleEvent(EVENT_CALL_SPARKS, 15s, 0, 2);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_BALL_LIGHTNING:
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
me->CastSpell(target, me->GetMap()->IsHeroic() ? SPELL_BALL_LIGHTNING_H : SPELL_BALL_LIGHTNING_N, false);
events.Repeat(10s, 11s);
break;
case EVENT_STATIC_OVERLOAD:
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
me->CastSpell(target, me->GetMap()->IsHeroic() ? SPELL_STATIC_OVERLOAD_H : SPELL_STATIC_OVERLOAD_N, false);
events.Repeat(5s, 6s);
break;
case EVENT_CHECK_HEALTH:
if (HealthBelowPct(HealthCheck))
me->CastSpell(me, SPELL_DISPERSE, false);
events.Repeat(1s);
return;
case EVENT_CALL_SPARKS:
{
EntryCheckPredicate pred(NPC_SPARK_OF_IONAR);
summons.DoAction(ACTION_CALLBACK, pred);
events.ScheduleEvent(EVENT_RESTORE, 2s, 0, 2);
return;
}
case EVENT_RESTORE:
EntryCheckPredicate pred(NPC_SPARK_OF_IONAR);
summons.DoAction(ACTION_SPARK_DESPAWN, pred);
me->SetVisible(true);
me->SetControlled(false, UNIT_STATE_STUNNED);
ScheduleEvents(true);
summons.DoAction(ACTION_CALLBACK, pred);
events.ScheduleEvent(EVENT_RESTORE, 2s, 0, 2);
return;
}
}
case EVENT_RESTORE:
EntryCheckPredicate pred(NPC_SPARK_OF_IONAR);
summons.DoAction(ACTION_SPARK_DESPAWN, pred);
DoMeleeAttackIfReady();
me->SetVisible(true);
me->SetControlled(false, UNIT_STATE_STUNNED);
ScheduleEvents(true);
return;
}
};
DoMeleeAttackIfReady();
}
};
class npc_spark_of_ionar : public CreatureScript
struct npc_spark_of_ionar : public ScriptedAI
{
public:
npc_spark_of_ionar() : CreatureScript("npc_spark_of_ionar") { }
npc_spark_of_ionar(Creature* creature) : ScriptedAI(creature) { }
CreatureAI* GetAI(Creature* creature) const override
void MoveInLineOfSight(Unit*) override { }
void UpdateAI(uint32) override { }
void AttackStart(Unit* /*who*/) override { }
void Reset() override { returning = false; }
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
return GetHallsOfLightningAI<npc_spark_of_ionarAI>(creature);
damage = 0;
}
struct npc_spark_of_ionarAI : public ScriptedAI
void DoAction(int32 param) override
{
npc_spark_of_ionarAI(Creature* creature) : ScriptedAI(creature) { }
if (param == ACTION_CALLBACK)
{
me->SetSpeed(MOVE_RUN, 2.5f);
me->GetThreatMgr().ClearAllThreat();
me->CombatStop(true);
me->GetMotionMaster()->MoveTargetedHome();
returning = true;
}
else if (param == ACTION_SPARK_DESPAWN)
{
me->GetMotionMaster()->MoveIdle();
me->RemoveAllAuras();
me->CastSpell(me, SPELL_SPARK_DESPAWN, true);
me->DespawnOrUnsummon(1s);
}
}
private:
bool returning;
void MoveInLineOfSight(Unit*) override { }
void UpdateAI(uint32) override { }
void AttackStart(Unit* /*who*/) override { }
void Reset() override { returning = false; }
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
damage = 0;
}
void DoAction(int32 param) override
{
if (param == ACTION_CALLBACK)
{
me->SetSpeed(MOVE_RUN, 2.5f);
me->GetThreatMgr().ClearAllThreat();
me->CombatStop(true);
me->GetMotionMaster()->MoveTargetedHome();
returning = true;
}
else if (param == ACTION_SPARK_DESPAWN)
{
me->GetMotionMaster()->MoveIdle();
me->RemoveAllAuras();
me->CastSpell(me, SPELL_SPARK_DESPAWN, true);
me->DespawnOrUnsummon(1s);
}
}
};
};
// 52658, 59795 - Static Overload
@ -291,7 +237,8 @@ class spell_ionar_static_overload : public AuraScript
return;
if (Unit* target = GetTarget())
target->CastSpell(target, SPELL_STATIC_OVERLOAD_KNOCK, true);
if (target->GetMap() && !target->GetMap()->IsHeroic())
target->CastSpell(target, SPELL_STATIC_OVERLOAD_KNOCK, true);
}
void Register() override
@ -302,7 +249,7 @@ class spell_ionar_static_overload : public AuraScript
void AddSC_boss_ionar()
{
new boss_ionar();
new npc_spark_of_ionar();
RegisterHallOfLightningCreatureAI(boss_ionar);
RegisterHallOfLightningCreatureAI(npc_spark_of_ionar);
RegisterSpellScript(spell_ionar_static_overload);
}

View File

@ -60,198 +60,112 @@ enum LokenEvents
EVENT_AURA_REMOVE = 5
};
class boss_loken : public CreatureScript
struct boss_loken : public BossAI
{
public:
boss_loken() : CreatureScript("boss_loken") { }
boss_loken(Creature* creature) : BossAI(creature, DATA_LOKEN), _introDone(false) { }
CreatureAI* GetAI(Creature* creature) const override
void Reset() override
{
return GetHallsOfLightningAI<boss_lokenAI>(creature);
_Reset();
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
me->RemoveAllAuras();
ScheduleHealthCheckEvent(75, [&] {
Talk(SAY_75HEALTH);
});
ScheduleHealthCheckEvent(50, [&] {
Talk(SAY_50HEALTH);
});
ScheduleHealthCheckEvent(25, [&] {
Talk(SAY_25HEALTH);
});
}
struct boss_lokenAI : public ScriptedAI
void MoveInLineOfSight(Unit* who) override
{
boss_lokenAI(Creature* creature) : ScriptedAI(creature)
BossAI::MoveInLineOfSight(who);
if (_introDone || !who->IsPlayer() || !me->IsWithinDistInMap(who, 40.0f))
return;
Talk(SAY_INTRO_1);
Talk(SAY_INTRO_2, 10s);
_introDone = true;
}
void JustEngagedWith(Unit*) override
{
me->m_Events.KillAllEvents(false);
_JustEngagedWith();
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_ARC_LIGHTNING, 10s);
events.ScheduleEvent(EVENT_SHOCKWAVE, 3s);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 15s);
if (IsHeroic())
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
}
void JustDied(Unit*) override
{
_JustDied();
Talk(SAY_DEATH);
}
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Talk(SAY_SLAY);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
m_pInstance = creature->GetInstanceScript();
if (m_pInstance)
isActive = m_pInstance->GetData(TYPE_LOKEN_INTRO);
}
InstanceScript* m_pInstance;
EventMap events;
bool isActive;
uint32 IntroTimer;
uint8 HealthCheck;
void MoveInLineOfSight(Unit*) override { }
void Reset() override
{
events.Reset();
if (m_pInstance)
{
m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
m_pInstance->SetData(TYPE_LOKEN, NOT_STARTED);
}
HealthCheck = 75;
IntroTimer = 0;
me->RemoveAllAuras();
if (!isActive)
{
me->SetControlled(true, UNIT_STATE_STUNNED);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
}
else
{
me->SetControlled(false, UNIT_STATE_STUNNED);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
}
}
void JustEngagedWith(Unit*) override
{
me->SetInCombatWithZone();
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_ARC_LIGHTNING, 10s);
events.ScheduleEvent(EVENT_SHOCKWAVE, 3s);
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 15s);
if (m_pInstance)
{
m_pInstance->SetData(TYPE_LOKEN, IN_PROGRESS);
if (me->GetMap()->IsHeroic())
m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
}
}
void JustDied(Unit*) override
{
Talk(SAY_DEATH);
if (m_pInstance)
m_pInstance->SetData(TYPE_LOKEN, DONE);
}
void LokenSpeach(bool hp)
{
if (hp)
{
switch (HealthCheck)
{
case 75:
Talk(SAY_75HEALTH);
break;
case 50:
Talk(SAY_50HEALTH);
break;
case 25:
Talk(SAY_25HEALTH);
break;
}
}
else
case EVENT_LIGHTNING_NOVA:
Talk(SAY_NOVA);
events.Repeat(15s);
me->CastSpell(me, SPELL_LIGHTNING_NOVA_VISUAL, true);
me->CastSpell(me, SPELL_LIGHTNING_NOVA_THUNDERS, true);
events.DelayEvents(5s);
events.ScheduleEvent(EVENT_AURA_REMOVE, me->GetMap()->IsHeroic() ? 4s : 5s);
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_LIGHTNING_NOVA_H : SPELL_LIGHTNING_NOVA_N, false);
break;
case EVENT_SHOCKWAVE:
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_PULSING_SHOCKWAVE_H : SPELL_PULSING_SHOCKWAVE_N, false);
break;
case EVENT_ARC_LIGHTNING:
if (Unit* target = SelectTargetFromPlayerList(100, SPELL_ARC_LIGHTNING))
me->CastSpell(target, SPELL_ARC_LIGHTNING, false);
events.Repeat(12s);
break;
case EVENT_AURA_REMOVE:
me->RemoveAura(SPELL_LIGHTNING_NOVA_THUNDERS);
break;
}
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Talk(SAY_SLAY);
}
void UpdateAI(uint32 diff) override
{
if (!isActive)
{
IntroTimer += diff;
if (IntroTimer > 5000 && IntroTimer < 10000)
{
if (SelectTargetFromPlayerList(60))
{
Talk(SAY_INTRO_1);
IntroTimer = 10000;
}
else
IntroTimer = 0;
}
if (IntroTimer >= 30000 && IntroTimer < 40000)
{
Talk(SAY_INTRO_2);
IntroTimer = 40000;
}
if (IntroTimer >= 60000)
{
isActive = true;
if (m_pInstance)
m_pInstance->SetData(TYPE_LOKEN_INTRO, 1);
me->SetControlled(false, UNIT_STATE_STUNNED);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
if (Player* target = SelectTargetFromPlayerList(80))
AttackStart(target);
}
return;
}
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK_HEALTH:
if (HealthBelowPct(HealthCheck))
{
LokenSpeach(true);
HealthCheck -= 25;
}
events.Repeat(1s);
break;
case EVENT_LIGHTNING_NOVA:
events.Repeat(15s);
me->CastSpell(me, SPELL_LIGHTNING_NOVA_VISUAL, true);
me->CastSpell(me, SPELL_LIGHTNING_NOVA_THUNDERS, true);
events.DelayEvents(5s);
events.ScheduleEvent(EVENT_AURA_REMOVE, me->GetMap()->IsHeroic() ? 4s : 5s);
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_LIGHTNING_NOVA_H : SPELL_LIGHTNING_NOVA_N, false);
break;
case EVENT_SHOCKWAVE:
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_PULSING_SHOCKWAVE_H : SPELL_PULSING_SHOCKWAVE_N, false);
break;
case EVENT_ARC_LIGHTNING:
if (Unit* target = SelectTargetFromPlayerList(100, SPELL_ARC_LIGHTNING))
me->CastSpell(target, SPELL_ARC_LIGHTNING, false);
events.Repeat(12s);
break;
case EVENT_AURA_REMOVE:
me->RemoveAura(SPELL_LIGHTNING_NOVA_THUNDERS);
break;
}
DoMeleeAttackIfReady();
}
};
DoMeleeAttackIfReady();
}
private:
bool _introDone;
};
class spell_loken_pulsing_shockwave : public SpellScript
@ -276,6 +190,6 @@ class spell_loken_pulsing_shockwave : public SpellScript
void AddSC_boss_loken()
{
new boss_loken();
RegisterHallOfLightningCreatureAI(boss_loken);
RegisterSpellScript(spell_loken_pulsing_shockwave);
}

View File

@ -78,506 +78,302 @@ enum Yells
EMOTE_SHATTER = 6,
};
class boss_volkhan : public CreatureScript
struct boss_volkhan : public BossAI
{
public:
boss_volkhan() : CreatureScript("boss_volkhan") { }
boss_volkhan(Creature* creature) : BossAI(creature, DATA_VOLKHAN), summons(creature) { }
CreatureAI* GetAI(Creature* creature) const override
void Reset() override
{
return GetHallsOfLightningAI<boss_volkhanAI>(creature);
_Reset();
x = y = z = PointID = ShatteredCount = 0;
HealthCheck = 100;
me->SetSpeed(MOVE_RUN, 1.2f, true);
me->SetReactState(REACT_AGGRESSIVE);
instance->SetData(DATA_VOLKHAN_ACHIEVEMENT, true);
}
struct boss_volkhanAI : public ScriptedAI
void JustEngagedWith(Unit*) override
{
boss_volkhanAI(Creature* creature) : ScriptedAI(creature), summons(creature)
_JustEngagedWith();
me->SetInCombatWithZone();
Talk(SAY_AGGRO);
ScheduleEvents(false);
}
void JustDied(Unit*) override
{
_JustDied();
Talk(SAY_DEATH);
}
void GetNextPos()
{
if (me->GetPositionY() < -180)
{
m_pInstance = creature->GetInstanceScript();
if (me->GetPositionX() > 1330)
x = 1355;
else
x = 1308;
y = -178;
z = 52.5f;
}
else if (me->GetPositionY() < -145)
{
if (me->GetPositionX() > 1330)
x = 1355;
else
x = 1308;
y = -137;
z = 52.5f;
}
else if (me->GetPositionY() < -130)
{
if (me->GetPositionX() > 1330)
x = 1343;
else
x = 1320;
y = -123;
z = 56.7f;
}
else
{
PointID = POINT_ANVIL;
x = 1327;
y = -96;
z = 56.7f;
}
}
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Talk(SAY_SLAY);
}
void ScheduleEvents(bool anvil)
{
events.SetPhase(1);
events.RescheduleEvent(EVENT_HEAT, 8s, 0, 1);
events.RescheduleEvent(EVENT_SHATTER, 10s, 0, 1);
events.RescheduleEvent(EVENT_CHECK_HEALTH, anvil ? 1s : 6s, 0, 1);
events.RescheduleEvent(EVENT_POSITION, 4s, 0, 1);
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_MOLTEN_GOLEM)
{
summon->SetFaction(me->GetFaction());
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
summon->AI()->AttackStart(target);
}
}
void DoAction(int32 param) override
{
if (param == ACTION_DESTROYED)
{
ShatteredCount++;
if (ShatteredCount > 4)
instance->SetData(DATA_VOLKHAN_ACHIEVEMENT, false);
}
}
void MovementInform(uint32 type, uint32 id) override
{
if (type != POINT_MOTION_TYPE)
return;
if (id == POINT_ANVIL)
{
me->SetSpeed(MOVE_RUN, 1.2f, true);
me->SetReactState(REACT_AGGRESSIVE);
me->CastSpell(me, SPELL_TEMPER, false);
PointID = 0;
ScheduleEvents(true);
// update orientation at server
me->SetOrientation(2.19f);
// and client
WorldPacket data;
me->BuildHeartBeatMsg(&data);
me->SendMessageToSet(&data, false);
me->SetControlled(true, UNIT_STATE_ROOT);
}
else
events.ScheduleEvent(EVENT_MOVE_TO_ANVIL, 0ms, 0, 2);
}
void SpellHitTarget(Unit* /*who*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TEMPER)
{
me->CastSpell(me, SPELL_SUMMON_MOLTEN_GOLEM, true);
me->CastSpell(me, SPELL_SUMMON_MOLTEN_GOLEM, true);
me->GetMotionMaster()->MoveChase(me->GetVictim());
me->SetControlled(false, UNIT_STATE_ROOT);
}
}
void GoToAnvil()
{
events.SetPhase(2);
HealthCheck -= 20;
me->SetSpeed(MOVE_RUN, 4.0f, true);
me->SetReactState(REACT_PASSIVE);
Talk(SAY_FORGE);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
events.ScheduleEvent(EVENT_MOVE_TO_ANVIL, 0ms, 0, 2);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_HEAT:
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_HEAT_H : SPELL_HEAT_N, true);
events.Repeat(8s);
break;
case EVENT_CHECK_HEALTH:
if (HealthBelowPct(HealthCheck))
GoToAnvil();
events.Repeat(1s);
return;
case EVENT_SHATTER:
{
events.Repeat(10s);
summons.DoAction(ACTION_SHATTER);
break;
}
case EVENT_MOVE_TO_ANVIL:
GetNextPos();
me->GetMotionMaster()->MovePoint(PointID, x, y, z);
return;
case EVENT_POSITION:
if (me->GetDistance(1331.9f, -106, 56) > 95)
EnterEvadeMode();
else
events.Repeat(4s);
return;
}
InstanceScript* m_pInstance;
DoMeleeAttackIfReady();
}
private:
EventMap events;
SummonList summons;
uint8 HealthCheck;
float x, y, z;
uint8 PointID;
uint8 ShatteredCount;
void Reset() override
{
x = y = z = PointID = ShatteredCount = 0;
HealthCheck = 100;
events.Reset();
summons.DespawnAll();
me->SetSpeed(MOVE_RUN, 1.2f, true);
me->SetReactState(REACT_AGGRESSIVE);
if (m_pInstance)
{
m_pInstance->SetData(TYPE_VOLKHAN, NOT_STARTED);
m_pInstance->SetData(DATA_VOLKHAN_ACHIEVEMENT, true);
}
}
void JustEngagedWith(Unit*) override
{
me->SetInCombatWithZone();
Talk(SAY_AGGRO);
if (m_pInstance)
m_pInstance->SetData(TYPE_VOLKHAN, IN_PROGRESS);
ScheduleEvents(false);
}
void JustDied(Unit*) override
{
Talk(SAY_DEATH);
summons.DespawnAll();
if (m_pInstance)
m_pInstance->SetData(TYPE_VOLKHAN, DONE);
}
void GetNextPos()
{
if (me->GetPositionY() < -180)
{
if (me->GetPositionX() > 1330)
x = 1355;
else
x = 1308;
y = -178;
z = 52.5f;
}
else if (me->GetPositionY() < -145)
{
if (me->GetPositionX() > 1330)
x = 1355;
else
x = 1308;
y = -137;
z = 52.5f;
}
else if (me->GetPositionY() < -130)
{
if (me->GetPositionX() > 1330)
x = 1343;
else
x = 1320;
y = -123;
z = 56.7f;
}
else
{
PointID = POINT_ANVIL;
x = 1327;
y = -96;
z = 56.7f;
}
}
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
return;
Talk(SAY_SLAY);
}
void ScheduleEvents(bool anvil)
{
events.SetPhase(1);
events.RescheduleEvent(EVENT_HEAT, 8s, 0, 1);
events.RescheduleEvent(EVENT_SHATTER, 10s, 0, 1);
events.RescheduleEvent(EVENT_CHECK_HEALTH, anvil ? 1s : 6s, 0, 1);
events.RescheduleEvent(EVENT_POSITION, 4s, 0, 1);
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_MOLTEN_GOLEM)
{
summon->SetFaction(me->GetFaction());
if (Unit* target = SelectTarget(SelectTargetMethod::Random))
summon->AI()->AttackStart(target);
}
}
void DoAction(int32 param) override
{
if (param == ACTION_DESTROYED)
{
ShatteredCount++;
if (ShatteredCount > 4)
m_pInstance->SetData(DATA_VOLKHAN_ACHIEVEMENT, false);
}
}
void MovementInform(uint32 type, uint32 id) override
{
if (type != POINT_MOTION_TYPE)
return;
if (id == POINT_ANVIL)
{
me->SetSpeed(MOVE_RUN, 1.2f, true);
me->SetReactState(REACT_AGGRESSIVE);
me->CastSpell(me, SPELL_TEMPER, false);
PointID = 0;
ScheduleEvents(true);
// update orientation at server
me->SetOrientation(2.19f);
// and client
WorldPacket data;
me->BuildHeartBeatMsg(&data);
me->SendMessageToSet(&data, false);
me->SetControlled(true, UNIT_STATE_ROOT);
}
else
events.ScheduleEvent(EVENT_MOVE_TO_ANVIL, 0ms, 0, 2);
}
void SpellHitTarget(Unit* /*who*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TEMPER)
{
me->CastSpell(me, SPELL_SUMMON_MOLTEN_GOLEM, true);
me->CastSpell(me, SPELL_SUMMON_MOLTEN_GOLEM, true);
me->GetMotionMaster()->MoveChase(me->GetVictim());
me->SetControlled(false, UNIT_STATE_ROOT);
}
}
void GoToAnvil()
{
events.SetPhase(2);
HealthCheck -= 20;
me->SetSpeed(MOVE_RUN, 4.0f, true);
me->SetReactState(REACT_PASSIVE);
Talk(SAY_FORGE);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
events.ScheduleEvent(EVENT_MOVE_TO_ANVIL, 0ms, 0, 2);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_HEAT:
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_HEAT_H : SPELL_HEAT_N, true);
events.Repeat(8s);
break;
case EVENT_CHECK_HEALTH:
if (HealthBelowPct(HealthCheck))
GoToAnvil();
events.Repeat(1s);
return;
case EVENT_SHATTER:
{
events.Repeat(10s);
summons.DoAction(ACTION_SHATTER);
break;
}
case EVENT_MOVE_TO_ANVIL:
GetNextPos();
me->GetMotionMaster()->MovePoint(PointID, x, y, z);
return;
case EVENT_POSITION:
if (me->GetDistance(1331.9f, -106, 56) > 95)
EnterEvadeMode();
else
events.Repeat(4s);
return;
}
DoMeleeAttackIfReady();
}
};
};
class npc_molten_golem : public CreatureScript
struct npc_molten_golem : public ScriptedAI
{
public:
npc_molten_golem() : CreatureScript("npc_molten_golem") { }
CreatureAI* GetAI(Creature* creature) const override
npc_molten_golem(Creature* creature) : ScriptedAI(creature)
{
return GetHallsOfLightningAI<npc_molten_golemAI>(creature);
m_pInstance = creature->GetInstanceScript();
}
struct npc_molten_golemAI : public ScriptedAI
void Reset() override
{
npc_molten_golemAI(Creature* creature) : ScriptedAI(creature)
{
m_pInstance = creature->GetInstanceScript();
}
EventMap events;
InstanceScript* m_pInstance;
void Reset() override
{
events.Reset();
events.ScheduleEvent(EVENT_BLAST, 7s);
events.ScheduleEvent(EVENT_IMMOLATION, 3s);
}
void DamageTaken(Unit*, uint32& uiDamage, DamageEffectType, SpellSchoolMask) override
{
if (me->GetEntry() == NPC_BRITTLE_GOLEM)
{
uiDamage = 0;
return;
}
if (uiDamage >= me->GetHealth())
{
me->UpdateEntry(NPC_BRITTLE_GOLEM, 0, false);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
me->SetHealth(me->GetMaxHealth());
me->RemoveAllAuras();
me->AttackStop();
uiDamage = 0;
if (me->IsNonMeleeSpellCast(false))
me->InterruptNonMeleeSpells(false);
me->SetControlled(true, UNIT_STATE_STUNNED);
}
}
void DoAction(int32 param) override
{
if (me->GetEntry() == NPC_BRITTLE_GOLEM && param == ACTION_SHATTER)
{
if (Creature* volkhan = ObjectAccessor::GetCreature(*me, m_pInstance->GetGuidData(TYPE_VOLKHAN)))
volkhan->AI()->DoAction(ACTION_DESTROYED);
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_SHATTER_H : SPELL_SHATTER_N, true);
me->DespawnOrUnsummon(500ms);
}
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target or if we are frozen
if (!UpdateVictim() || me->GetEntry() == NPC_BRITTLE_GOLEM)
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_BLAST:
me->CastSpell(me, SPELL_BLAST_WAVE, false);
events.Repeat(14s);
break;
case EVENT_IMMOLATION:
me->CastSpell(me->GetVictim(), me->GetMap()->IsHeroic() ? SPELL_IMMOLATION_STRIKE_H : SPELL_IMMOLATION_STRIKE_N, false);
events.Repeat(5s);
break;
}
DoMeleeAttackIfReady();
}
};
};
enum monumentSpells
{
SPELL_FREEZE_ANIM = 16245,
SPELL_AWAKEN = 52875,
SPELL_PIERCING_HOWL = 23600,
SPELL_PENETRATING_STRIKE = 52890,
SPELL_FRIGHTENING_SHOUT = 19134,
SPELL_BLADE_TURNING_N = 52891,
SPELL_BLADE_TURNING_H = 59173,
SPELL_DEADLY_THROW_N = 52885,
SPELL_DEADLY_THROW_H = 59180,
SPELL_DEFLECTION_N = 52879,
SPELL_DEFLECTION_H = 59181,
SPELL_THROW_N = 52904,
SPELL_THROW_H = 59179,
};
enum monumentEvents
{
EVENT_PIERCING_HOWL = 1,
EVENT_PENETRATING_STRIKE = 2,
EVENT_FRIGHTENING_SHOUT = 3,
EVENT_BLADE_TURNING = 4,
EVENT_DEADLY_THROW = 11,
EVENT_DEFLECTION = 12,
EVENT_THROW = 13,
EVENT_UNFREEZE = 20,
};
class npc_hol_monument : public CreatureScript
{
public:
npc_hol_monument() : CreatureScript("npc_hol_monument") {}
CreatureAI* GetAI(Creature* creature) const override
{
return GetHallsOfLightningAI<npc_hol_monumentAI>(creature);
events.Reset();
events.ScheduleEvent(EVENT_BLAST, 7s);
events.ScheduleEvent(EVENT_IMMOLATION, 3s);
}
struct npc_hol_monumentAI : public ScriptedAI
void DamageTaken(Unit*, uint32& uiDamage, DamageEffectType, SpellSchoolMask) override
{
npc_hol_monumentAI(Creature* creature) : ScriptedAI(creature)
if (me->GetEntry() == NPC_BRITTLE_GOLEM)
{
_attackGUID.Clear();
_isActive = urand(0, 1);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->CastSpell(me, SPELL_FREEZE_ANIM, true);
uiDamage = 0;
return;
}
EventMap events;
bool _isActive;
ObjectGuid _attackGUID;
void Reset() override
if (uiDamage >= me->GetHealth())
{
me->UpdateEntry(NPC_BRITTLE_GOLEM, 0, false);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_DISABLE_MOVE);
me->SetHealth(me->GetMaxHealth());
me->RemoveAllAuras();
me->AttackStop();
uiDamage = 0;
if (me->IsNonMeleeSpellCast(false))
me->InterruptNonMeleeSpells(false);
me->SetControlled(true, UNIT_STATE_STUNNED);
}
}
void DoAction(int32 param) override
{
if (me->GetEntry() == NPC_BRITTLE_GOLEM && param == ACTION_SHATTER)
{
if (Creature* volkhan = m_pInstance->GetCreature(DATA_VOLKHAN))
volkhan->AI()->DoAction(ACTION_DESTROYED);
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_SHATTER_H : SPELL_SHATTER_N, true);
me->DespawnOrUnsummon(500ms);
}
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target or if we are frozen
if (!UpdateVictim() || me->GetEntry() == NPC_BRITTLE_GOLEM)
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_BLAST:
me->CastSpell(me, SPELL_BLAST_WAVE, false);
events.Repeat(14s);
break;
case EVENT_IMMOLATION:
me->CastSpell(me->GetVictim(), me->GetMap()->IsHeroic() ? SPELL_IMMOLATION_STRIKE_H : SPELL_IMMOLATION_STRIKE_N, false);
events.Repeat(5s);
break;
}
void MoveInLineOfSight(Unit* who) override
{
if (_attackGUID)
ScriptedAI::MoveInLineOfSight(who);
else if (_isActive && who->IsPlayer())
{
if ((who->GetPositionX() < me->GetPositionX() || who->GetPositionY() < -220.0f) && me->GetDistance2d(who) < 40)
{
_isActive = false;
_attackGUID = who->GetGUID();
events.Reset();
events.RescheduleEvent(EVENT_UNFREEZE, 5s);
}
}
}
void JustEngagedWith(Unit*) override
{
events.Reset();
if (me->GetEntry() == 28961) // NPC_TITANIUM_SIEGEBREAKER
{
events.ScheduleEvent(EVENT_PIERCING_HOWL, 10s, 25s);
events.ScheduleEvent(EVENT_PENETRATING_STRIKE, 5s, 10s);
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 20s, 28s);
events.ScheduleEvent(EVENT_BLADE_TURNING, 12s);
}
else
{
events.ScheduleEvent(EVENT_THROW, 10s, 25s);
events.ScheduleEvent(EVENT_DEADLY_THROW, 15s, 30s);
events.ScheduleEvent(EVENT_DEFLECTION, 15s);
}
}
void AttackStart(Unit* who) override
{
if (!_attackGUID || !_isActive)
return;
ScriptedAI::AttackStart(who);
}
void UpdateAI(uint32 diff) override
{
if (!_isActive && !_attackGUID)
return;
events.Update(diff);
uint32 eventId = events.ExecuteEvent();
if (eventId == EVENT_UNFREEZE)
{
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->CastSpell(me, SPELL_AWAKEN, true);
me->RemoveAllAuras();
_isActive = true;
if (Unit* target = ObjectAccessor::GetUnit(*me, _attackGUID))
AttackStart(target);
return;
}
//Return since we have no target or if we are disabled from fight
if (!UpdateVictim())
return;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (eventId)
{
case EVENT_PIERCING_HOWL:
me->CastSpell(me->GetVictim(), SPELL_PIERCING_HOWL, false);
events.Repeat(10s, 25s);
break;
case EVENT_PENETRATING_STRIKE:
me->CastSpell(me->GetVictim(), SPELL_PENETRATING_STRIKE, false);
events.Repeat(5s, 10s);
break;
case EVENT_FRIGHTENING_SHOUT:
me->CastSpell(me->GetVictim(), SPELL_FRIGHTENING_SHOUT, false);
events.Repeat(20s, 28s);
break;
case EVENT_BLADE_TURNING:
me->CastSpell(me->GetVictim(), me->GetMap()->IsHeroic() ? SPELL_BLADE_TURNING_H : SPELL_BLADE_TURNING_N, false);
events.Repeat(12s);
break;
case EVENT_THROW:
me->CastSpell(SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0), me->GetMap()->IsHeroic() ? SPELL_THROW_H : SPELL_THROW_N, true);
events.Repeat(10s, 25s);
break;
case EVENT_DEADLY_THROW:
me->CastSpell(SelectTarget(SelectTargetMethod::Random, 0, 50.0f, true, 0), me->GetMap()->IsHeroic() ? SPELL_DEADLY_THROW_H : SPELL_DEADLY_THROW_N, true);
events.Repeat(15s, 30s);
break;
case EVENT_DEFLECTION:
me->CastSpell(me, me->GetMap()->IsHeroic() ? SPELL_DEFLECTION_H : SPELL_DEFLECTION_N, false);
events.Repeat(15s);
break;
}
DoMeleeAttackIfReady();
}
};
DoMeleeAttackIfReady();
}
private:
EventMap events;
InstanceScript* m_pInstance;
};
void AddSC_boss_volkhan()
{
new boss_volkhan();
new npc_molten_golem();
new npc_hol_monument();
RegisterHallOfLightningCreatureAI(boss_volkhan);
RegisterHallOfLightningCreatureAI(npc_molten_golem);
}

View File

@ -24,34 +24,41 @@
#define HallsOfLightningScriptName "instance_halls_of_lightning"
enum HoLEvents
enum HoLBossIds
{
TYPE_BJARNGRIM = 0,
TYPE_IONAR = 1,
TYPE_LOKEN = 2,
TYPE_VOLKHAN = 3,
TYPE_LOKEN_INTRO = 4,
MAX_ENCOUNTER = 5,
DATA_BJARNGRIM = 0,
DATA_IONAR = 1,
DATA_LOKEN = 2,
DATA_VOLKHAN = 3,
MAX_ENCOUNTERS
};
enum HoLDataTypes
{
// GameObject data
DATA_LOKEN_THRONE = 0,
// Achievement data
DATA_BJARNGRIM_ACHIEVEMENT = 10,
DATA_VOLKHAN_ACHIEVEMENT = 11,
};
enum HoLNPCs
{
NPC_BJARNGRIM = 28586,
NPC_VOLKHAN = 28587,
NPC_IONAR = 28546,
NPC_LOKEN = 28923,
NPC_TITANIUM_THUNDERER = 28965,
NPC_TITANIUM_SIEGEBREAKER = 28961
};
enum HoLGOs
{
GO_BJARNGRIM_DOOR = 191416, //_doors10
GO_VOLKHAN_DOOR = 191325, //_doors07
GO_IONAR_DOOR = 191326, //_doors05
GO_LOKEN_DOOR = 191324, //_doors02
GO_LOKEN_THRONE = 192654,
GO_VOLKHAN_DOOR = 191325,
GO_IONAR_DOOR = 191326,
GO_LOKEN_THRONE = 192654
};
enum HoLActions
{
ACTION_ACTIVATE_TITANIUM_VRYKUL,
};
template <class AI, class T>
@ -60,4 +67,6 @@ inline AI* GetHallsOfLightningAI(T* obj)
return GetInstanceAI<AI>(obj, HallsOfLightningScriptName);
}
#define RegisterHallOfLightningCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetHallsOfLightningAI)
#endif

View File

@ -15,206 +15,121 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AreaTriggerScript.h"
#include "CreatureScript.h"
#include "InstanceMapScript.h"
#include "Player.h"
#include "ScriptedCreature.h"
#include "halls_of_lightning.h"
DoorData const doorData[] =
{
{ GO_VOLKHAN_DOOR, DATA_VOLKHAN, DOOR_TYPE_PASSAGE },
{ GO_IONAR_DOOR, DATA_IONAR, DOOR_TYPE_PASSAGE },
{ 0, 0, DOOR_TYPE_ROOM }
};
ObjectData const gameObjectData[] =
{
{ GO_LOKEN_THRONE, DATA_LOKEN_THRONE },
{ 0, 0 }
};
class instance_halls_of_lightning : public InstanceMapScript
{
public:
instance_halls_of_lightning() : InstanceMapScript("instance_halls_of_lightning", MAP_HALLS_OF_LIGHTNING) { }
InstanceScript* GetInstanceScript(InstanceMap* pMap) const override
{
return new instance_halls_of_lightning_InstanceMapScript(pMap);
}
struct instance_halls_of_lightning_InstanceMapScript : public InstanceScript
{
instance_halls_of_lightning_InstanceMapScript(Map* pMap) : InstanceScript(pMap) { Initialize(); };
uint32 m_auiEncounter[MAX_ENCOUNTER];
ObjectGuid m_uiGeneralBjarngrimGUID;
ObjectGuid m_uiIonarGUID;
ObjectGuid m_uiLokenGUID;
ObjectGuid m_uiVolkhanGUID;
ObjectGuid m_uiBjarngrimDoorGUID;
ObjectGuid m_uiVolkhanDoorGUID;
ObjectGuid m_uiIonarDoorGUID;
ObjectGuid m_uiLokenDoorGUID;
ObjectGuid m_uiLokenGlobeGUID;
bool volkhanAchievement;
bool bjarngrimAchievement;
void Initialize() override
instance_halls_of_lightning_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
{
SetHeaders(DataHeader);
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
volkhanAchievement = false;
bjarngrimAchievement = false;
}
bool IsEncounterInProgress() const override
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
{
if (m_auiEncounter[i] == IN_PROGRESS && i != TYPE_LOKEN_INTRO)
{
return true;
}
}
return false;
}
void OnCreatureCreate(Creature* pCreature) override
{
switch (pCreature->GetEntry())
{
case NPC_BJARNGRIM:
m_uiGeneralBjarngrimGUID = pCreature->GetGUID();
break;
case NPC_VOLKHAN:
m_uiVolkhanGUID = pCreature->GetGUID();
break;
case NPC_IONAR:
m_uiIonarGUID = pCreature->GetGUID();
break;
case NPC_LOKEN:
m_uiLokenGUID = pCreature->GetGUID();
break;
}
}
void OnGameObjectCreate(GameObject* pGo) override
{
switch (pGo->GetEntry())
{
case GO_BJARNGRIM_DOOR:
m_uiBjarngrimDoorGUID = pGo->GetGUID();
if (m_auiEncounter[TYPE_BJARNGRIM] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_VOLKHAN_DOOR:
m_uiVolkhanDoorGUID = pGo->GetGUID();
if (m_auiEncounter[TYPE_VOLKHAN] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_IONAR_DOOR:
m_uiIonarDoorGUID = pGo->GetGUID();
if (m_auiEncounter[TYPE_IONAR] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_LOKEN_DOOR:
m_uiLokenDoorGUID = pGo->GetGUID();
if (m_auiEncounter[TYPE_LOKEN] == DONE)
pGo->SetGoState(GO_STATE_ACTIVE);
break;
case GO_LOKEN_THRONE:
m_uiLokenGlobeGUID = pGo->GetGUID();
break;
}
}
SetBossNumber(MAX_ENCOUNTERS);
LoadDoorData(doorData);
LoadObjectData(nullptr, gameObjectData);
_volkhanAchievement = false;
_bjarngrimAchievement = false;
};
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override
{
switch (criteria_id)
{
case 7321: //Shatter Resistant (2042)
return volkhanAchievement;
return _volkhanAchievement;
case 6835: // Lightning Struck (1834)
return bjarngrimAchievement;
return _bjarngrimAchievement;
}
return false;
}
void SetData(uint32 uiType, uint32 uiData) override
{
m_auiEncounter[uiType] = uiData;
if (uiType == TYPE_LOKEN_INTRO)
SaveToDB();
// Achievements
if (uiType == DATA_BJARNGRIM_ACHIEVEMENT)
bjarngrimAchievement = (bool)uiData;
_bjarngrimAchievement = (bool)uiData;
else if (uiType == DATA_VOLKHAN_ACHIEVEMENT)
volkhanAchievement = (bool)uiData;
if (uiData != DONE)
return;
switch (uiType)
{
case TYPE_BJARNGRIM:
HandleGameObject(m_uiBjarngrimDoorGUID, true);
break;
case TYPE_VOLKHAN:
HandleGameObject(m_uiVolkhanDoorGUID, true);
break;
case TYPE_IONAR:
HandleGameObject(m_uiIonarDoorGUID, true);
break;
case TYPE_LOKEN:
HandleGameObject(m_uiLokenDoorGUID, true);
//Appears to be type 5 GO with animation. Need to figure out how this work, code below only placeholder
if (GameObject* pGlobe = instance->GetGameObject(m_uiLokenGlobeGUID))
pGlobe->SetGoState(GO_STATE_ACTIVE);
break;
}
SaveToDB();
_volkhanAchievement = (bool)uiData;
}
void ReadSaveDataMore(std::istringstream& data) override
{
data >> m_auiEncounter[0];
data >> m_auiEncounter[1];
data >> m_auiEncounter[2];
data >> m_auiEncounter[3];
}
void WriteSaveDataMore(std::ostringstream& data) override
{
data << m_auiEncounter[0] << ' '
<< m_auiEncounter[1] << ' '
<< m_auiEncounter[2] << ' '
<< m_auiEncounter[3] << ' ';
}
uint32 GetData(uint32 uiType) const override
{
return m_auiEncounter[uiType];
}
ObjectGuid GetGuidData(uint32 uiData) const override
{
switch (uiData)
{
case TYPE_BJARNGRIM:
return m_uiGeneralBjarngrimGUID;
case TYPE_VOLKHAN:
return m_uiVolkhanGUID;
case TYPE_IONAR:
return m_uiIonarGUID;
case TYPE_LOKEN:
return m_uiLokenGUID;
}
return ObjectGuid::Empty;
}
private:
bool _volkhanAchievement;
bool _bjarngrimAchievement;
};
InstanceScript* GetInstanceScript(InstanceMap* pMap) const override
{
return new instance_halls_of_lightning_InstanceMapScript(pMap);
}
};
enum TitaniumHallwaySpells
{
SPELL_FREEZE_ANIM = 16245,
SPELL_AWAKEN = 52875,
};
class at_hol_hall_of_watchers : public OnlyOnceAreaTriggerScript
{
public:
at_hol_hall_of_watchers() : OnlyOnceAreaTriggerScript("at_hol_hall_of_watchers") {}
bool _OnTrigger(Player* player, const AreaTrigger* /*at*/) override
{
std::list<Creature*> creatures;
player->GetCreatureListWithEntryInGrid(creatures, { NPC_TITANIUM_SIEGEBREAKER, NPC_TITANIUM_THUNDERER }, 50.0f);
creatures.remove_if([&](Creature const* creature) -> bool
{
return !player->IsWithinLOSInMap(creature) || !creature->HasAura(SPELL_FREEZE_ANIM);
});
if (creatures.empty())
return false;
Acore::Containers::RandomResize(creatures, urand(2, 4));
ObjectGuid target = player->GetGUID();
for (Creature* creature : creatures)
{
creature->SetHomePosition(player->GetPosition());
creature->AI()->DoCastSelf(SPELL_AWAKEN);
creature->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
creature->m_Events.AddEventAtOffset([creature, target] {
creature->AI()->DoAction(ACTION_ACTIVATE_TITANIUM_VRYKUL);
if (Player* targetPlayer = ObjectAccessor::GetPlayer(*creature, target))
creature->AI()->AttackStart(targetPlayer);
}, 5s);
}
return false;
}
};
void AddSC_instance_halls_of_lightning()
{
new instance_halls_of_lightning();
new at_hol_hall_of_watchers();
}

View File

@ -574,7 +574,7 @@ public:
summon->SetHomePosition(x, y, z, o);
summon->UpdatePosition(x, y, z, o, true);
summon->StopMovingOnCurrentPos();
summon->m_Events.AddEvent(new CosmicSmashDamageEvent(summon), summon->m_Events.CalculateTime(4000));
summon->m_Events.AddEventAtOffset(new CosmicSmashDamageEvent(summon), 4s);
break;
}
case NPC_UNLEASHED_DARK_MATTER:

View File

@ -418,7 +418,7 @@ public:
if (pInstance)
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
me->m_Events.AddEvent(new CastRunesEvent(*me), me->m_Events.CalculateTime(8000));
me->m_Events.AddEventAtOffset(new CastRunesEvent(*me), 8s);
}
void JustReachedHome() override

View File

@ -769,12 +769,12 @@ public:
// so that can't be the issue
// See BoomEvent class
// Schedule 1s delayed
me->m_Events.AddEvent(new BoomEvent(me), me->m_Events.CalculateTime(1 * IN_MILLISECONDS));
me->m_Events.AddEventAtOffset(new BoomEvent(me), 1s);
}
void JustDied(Unit* /*killer*/) override
{
me->m_Events.AddEvent(new BoomEvent(me), me->m_Events.CalculateTime(1 * IN_MILLISECONDS));
me->m_Events.AddEventAtOffset(new BoomEvent(me), 1s);
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override

View File

@ -1439,7 +1439,7 @@ public:
{
me->SetDisplayId(me->GetNativeDisplayId());
me->CastSpell(me, SPELL_SAC_EMERGE, true);
me->m_Events.AddEvent(new SACActivateEvent(me), me->m_Events.CalculateTime(4000));
me->m_Events.AddEventAtOffset(new SACActivateEvent(me), 4s);
}
void Deactivate()
@ -1452,7 +1452,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
me->RemoveAurasDueToSpell(SPELL_SAC_GHOUL_AREA_AURA);
me->m_Events.AddEvent(new SACDeactivateEvent(me), me->m_Events.CalculateTime(4000));
me->m_Events.AddEventAtOffset(new SACDeactivateEvent(me), 4s);
}
void JustRespawned() override

View File

@ -975,7 +975,7 @@ public:
};
if (who->IsPlayer())
who->m_Events.AddEvent(new DelayedTransportPositionOffsets(who), who->m_Events.CalculateTime(500));
who->m_Events.AddEventAtOffset(new DelayedTransportPositionOffsets(who), 500ms);
return;
}

View File

@ -771,7 +771,7 @@ class spell_illidari_council_deadly_strike_aura : public AuraScript
if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
{
GetUnitOwner()->CastSpell(target, GetSpellInfo()->Effects[effect->GetEffIndex()].TriggerSpell, true);
GetUnitOwner()->m_Events.AddEvent(new VerasEnvenom(*GetUnitOwner(), target->GetGUID()), GetUnitOwner()->m_Events.CalculateTime(urand(1500, 3500)));
GetUnitOwner()->m_Events.AddEventAtOffset(new VerasEnvenom(*GetUnitOwner(), target->GetGUID()), randtime(1500ms, 3500ms));
}
}

View File

@ -284,7 +284,7 @@ public:
if (type != POINT_MOTION_TYPE || id != POINT_GO_BACK)
return;
me->m_Events.AddEvent(new SuckBackEvent(*me, ACTION_ESSENCE_OF_SUFFERING), me->m_Events.CalculateTime(1500));
me->m_Events.AddEventAtOffset(new SuckBackEvent(*me, ACTION_ESSENCE_OF_SUFFERING), 1500ms);
me->SetTarget();
me->SetFacingTo(M_PI / 2.0f);
}
@ -392,7 +392,7 @@ public:
if (type != POINT_MOTION_TYPE || id != POINT_GO_BACK)
return;
me->m_Events.AddEvent(new SuckBackEvent(*me, ACTION_ESSENCE_OF_DESIRE), me->m_Events.CalculateTime(1500));
me->m_Events.AddEventAtOffset(new SuckBackEvent(*me, ACTION_ESSENCE_OF_DESIRE), 1500ms);
me->SetTarget();
me->SetFacingTo(M_PI / 2.0f);
}

View File

@ -452,10 +452,10 @@ class spell_alar_flame_quills : public AuraScript
// 24 spells in total
for (uint8 i = 0; i < 21; ++i)
GetUnitOwner()->m_Events.AddEvent(new CastQuill(GetUnitOwner(), SPELL_QUILL_MISSILE_1 + i), GetUnitOwner()->m_Events.CalculateTime(i * 40));
GetUnitOwner()->m_Events.AddEvent(new CastQuill(GetUnitOwner(), SPELL_QUILL_MISSILE_2 + 0), GetUnitOwner()->m_Events.CalculateTime(22 * 40));
GetUnitOwner()->m_Events.AddEvent(new CastQuill(GetUnitOwner(), SPELL_QUILL_MISSILE_2 + 1), GetUnitOwner()->m_Events.CalculateTime(23 * 40));
GetUnitOwner()->m_Events.AddEvent(new CastQuill(GetUnitOwner(), SPELL_QUILL_MISSILE_2 + 2), GetUnitOwner()->m_Events.CalculateTime(24 * 40));
GetUnitOwner()->m_Events.AddEventAtOffset(new CastQuill(GetUnitOwner(), SPELL_QUILL_MISSILE_1 + i), Milliseconds(i * 40));
GetUnitOwner()->m_Events.AddEventAtOffset(new CastQuill(GetUnitOwner(), SPELL_QUILL_MISSILE_2 + 0), Milliseconds(22 * 40));
GetUnitOwner()->m_Events.AddEventAtOffset(new CastQuill(GetUnitOwner(), SPELL_QUILL_MISSILE_2 + 1), Milliseconds(23 * 40));
GetUnitOwner()->m_Events.AddEventAtOffset(new CastQuill(GetUnitOwner(), SPELL_QUILL_MISSILE_2 + 2), Milliseconds(24 * 40));
}
void Register() override

View File

@ -1032,7 +1032,7 @@ public:
bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override
{
if (_owner->IsBeingTeleportedNear())
_owner->m_Events.AddEvent(new lapseTeleport(_owner), _owner->m_Events.CalculateTime(1));
_owner->m_Events.AddEventAtOffset(new lapseTeleport(_owner), 1ms);
else if (!_owner->IsBeingTeleported())
{
_owner->CastSpell(_owner, SPELL_GRAVITY_LAPSE_KNOCKBACK, true);
@ -1062,7 +1062,7 @@ class spell_kaelthas_gravity_lapse : public SpellScript
if (Player* target = GetHitPlayer())
{
GetCaster()->CastSpell(target, _currentSpellId++, true);
target->m_Events.AddEvent(new lapseTeleport(target), target->m_Events.CalculateTime(1));
target->m_Events.AddEventAtOffset(new lapseTeleport(target), 1ms);
}
}

View File

@ -193,7 +193,7 @@ struct npc_pet_gen_argent_pony_bridle : public ScriptedAI
duration = cooldown;
aura = SPELL_AURA_POSTMAN_S + i;
_state = argentPonyService[TEAM_ALLIANCE][i];
me->ToTempSummon()->UnSummon(duration);
me->ToTempSummon()->UnSummon(Milliseconds(duration));
break;
}
}
@ -204,7 +204,7 @@ struct npc_pet_gen_argent_pony_bridle : public ScriptedAI
duration = cooldown * IN_MILLISECONDS;
aura = SPELL_AURA_BANK_G + i;
_state = argentPonyService[TEAM_HORDE][i];
me->ToTempSummon()->UnSummon(duration);
me->ToTempSummon()->UnSummon(Milliseconds(duration));
break;
}
}

View File

@ -138,7 +138,7 @@ struct npc_pet_mage_mirror_image : CasterAI
newAura->SetDuration(visAura->GetDuration());
}
me->m_Events.AddEvent(new DeathEvent(*me), me->m_Events.CalculateTime(29500));
me->m_Events.AddEventAtOffset(new DeathEvent(*me), 29500ms);
}
// Do not reload Creature templates on evade mode enter - prevent visual lost

View File

@ -1669,7 +1669,7 @@ public:
_player->HandleEmoteCommand(RAND(EMOTE_ONESHOT_APPLAUD, EMOTE_ONESHOT_DANCESPECIAL, EMOTE_ONESHOT_LAUGH, EMOTE_ONESHOT_CHEER, EMOTE_ONESHOT_CHICKEN));
}
_player->m_Events.AddEvent(this, RAND(_player->m_Events.CalculateTime(5000), _player->m_Events.CalculateTime(10000), _player->m_Events.CalculateTime(15000)));
_player->m_Events.AddEventAtOffset(this, RAND(5s, 10s, 15s));
return false; // do not delete re-added event in EventProcessor::Update
}
@ -1690,7 +1690,7 @@ class spell_item_party_time : public AuraScript
return;
}
player->m_Events.AddEvent(new PartyTimeEmoteEvent(player), RAND(player->m_Events.CalculateTime(5000), player->m_Events.CalculateTime(10000), player->m_Events.CalculateTime(15000)));
player->m_Events.AddEventAtOffset(new PartyTimeEmoteEvent(player), RAND(5s, 10s, 15s));
}
void Register() override