summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/sql/updates/db_world/2025_10_18_00.sql7
-rw-r--r--data/sql/updates/db_world/2025_10_18_01.sql6
-rw-r--r--data/sql/updates/db_world/2025_10_18_02.sql94
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp42
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp112
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp152
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h15
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp71
8 files changed, 211 insertions, 288 deletions
diff --git a/data/sql/updates/db_world/2025_10_18_00.sql b/data/sql/updates/db_world/2025_10_18_00.sql
new file mode 100644
index 0000000000..12c66d7e1c
--- /dev/null
+++ b/data/sql/updates/db_world/2025_10_18_00.sql
@@ -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');
diff --git a/data/sql/updates/db_world/2025_10_18_01.sql b/data/sql/updates/db_world/2025_10_18_01.sql
new file mode 100644
index 0000000000..283cd01aab
--- /dev/null
+++ b/data/sql/updates/db_world/2025_10_18_01.sql
@@ -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
diff --git a/data/sql/updates/db_world/2025_10_18_02.sql b/data/sql/updates/db_world/2025_10_18_02.sql
new file mode 100644
index 0000000000..f28a79c446
--- /dev/null
+++ b/data/sql/updates/db_world/2025_10_18_02.sql
@@ -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;
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
index 916fad6a57..3c51b4fa0f 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_ionar.cpp
@@ -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,
};
@@ -75,8 +72,11 @@ struct boss_ionar : public BossAI
void Reset() override
{
_Reset();
- HealthCheck = 50;
me->SetVisible(true);
+
+ ScheduleHealthCheckEvent(50, [&] {
+ DoCastSelf(SPELL_DISPERSE);
+ });
}
void ScheduleEvents(bool spark)
@@ -120,16 +120,14 @@ struct boss_ionar : public BossAI
{
Talk(SAY_SPLIT);
- Creature* spark;
for (uint8 i = 0; i < 5; ++i)
{
- if ((spark = me->SummonCreature(NPC_SPARK_OF_IONAR, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 20000)))
+ if (Creature* spark = me->SummonCreature(NPC_SPARK_OF_IONAR, me->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 20000))
{
- summons.Summon(spark);
- spark->CastSpell(spark, me->GetMap()->IsHeroic() ? SPELL_SPARK_VISUAL_TRIGGER_H : SPELL_SPARK_VISUAL_TRIGGER_N, true);
+ 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->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0);
+ spark->SetHomePosition(me->GetPosition());
if (Player* tgt = SelectTargetFromPlayerList(100))
spark->GetMotionMaster()->MoveFollow(tgt, 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
@@ -156,23 +154,13 @@ struct boss_ionar : public BossAI
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);
-
+ DoCastRandomTarget(SPELL_BALL_LIGHTNING, 1, 0.0f, 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);
-
+ DoCastRandomTarget(SPELL_STATIC_OVERLOAD);
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);
@@ -192,9 +180,6 @@ struct boss_ionar : public BossAI
DoMeleeAttackIfReady();
}
-
- private:
- uint8 HealthCheck;
};
struct npc_spark_of_ionar : public ScriptedAI
@@ -252,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
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
index c70f60ee6d..043f9087d4 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
@@ -62,36 +62,43 @@ enum LokenEvents
struct boss_loken : public BossAI
{
- boss_loken(Creature* creature) : BossAI(creature, DATA_LOKEN)
- {
- isActive = instance->GetData(DATA_LOKEN_INTRO);
- }
-
- void MoveInLineOfSight(Unit*) override { }
+ boss_loken(Creature* creature) : BossAI(creature, DATA_LOKEN), _introDone(false) { }
void Reset() override
{
_Reset();
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEVEMENT_TIMELY_DEATH);
- 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);
- }
+ ScheduleHealthCheckEvent(75, [&] {
+ Talk(SAY_75HEALTH);
+ });
+
+ ScheduleHealthCheckEvent(50, [&] {
+ Talk(SAY_50HEALTH);
+ });
+
+ ScheduleHealthCheckEvent(25, [&] {
+ Talk(SAY_25HEALTH);
+ });
+ }
+
+ void MoveInLineOfSight(Unit* who) override
+ {
+ 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);
@@ -109,27 +116,6 @@ struct boss_loken : public BossAI
Talk(SAY_DEATH);
}
- 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
- Talk(SAY_NOVA);
- }
-
void KilledUnit(Unit* victim) override
{
if (!victim->IsPlayer())
@@ -140,40 +126,6 @@ struct boss_loken : public BossAI
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;
- instance->SetData(DATA_LOKEN_INTRO, 1);
-
- me->SetControlled(false, UNIT_STATE_STUNNED);
- me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
-
- if (GameObject* globe = instance->GetGameObject(DATA_LOKEN_THRONE))
- globe->SetGoState(GO_STATE_ACTIVE);
- }
-
- return;
- }
-
//Return since we have no target
if (!UpdateVictim())
return;
@@ -185,16 +137,8 @@ struct boss_loken : public BossAI
switch (events.ExecuteEvent())
{
- case EVENT_CHECK_HEALTH:
- if (HealthBelowPct(HealthCheck))
- {
- LokenSpeach(true);
- HealthCheck -= 25;
- }
-
- events.Repeat(1s);
- break;
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);
@@ -221,9 +165,7 @@ struct boss_loken : public BossAI
DoMeleeAttackIfReady();
}
private:
- bool isActive;
- uint32 IntroTimer;
- uint8 HealthCheck;
+ bool _introDone;
};
class spell_loken_pulsing_shockwave : public SpellScript
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
index 2489020e51..30e110231f 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
@@ -372,160 +372,8 @@ private:
InstanceScript* m_pInstance;
};
-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,
-};
-
-struct npc_hol_monument : public ScriptedAI
-{
- npc_hol_monument(Creature* creature) : ScriptedAI(creature)
- {
- _attackGUID.Clear();
- _isActive = urand(0, 1);
- me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
- me->CastSpell(me, SPELL_FREEZE_ANIM, true);
- }
-
- 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();
- }
-
- private:
- EventMap events;
- bool _isActive;
- ObjectGuid _attackGUID;
-};
-
void AddSC_boss_volkhan()
{
RegisterHallOfLightningCreatureAI(boss_volkhan);
RegisterHallOfLightningCreatureAI(npc_molten_golem);
- RegisterHallOfLightningCreatureAI(npc_hol_monument);
}
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h
index 80f06acab6..99b3fecb81 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/halls_of_lightning.h
@@ -35,8 +35,6 @@ enum HoLBossIds
enum HoLDataTypes
{
- DATA_LOKEN_INTRO = 0,
-
// GameObject data
DATA_LOKEN_THRONE = 0,
@@ -47,17 +45,20 @@ enum HoLDataTypes
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_VOLKHAN_DOOR = 191325,
GO_IONAR_DOOR = 191326,
- GO_LOKEN_THRONE = 192654,
+ GO_LOKEN_THRONE = 192654
+};
+
+enum HoLActions
+{
+ ACTION_ACTIVATE_TITANIUM_VRYKUL,
};
template <class AI, class T>
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp
index fb480c0a47..1341f31c06 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/instance_halls_of_lightning.cpp
@@ -15,8 +15,10 @@
* 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"
@@ -46,8 +48,8 @@ public:
SetBossNumber(MAX_ENCOUNTERS);
LoadDoorData(doorData);
LoadObjectData(nullptr, gameObjectData);
- volkhanAchievement = false;
- bjarngrimAchievement = false;
+ _volkhanAchievement = false;
+ _bjarngrimAchievement = false;
};
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) override
@@ -55,33 +57,25 @@ public:
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
{
- if (uiType == DATA_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;
-
- SaveToDB();
+ _volkhanAchievement = (bool)uiData;
}
private:
- bool volkhanAchievement;
- bool bjarngrimAchievement;
+ bool _volkhanAchievement;
+ bool _bjarngrimAchievement;
};
InstanceScript* GetInstanceScript(InstanceMap* pMap) const override
@@ -90,7 +84,52 @@ public:
}
};
+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();
}