Compare commits

...

22 Commits

Author SHA1 Message Date
sogladev
2b3520ffcc
Merge b33b932b664fe2e2944d7e94608ad857290eae5e into 5bef92d5eaca3e2ecc317f9d599312bc23eb71aa 2025-11-10 03:24:55 +01:00
github-actions[bot]
5bef92d5ea chore(DB): import pending files
Referenced commit(s): 723aae903999e84f8cbfc9de263462d64f3aadf0
2025-11-09 22:15:10 +00:00
sogladev
723aae9039
fix(Scripts/Northrend): Zul'Drak Betrayal quest (#23562) 2025-11-09 23:14:07 +01:00
Andrew
283f03bdcd
fix(Scripts/HoL): Killing Volkhan should despawn all Slags (#23581) 2025-11-09 23:06:47 +01:00
github-actions[bot]
57daeed03a chore(DB): import pending files
Referenced commit(s): 36d739ee42006ba7018f595b36a7cbcc54d06630
2025-11-09 22:06:42 +00:00
Andrew
36d739ee42
fix(DB/Spells): Ionar spark Arcing Burn should stack from different c… (#23588) 2025-11-09 23:05:35 +01:00
github-actions[bot]
3ad79541f6 chore(DB): import pending files
Referenced commit(s): be58898d061b940c13f2039695b270a242591de0
2025-11-09 18:05:21 +00:00
sogladev
be58898d06
fix(DB/SmartAI): Howling Fjord quest vehicle Iron Rune Construct (#23063)
Co-authored-by: Killyana <morphone1@gmail.com>
2025-11-09 15:04:17 -03:00
github-actions[bot]
611a85529d chore(DB): import pending files
Referenced commit(s): 040e7a0a4d690532a0bd240a515f0519173d9e4a
2025-11-09 13:15:20 +00:00
Andrew
040e7a0a4d
fix(DB/Creature): Despawn all instances of Superior Healing Ward (#23584) 2025-11-09 10:14:19 -03:00
github-actions[bot]
d4cd580ddc chore(DB): import pending files
Referenced commit(s): 37833c66e69733c68c4244c2a2070b5c2421f0a8
2025-11-09 08:50:22 +00:00
Andrew
37833c66e6
fix(DB/Creature): Remove xp from Reclamation mobs (#23579) 2025-11-09 05:49:21 -03:00
github-actions[bot]
ec274182a2 chore(DB): import pending files
Referenced commit(s): d9b2e775e3266f4b592ca09eefd99b6f212d1861
2025-11-09 07:58:11 +00:00
Andrew
d9b2e775e3
fix(DB/Creature): Fix Sorlof visibility distance (#23573) 2025-11-09 04:57:04 -03:00
killerwife
c85c86b285
Remove double unroot in Unit::_ExitVehicle (#23545) 2025-11-08 19:40:30 -03:00
sogladev
125e1aec9d
fix(Scripts/AzjolNerub): update Azjol-Nerub's Anub'arak (#23570) 2025-11-08 17:27:56 -03:00
Andrew
fca2e12056
fix(Scripts/DTK): Fix a couple of Prophet Tharon'ja issues (#23568) 2025-11-08 20:01:55 +01:00
github-actions[bot]
c9aedce67f chore(DB): import pending files
Referenced commit(s): e1d28ae712d077b9f4de445417ed4a4e2b89c8bf
2025-11-08 17:15:22 +00:00
Benjamin Jackson
e1d28ae712
fix(DB/Creature): Adjust experience modifiers for Wrath instance bosses. (#23567) 2025-11-08 14:14:21 -03:00
github-actions[bot]
983557345e chore(DB): import pending files
Referenced commit(s): 743a764c3cb22a013a49338edf250b1b643ebd8e
2025-11-08 17:09:19 +00:00
Andrew
743a764c3c
fix(DB/Conditions): Malister's Frost Wand should require Proto-Drake (#23569) 2025-11-08 14:08:15 -03:00
Jelle Meeus
b33b932b66
fix(Scripts/Northrend): Azjol-Nerub Hadronox
Allow reset trick for 'Hadronox Denied' achievement
Fix web grab LoS issue
Update boss spawn
Update crusher packs handling, summoning, pathing
Update foe waypoints and smartAI
Update hadronox movement points
Refactor spelldifficulty_dbc
Refactor registry macros

[3.3.5] Azjol-Nerub rewrite
4b990eb7d7

Co-authored-by: Treeston <treeston.mmoc@gmail.com>
2025-11-06 16:54:09 +01:00
18 changed files with 1356 additions and 554 deletions

View File

@ -0,0 +1,5 @@
-- DB update 2025_11_08_00 -> 2025_11_08_01
--
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 17) AND (`SourceGroup` = 0) AND (`SourceEntry` = 40969) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 31) AND (`ConditionTarget` = 1) AND (`ConditionValue1` = 3) AND (`ConditionValue2` = 23689) AND (`ConditionValue3` = 0);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(17, 0, 40969, 0, 0, 31, 1, 3, 23689, 0, 0, 0, 0, '', 'Malister Frost Wand require Proto-Drake');

View File

@ -0,0 +1,172 @@
-- DB update 2025_11_08_01 -> 2025_11_08_02
SET @BossXPMod = 7.5,
@FinalBossXPMod = 10;
UPDATE `creature_template` SET `ExperienceModifier` = @BossXPMod WHERE `entry` IN (
-- Utgarde Keep
23953, -- Prince Keleseth
30748,
24200, -- Skarvald the Constructor
31679,
24201, -- Dalronn the Controller
31656,
-- Azjol-Nerub
28684, -- Krik'thir the Gatewatcher
31612,
28921, -- Hadronox
31611,
-- Ahn'kahet: The Old Kingdom
29309, -- Elder Nadox
31456,
29308, -- Prince Taldaram
31469,
29310, -- Jedoga Shadowseeker
31465,
30258, -- Amanitar
31463,
-- The Nexus
26731, -- Grand Magus Telestra
30510,
26763, -- Anomalus
30529,
26794, -- Ormorok the Tree-Shaper
30532,
26796, -- Commander Stoutbeard
30398,
26798, -- Commander Kolurg
30397,
-- Drak'Tharon Keep
26630, -- Trollgore
31362,
26631, -- Novos the Summoner
31350,
-- 27483, -- King Dred, observed to not give as much experience as this
-- 31349,
-- The Violet Hold
29315, -- Erekem
31507,
29316, -- Moragg
31510,
29313, -- Ichoron
31508,
29266, -- Xevozz
31511,
29312, -- Lavanthor
31509,
29314, -- Zuramat the Obliterator
31512,
-- Gundrak
29304, -- Slad'ran
31370,
-- 29573, -- Drakkari Elemental, observed to not give as much experience as this
-- 31367,
29305, -- Moorabi
30530,
29932, -- Eck the Ferocious
-- Halls of Stone
27975, -- Maiden of Grief
31384,
27977, -- Krystallus
31381,
-- Halls of Lightning
28586, -- General Bjarngrim
31533,
28587, -- Volkhan
31536,
28546, -- Ionar
31537,
-- The Oculus
27654, -- Drakos the Interrogator
31558,
27447, -- Varos Cloudstrider
31559,
27655, -- Mage-Lord Urom
31560,
-- Utgarde Pinnacle
26668, -- Svala Sorrowgrave
30810,
26687, -- Gortok Palehoof
30774,
26693, -- Skadi the Ruthless
30807,
-- The Culling of Stratholme
26529, -- Meathook
31211,
26530, -- Salramm the Fleshcrafter
31212,
26532, -- Chrono-Lord Epoch
31215,
32273, -- Infinite Corruptor
32313,
-- Trial of the Champion
34705, -- Marshal Jacob Alerius
36088,
34702, -- Ambrose Boltspark
36082,
34701, -- Colosos
36083,
34657, -- Jaelyne Evensong
36086,
34703, -- Lana Stouthammer
36087,
35572, -- Mokra the Skullcrusher
36089,
35569, -- Eressea Dawnsinger
36085,
35571, -- Runok Wildmane
36090,
35570, -- Zul'tore
36091,
35617, -- Deathstalker Visceri
36084,
35119, -- Eadric the Pure
35518,
34928, -- Argent Confessor Paletress
35517,
-- The Forge of Souls
36497, -- Bronjahm
36498,
-- Pit of Saron
36494, -- Forgemaster Garfrost
37613,
36476, -- Ick
37627,
-- Halls of Reflection
38112, -- Falric
38599,
38113, -- Marwyn
38603
);
UPDATE `creature_template` SET `ExperienceModifier` = @FinalBossXPMod WHERE `entry` IN (
23954, -- Ingvar the Plunderer, Utgarde Keep
31673,
29120, -- Anub'arak, Azjol-Nerub
31610,
29311, -- Herald Volazj,
31464,
26723, -- Keristrasza
30540,
26632, -- The Prophet Tharon'ja
31360,
31134, -- Cyanigosa
31506,
29306, -- Gal'darah
31368,
27978, -- Sjonnir The Ironshaper
31386,
28923, -- Loken
31538,
27656, -- Ley-Guardian Eregos
31561,
26861, -- King Ymiron
30788,
26533, -- Mal'Ganis
31217,
35451, -- The Black Knight, Trial of the Champion
35490,
36502, -- Devourer of Souls, Forge of Souls
37677,
36658, -- Scourgelord Tyrannus, Pit of Saron
36938
);

View File

@ -0,0 +1,3 @@
-- DB update 2025_11_08_02 -> 2025_11_09_00
--
UPDATE `creature_addon` SET `visibilityDistanceType` = 3 WHERE `guid` = 103278;

View File

@ -0,0 +1,3 @@
-- DB update 2025_11_09_00 -> 2025_11_09_01
--
UPDATE `creature_template` SET `flags_extra` = `flags_extra`|64 WHERE `entry` IN (28220, 28218, 28242, 28103, 28212, 28207, 28170);

View File

@ -0,0 +1,3 @@
-- DB update 2025_11_09_01 -> 2025_11_09_02
--
DELETE FROM `creature` WHERE `id1` = 10218;

View File

@ -0,0 +1,67 @@
-- DB update 2025_11_09_02 -> 2025_11_09_03
--
-- Fixes "Bluff", Set `allowOverride` of action list
UPDATE `smart_scripts` SET `action_param3` = 1 WHERE (`entryorguid` IN (23672, 23673, 23675, 24271)) AND (`source_type` = 0) AND (`event_type` = 8) AND (`event_param1` = 44609);
-- Removes double spawns
DELETE FROM `gameobject` WHERE `id` = 186959 AND `guid` IN (264459, 264460, 264461, 264462, 264463, 264464, 264465);
-- Add missing aura. Usage is unknown
DELETE FROM `creature_template_addon` WHERE (`entry` = 24825);
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
(24825, 0, 0, 0, 0, 0, 0, '44652');
-- Disable flying vehicle, but causes camera stuttering on rocket jump
UPDATE `creature_template_movement` SET `Flight` = 0 WHERE (`CreatureId` = 24825);
DELETE FROM `creature_text` WHERE (`CreatureID` = 24825) AND (`GroupID` = 1);
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(24825, 1, 0, 'Launching.', 12, 0, 100, 0, 0, 0, 23860, 0, 'Iron Rune Construct');
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 24825) AND (`source_type` = 0) AND (`id` IN (15, 16));
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
(24825, 0, 15, 0, 31, 0, 100, 512, 44609, 0, 3000, 3000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Spellhit \'Bluff\' - Say Line 0'),
(24825, 0, 16, 0, 8, 0, 100, 512, 44626, 0, 5000, 5000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Spellhit \'Rocket Jump\' - Say Line 1');
-- Remove unused 'Say Line 0' in actionscripts
DELETE FROM `smart_scripts` WHERE (`entryorguid` IN (2367201, 2367301, 2367501, 2427101)) AND `source_type` = 9 AND `id` = 1 AND `target_type` = 19 AND `target_param1` = 24825 AND `action_type` = 1 AND `target_param2` = 20;
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` IN (2, 4)) AND (`SourceEntry` = 44608) AND (`SourceId` = 0) AND (`ConditionTypeOrReference` = 31);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 4, 44608, 0, 0, 31, 0, 3, 24826, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 4, 44608, 0, 1, 31, 0, 3, 24827, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 4, 44608, 0, 2, 31, 0, 3, 24828, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 4, 44608, 0, 3, 31, 0, 3, 24829, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 4, 44608, 0, 4, 31, 0, 3, 24831, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 4, 44608, 0, 5, 31, 0, 3, 24832, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 2, 44608, 0, 0, 31, 0, 5, 186953, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 2, 44608, 0, 1, 31, 0, 5, 186960, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 2, 44608, 0, 2, 31, 0, 5, 186961, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 2, 44608, 0, 3, 31, 0, 5, 186963, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 2, 44608, 0, 4, 31, 0, 5, 186962, 0, 0, 0, 0, '', 'Rocket Jump'),
(13, 2, 44608, 0, 5, 31, 0, 5, 186964, 0, 0, 0, 0, '', 'Rocket Jump');
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` = 24825);
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
(24825, 0, 0, 0, 54, 0, 100, 512, 0, 0, 0, 0, 0, 0, 75, 44643, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Just Summoned - Add Aura \'Reputation and Language\''),
(24825, 0, 1, 0, 28, 0, 100, 512, 0, 0, 0, 0, 0, 0, 28, 44643, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Passenger Removed - Remove Aura \'Reputation and Language\''),
(24825, 0, 2, 0, 38, 0, 100, 512, 0, 1, 0, 0, 0, 0, 53, 2, 24826, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Data Set 0 1 - Start Waypoint Path 24826'),
(24825, 0, 3, 0, 38, 0, 100, 512, 0, 2, 0, 0, 0, 0, 53, 2, 24827, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Data Set 0 2 - Start Waypoint Path 24827'),
(24825, 0, 4, 0, 38, 0, 100, 512, 0, 3, 0, 0, 0, 0, 53, 2, 24828, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Data Set 0 3 - Start Waypoint Path 24828'),
(24825, 0, 5, 0, 38, 0, 100, 512, 0, 4, 0, 0, 0, 0, 53, 2, 24831, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Data Set 0 4 - Start Waypoint Path 24831'),
(24825, 0, 6, 0, 38, 0, 100, 512, 0, 5, 0, 0, 0, 0, 53, 2, 24829, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Data Set 0 5 - Start Waypoint Path 24829'),
(24825, 0, 7, 0, 38, 0, 100, 512, 0, 6, 0, 0, 0, 0, 53, 2, 24832, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Data Set 0 6 - Start Waypoint Path 24832'),
(24825, 0, 8, 0, 58, 0, 100, 512, 0, 0, 0, 0, 0, 0, 28, 44626, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Path 0 Finished - Remove Aura \'Rocket Jump\''),
(24825, 0, 9, 0, 31, 0, 100, 512, 44609, 0, 3000, 3000, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Target Spellhit \'Bluff\' - Say Line 0'),
(24825, 0, 10, 0, 8, 0, 100, 512, 44626, 0, 5000, 5000, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Iron Rune Construct - On Spellhit \'Rocket Jump\' - Say Line 1');
--
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE (`entry` IN (24826, 24827, 24828, 24829, 24831, 24832));
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` IN (24826, 24827, 24828, 24829, 24831, 24832));
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
(24826, 0, 0, 0, 8, 0, 100, 0, 44608, 0, 0, 0, 0, 0, 45, 0, 1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'On Spellhit \'Rocket Jump\' - Set Data 0 1'),
(24827, 0, 0, 0, 8, 0, 100, 0, 44608, 0, 0, 0, 0, 0, 45, 0, 2, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'On Spellhit \'Rocket Jump\' - Set Data 0 2'),
(24828, 0, 0, 0, 8, 0, 100, 0, 44608, 0, 0, 0, 0, 0, 45, 0, 3, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'On Spellhit \'Rocket Jump\' - Set Data 0 3'),
(24831, 0, 0, 0, 8, 0, 100, 0, 44608, 0, 0, 0, 0, 0, 45, 0, 4, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'On Spellhit \'Rocket Jump\' - Set Data 0 4'),
(24829, 0, 0, 0, 8, 0, 100, 0, 44608, 0, 0, 0, 0, 0, 45, 0, 5, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'On Spellhit \'Rocket Jump\' - Set Data 0 5'),
(24832, 0, 0, 0, 8, 0, 100, 0, 44608, 0, 0, 0, 0, 0, 45, 0, 6, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'On Spellhit \'Rocket Jump\' - Set Data 0 6');
DELETE FROM `smart_scripts` WHERE `source_type` = 9 AND `entryorguid` IN (2482600, 2482700, 2482800, 2482900, 2483100, 2483200);

View File

@ -0,0 +1,6 @@
-- DB update 2025_11_09_03 -> 2025_11_09_04
--
DELETE FROM `spell_custom_attr` WHERE `spell_id` IN (52671, 59834);
INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES
(52671, 0x00400000),
(59834, 0x00400000);

View File

@ -0,0 +1,79 @@
-- DB update 2025_11_09_04 -> 2025_11_09_05
--
-- v11_2_5_63906
SET @VBUILD := 63906;
DELETE FROM `creature_template_addon` WHERE (`entry` = 28503);
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
(28503, 0, 0, 0, 0, 0, 0, '58837');
DELETE FROM `creature_template_addon` WHERE (`entry` = 28998);
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
(28998, 0, 0, 0, 0, 0, 0, '58837');
DELETE FROM `creature` WHERE (`id1` = 28998) AND (`guid` IN (1974609));
INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `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`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES
(1974609, 28998, 0, 0, 571, 0, 0, 1, 1, 0, 6175.2456, -2017.6545, 590.9613, 3.0019662, 300, 0, 0, 550001, 0, 0, 0, 0, 0, '', NULL, @VBUILD);
DELETE FROM `creature_template_addon` WHERE (`entry` = 28998);
INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
(28998, 0, 0, 0, 1, 0, 0, '');
UPDATE `spell_target_position` SET `PositionX`=6161.15, `PositionY`=-2015.36, `PositionZ`=590.878, `Orientation`=6.283189773559570312, `VerifiedBuild`=@VBUILD WHERE `ID`=52863 AND `EffectIndex`=0;
UPDATE `creature_template_addon` SET `bytes2` = 1 WHERE (`entry` = 28717);
-- Update comments
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 28498) AND (`source_type` = 0) AND (`id` IN (0, 1, 2, 3, 4));
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
(28498, 0, 0, 0, 54, 0, 100, 512, 0, 0, 0, 0, 0, 0, 53, 1, 28498, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'The Lich King - On Just Summoned - Start Waypoint Path 28498'),
(28498, 0, 1, 2, 40, 0, 100, 512, 2, 0, 0, 0, 0, 0, 54, 83000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'The Lich King - On Point 2 of Path Any Reached - Pause Waypoint'),
(28498, 0, 2, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 80, 2849800, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'The Lich King - On Point 2 of Path Any Reached - Run Script'),
(28498, 0, 3, 4, 40, 0, 100, 512, 3, 0, 0, 0, 0, 0, 45, 0, 2, 0, 0, 0, 0, 10, 127495, 0, 0, 0, 0, 0, 0, 0, 'The Lich King - On Point 3 of Path Any Reached - Set Data 0 2'),
(28498, 0, 4, 0, 61, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'The Lich King - On Point 3 of Path Any Reached - Despawn Instant');
-- Disable gravity
DELETE FROM `creature_template_movement` WHERE (`CreatureId` = 29100);
INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES
(29100, 0, 0, 1, 0, 0, 0, 0);
-- Idle
UPDATE `creature` SET `MovementType` = 0, `wander_distance` = 0 WHERE `id1` = 29100 AND `guid` IN (112307, 112308, 112309, 112310);
UPDATE `gameobject_template` SET `AIName` = 'SmartGameObjectAI' WHERE `entry` = 202357;
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 202357) AND (`source_type` = 1) AND (`id` IN (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
(202357, 1, 0, 0, 62, 0, 100, 0, 11091, 0, 0, 0, 0, 0, 11, 57553, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Drakuru\'s Last Wish - On Gossip Option 0 Selected - Cast \'Escape Voltarus\'');
-- Drakuru's Last Wish
UPDATE `gameobject_template_addon` SET `flags` = 32 WHERE (`entry` = 202357);
-- Skull and Portal spells target 'Totally Generic Bunny (JSB)'
DELETE FROM `creature` WHERE (`id1` = 28960) and `guid` IN (98914, 98920);
INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `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`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES
(98914, 28960, 0, 0, 571, 0, 0, 1, 1, 0, 6144.01, -2011.8, 590.963, 6.16101, 300, 0, 0, 4979, 0, 0, 0, 0, 0, '', '\'Throw Portal Crystal\' guid target', @VBUILD),
(98920, 28960, 0, 0, 571, 0, 0, 1, 1, 0, 6181.5137, -2032.4258, 590.96124, 1.01229, 300, 0, 0, 4979, 0, 0, 0, 0, 0, '', '\'Drakuru\'s Skull Missile\' guid target', @VBUILD);
UPDATE `conditions` SET `ConditionValue3` = 98914, `Comment` = 'target Totally Generic Bunny (JSB)' WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 54209) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 31) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 3) AND (`ConditionValue2` = 28960) AND (`ConditionValue3` = 0);
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 54250) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 31) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 3) AND (`ConditionValue2` = 28960);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 54250, 0, 0, 31, 0, 3, 28960, 98920, 0, 0, 0, '', 'target Totally Generic Bunny (JSB)');
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceGroup` = 1) AND (`SourceEntry` = 54089) AND (`SourceId` = 0) AND (`ElseGroup` = 0) AND (`ConditionTypeOrReference` = 1) AND (`ConditionTarget` = 0) AND (`ConditionValue1` = 51966) AND (`ConditionValue2` = 0) AND (`ConditionValue3` = 0);
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(13, 1, 54089, 0, 0, 1, 0, 51966, 0, 0, 0, 0, 0, '', 'Has Aura \'Scourge Disguise\'');
-- 54104 Blight Fog
UPDATE `creature_template_addon` SET `auras` = '54104' WHERE (`entry` = 28998);
DELETE FROM `creature_summon_groups` WHERE `summonerId` = 28998 and `summonerType` = 0 AND `groupId` = 1;
INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`, `Comment`) VALUES
(28998, 0, 1, 28931, 6184.1455, -1970.1699, 586.84186, 4.5902, 8, 0, 'Overlord Drakuru - Group 1 - Blightblood Troll'),
(28998, 0, 1, 28931, 6222.855, -2026.6315, 586.84186, 3.00197, 8, 0, 'Overlord Drakuru - Group 1 - Blightblood Troll'),
(28998, 0, 1, 28931, 6166.278, -2065.3123, 586.84186, 1.44862, 8, 0, 'Overlord Drakuru - Group 1 - Blightblood Troll'),
(28998, 0, 1, 28931, 6127.5117, -2008.6506, 586.84186, 6.16101, 8, 0, 'Overlord Drakuru - Group 1 - Blightblood Troll');
-- 54105 Blight Fog
DELETE FROM `spell_script_names` WHERE (`spell_id` = 54105);
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(54105, 'spell_blight_fog');

View File

@ -0,0 +1,74 @@
--
-- HARD_RESET
UPDATE `creature_template` SET `flags_extra` = `flags_extra` | 2147483648 WHERE (`entry` IN (28921, 31611));
DELETE FROM `spelldifficulty_dbc` WHERE `ID` IN (53406, 53317, 53394, 53330, 53322);
INSERT INTO `spelldifficulty_dbc` (`ID`, `DifficultySpellID_1`, `DifficultySpellID_2`, `DifficultySpellID_3`, `DifficultySpellID_4`) VALUES
(53406, 53406, 59420, 0, 0),
(53317, 53317, 59343, 0, 0),
(53394, 53394, 59344, 0, 0),
(53330, 53330, 59348, 0, 0),
(53322, 53322, 59347, 0, 0);
DELETE FROM `spell_script_names` WHERE `spell_id` IN (53406, 59420) AND `ScriptName` = 'spell_hadronox_web_grab';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(53406, 'spell_hadronox_web_grab'),
(59420, 'spell_hadronox_web_grab');
DELETE FROM `creature_summon_groups` WHERE `summonerId` = 28921;
INSERT INTO `creature_summon_groups` (`summonerId`, `summonerType`, `groupId`, `entry`, `position_x`, `position_y`, `position_z`, `orientation`, `summonType`, `summonTime`, `Comment`) VALUES
(28921, 0, 1, 28922, 529.691, 547.126, 731.916, 4.79965, 6, 45000, 'Hadronox - Group 1 - Anub''ar Crusher'),
(28921, 0, 1, 29117, 539.208, 549.754, 732.867, 4.55531, 6, 30000, 'Hadronox - Group 1 - Anub''ar Champion'),
(28921, 0, 1, 29118, 520.391, 548.789, 732.012, 5.0091, 6, 30000, 'Hadronox - Group 1 - Anub''ar Crypt Fiend'),
(28921, 0, 2, 28922, 493.477, 603.344, 760.563, 5.44024, 6, 45000, 'Hadronox - Group 2 - Anub''ar Crusher'),
(28921, 0, 2, 29117, 490.442, 604.335, 763.182, 5.6256, 6, 30000, 'Hadronox - Group 2 - Anub''ar Champion'),
(28921, 0, 2, 29119, 488.825, 609.282, 767.588, 5.59029, 6, 30000, 'Hadronox - Group 2 - Anub''ar Necromancer'),
(28921, 0, 3, 28922, 566.979, 602.571, 759.642, 3.88597, 6, 45000, 'Hadronox - Group 3 - Anub''ar Crusher'),
(28921, 0, 3, 29118, 569.348, 604.999, 763.214, 4.17983, 6, 30000, 'Hadronox - Group 3 - Anub''ar Crypt Fiend'),
(28921, 0, 3, 29119, 572.474, 607.411, 767.178, 3.94417, 6, 30000, 'Hadronox - Group 3 - Anub''ar Necromancer'),
(28921, 0, 4, 23472, 581.448, 608.841, 739.405, 1.72788, 6, 3600000, 'Hadronox - Group 4 - World Trigger'),
(28921, 0, 4, 23472, 477.016, 618.4, 771.515, 2.35619, 6, 3600000, 'Hadronox - Group 4 - World Trigger'),
(28921, 0, 4, 23472, 583.091, 617.371, 771.551, 0.645772, 6, 3600000, 'Hadronox - Group 4 - World Trigger');
DELETE FROM `creature` WHERE (`id1` = 23472) AND (`guid` IN (127376, 127377, 127378));
DELETE FROM `creature_addon` WHERE (`guid` IN (127376, 127377, 127378));
DELETE FROM `smart_scripts` WHERE (`source_type` = 0) AND (`entryorguid` IN (29117, 29118, 29119));
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_anub_ar_crusher_champion' WHERE (`entry` = 29117);
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_anub_ar_crusher_crypt_fiend' WHERE (`entry` = 29118);
UPDATE `creature_template` SET `AIName` = '', `ScriptName` = 'npc_anub_ar_crusher_necromancer' WHERE (`entry` = 29119);
SET @SPAWN_X := 522.53107;
SET @SPAWN_Y := 544.91125;
SET @SPAWN_Z := 674.6791;
SET @SPAWN_O := 5.633617;
DELETE FROM `creature` WHERE (`id1` = 28921) AND (`guid` = 127401);
INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `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`, `ScriptName`, `Comment`, `VerifiedBuild`) VALUES
(127401, 28921, 0, 0, 601, 0, 0, 3, 1, 0, @SPAWN_X, @SPAWN_Y, @SPAWN_Z, @SPAWN_O, 86400, 0, 0, 154230, 0, 0, 0, 0, 0, '', NULL, 0);
DELETE FROM `waypoint_data` WHERE `id` IN (3000012, 3000013) AND `point` IN (13, 14);
DELETE FROM `waypoint_data` WHERE `id` = 3000014 AND `point` IN (9, 10);
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(3000012, 13, 538.0253, 529.9829, 686.0557, 0, 1, 0, 100, 0),
(3000012, 14, 532.7753, 535.2329, 681.0557, 0, 1, 0, 100, 0),
(3000013, 13, 538.0253, 529.9829, 686.0557, 0, 1, 0, 100, 0),
(3000013, 14, 532.7753, 535.2329, 681.0557, 0, 1, 0, 100, 0),
(3000014, 9, 538.0253, 529.9829, 686.0557, 0, 1, 0, 100, 0),
(3000014, 10, 532.7753, 535.2329, 681.0557, 0, 1, 0, 100, 0);
DELETE FROM `smart_scripts` WHERE (`source_type` = 0 AND `entryorguid` IN (29062, 29063, 29064));
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
(29062, 0, 0, 0, 0, 0, 100, 0, 4000, 7000, 12000, 18000, 0, 0, 11, 53317, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Champion - In Combat - Cast \'Rend\''),
(29062, 0, 1, 0, 105, 0, 100, 0, 9000, 13000, 9000, 13000, 0, 5, 11, 53394, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Champion - On Hostile Casting in Range - Cast \'Pummel\''),
(29062, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 10000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Champion - On Just Died - Despawn In 10000 ms'),
(29062, 0, 3, 0, 1, 0, 100, 0, 10000, 10000, 1000, 1000, 0, 0, 49, 0, 0, 0, 0, 0, 0, 11, 28921, 50, 1, 0, 0, 0, 0, 0, 'Anub\'ar Champion Out of Combat - Start Attacking'),
(29062, 0, 4, 0, 0, 0, 100, 0, 15000, 50000, 15000, 50000, 0, 0, 11, 53798, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Champion - In Combat - Cast \'Taunt\''),
(29063, 0, 0, 0, 0, 0, 100, 0, 4000, 7000, 9000, 12000, 0, 0, 11, 53330, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - In Combat - Cast \'Infected Wound\''),
(29063, 0, 1, 0, 0, 0, 100, 0, 9000, 12000, 13000, 17000, 0, 0, 11, 53322, 0, 0, 0, 0, 0, 5, 30, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - In Combat - Cast \'Crushing Webs\''),
(29063, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 10000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - On Just Died - Despawn In 10000 ms'),
(29063, 0, 3, 0, 1, 0, 100, 0, 10000, 10000, 1000, 1000, 0, 0, 49, 0, 0, 0, 0, 0, 0, 11, 28921, 50, 1, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - Out of Combat - Start Attacking'),
(29063, 0, 4, 0, 0, 0, 100, 0, 15000, 50000, 15000, 50000, 0, 0, 11, 53798, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Crypt Fiend - In Combat - Cast \'Taunt\''),
(29064, 0, 0, 0, 1, 0, 100, 0, 0, 1000, 2000, 3000, 0, 0, 11, 53333, 64, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Necromancer - Out of Combat - Cast \'Shadow Bolt\''),
(29064, 0, 2, 0, 6, 0, 100, 512, 0, 0, 0, 0, 0, 0, 41, 10000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Necromancer - On Just Died - Despawn In 10000 ms'),
(29064, 0, 3, 0, 1, 0, 100, 0, 10000, 10000, 1000, 1000, 0, 0, 49, 0, 0, 0, 0, 0, 0, 11, 28921, 50, 1, 0, 0, 0, 0, 0, 'Anub\'ar Necromancer Out of Combat - Start Attacking'),
(29064, 0, 4, 0, 0, 0, 100, 0, 15000, 50000, 15000, 50000, 0, 0, 11, 53798, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 'Anub\'ar Necromancer - In Combat - Cast \'Taunt\'');

View File

@ -19586,12 +19586,6 @@ void Unit::_ExitVehicle(Position const* exitPosition)
sScriptMgr->AnticheatSetUnderACKmount(player);
}
else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT))
{
WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
data << GetPackGUID();
SendMessageToSet(&data, false);
}
// xinef: hack for flameleviathan seat vehicle
VehicleEntry const* vehicleInfo = vehicle->GetVehicleInfo();

View File

@ -2187,12 +2187,6 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(1);
});
// Halls of Lightning, Arcing Burn
ApplySpellFix({ 52671, 59834 }, [](SpellInfo* spellInfo)
{
spellInfo->AttributesEx3 |= SPELL_ATTR3_DOT_STACKING_RULE;
});
// Trial of the Champion, Death's Respite
ApplySpellFix({ 68306 }, [](SpellInfo* spellInfo)
{

View File

@ -43,6 +43,7 @@ enum ANIds
NPC_HADRONOX = 28921,
NPC_ANUBARAK = 29120,
NPC_WORLD_TRIGGER_LAOI = 23472,
NPC_ANUB_AR_CHAMPION = 29062,
NPC_ANUB_AR_NECROMANCER = 29063,
NPC_ANUB_AR_CRYPTFIEND = 29064,

View File

@ -75,7 +75,6 @@ enum Events
enum CreatureIds
{
NPC_WORLD_TRIGGER = 22515,
NPC_ANUBAR_GUARDIAN = 29216,
NPC_ANUBAR_VENOMANCER = 29217,
};
@ -133,13 +132,13 @@ struct boss_anub_arak : public BossAI
DoCastSelf(SPELL_IMPALE_PERIODIC, true);
++_submergePhase;
events.Reset();
ScheduleSubmerged();
}
}
void ScheduleEmerged()
{
events.Reset();
events.SetPhase(PHASE_EMERGED);
events.ScheduleEvent(EVENT_CARRION_BEETLES, 6500ms, 0, PHASE_EMERGED);
events.ScheduleEvent(EVENT_LEECHING_SWARM, 20s, 0, PHASE_EMERGED);
@ -148,7 +147,6 @@ struct boss_anub_arak : public BossAI
void ScheduleSubmerged()
{
events.Reset();
events.SetPhase(PHASE_SUBMERGED);
events.ScheduleEvent(EVENT_EMERGE, 60s, 0, PHASE_SUBMERGED);
@ -209,14 +207,13 @@ struct boss_anub_arak : public BossAI
}
}
void JustEngagedWith(Unit* who) override
void JustEngagedWith(Unit* /*who*/) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
events.SetPhase(PHASE_EMERGED);
events.ScheduleEvent(EVENT_CLOSE_DOORS, 5s);
events.ScheduleEvent(EVENT_CLOSE_DOORS, 5s, 0, PHASE_EMERGED);
ScheduleEmerged();
// set up world triggers
@ -288,7 +285,8 @@ struct boss_anub_arak : public BossAI
if (_remainingLargeSummonsBeforeEmerge == 0)
{
events.Reset();
events.ScheduleEvent(EVENT_EMERGE, 5s);
events.SetPhase(PHASE_SUBMERGED);
events.ScheduleEvent(EVENT_EMERGE, 5s, 0, PHASE_SUBMERGED);
}
break;
}
@ -333,10 +331,10 @@ struct boss_anub_arak : public BossAI
DoCastSelf(SPELL_SELF_ROOT, true);
me->DisableRotate(true);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_ENABLE_ROTATE, 3300ms);
events.ScheduleEvent(EVENT_ENABLE_ROTATE, 3300ms, 0, PHASE_EMERGED);
DoCast(target, SPELL_POUND);
}
events.ScheduleEvent(EVENT_POUND, 18s);
events.ScheduleEvent(EVENT_POUND, 18s, 0, PHASE_EMERGED);
break;
case EVENT_ENABLE_ROTATE:
me->RemoveAurasDueToSpell(SPELL_SELF_ROOT);

View File

@ -26,19 +26,39 @@
enum Spells
{
// World Trigger
SPELL_SUMMON_ANUBAR_CHAMPION = 53064,
SPELL_SUMMON_ANUBAR_CRYPT_FIEND = 53065,
SPELL_SUMMON_ANUBAR_NECROMANCER = 53066,
SPELL_SUMMON_ANUBAR_CHAMPION_PERIODIC = 53035,
SPELL_SUMMON_ANUBAR_NECROMANCER_PERIODIC = 53036,
SPELL_SUMMON_ANUBAR_CRYPT_FIEND_PERIODIC = 53037,
// Hadronox
SPELL_WEB_FRONT_DOORS = 53177,
SPELL_WEB_SIDE_DOORS = 53185,
SPELL_ACID_CLOUD = 53400,
SPELL_LEECH_POISON = 53030,
SPELL_LEECH_POISON_HEAL = 53800,
SPELL_WEB_GRAB = 57731,
SPELL_WEB_GRAB = 53406,
SPELL_PIERCE_ARMOR = 53418,
// Anub'ar Crusher
SPELL_SMASH = 53318,
SPELL_FRENZY = 53801
SPELL_FRENZY = 53801,
// Anub'ar Champion
SPELL_REND = 59343,
SPELL_PUMMEL = 59344,
// Anub'ar Crypt Guard
SPELL_CRUSHING_WEBS = 59347,
SPELL_INFECTED_WOUND = 59348,
// Anub'ar Necromancer
SPELL_SHADOW_BOLT = 53333,
SPELL_ANIMATE_BONES_1 = 53334,
SPELL_ANIMATE_BONES_2 = 53336,
};
enum Events
@ -54,274 +74,533 @@ enum Events
EVENT_HADRONOX_SUMMON = 9,
EVENT_CRUSHER_SMASH = 20,
EVENT_CHECK_HEALTH = 21
EVENT_CHECK_HEALTH = 21,
EVENT_CHECK_EVADE = 22,
// Anub'ar Champion
EVENT_REND,
EVENT_PUMMEL,
// Anub'ar Crypt Guard
EVENT_CRUSHING_WEBS,
EVENT_INFECTED_WOUND,
// Anub'ar Necromancer
EVENT_SHADOW_BOLT,
EVENT_ANIMATE_BONES
};
enum NPCs
{
NPC_ANUB_AR_CRUSHER = 28922,
NPC_ANUB_AR_CHAMPION_PACK = 29117,
NPC_ANUB_AR_CRYPT_FIEND_PACK = 29118,
NPC_ANUB_AR_NECROMANCER_PACK = 29119,
};
enum SummonGroups : uint32
{
SUMMON_GROUP_CRUSHER_NONE = 0,
SUMMON_GROUP_CRUSHER_1 = 1,
SUMMON_GROUP_CRUSHER_2 = 2,
SUMMON_GROUP_CRUSHER_3 = 3,
SUMMON_GROUP_WORLD_TRIGGERS = 4,
};
enum Data
{
DATA_CRUSHER_PACK_ID = 1,
};
enum Misc
{
NPC_ANUB_AR_CRUSHER = 28922,
SAY_CRUSHER_AGGRO = 0,
SAY_CRUSHER_EMOTE = 1,
SAY_CRUSHER_AGGRO = 1,
SAY_CRUSHER_EMOTE = 2,
SAY_HADRONOX_EMOTE = 0,
ACTION_DESPAWN_ADDS = 1,
ACTION_START_EVENT = 2
ACTION_CRUSHER_ENGAGED = 1,
ACTION_CRUSHER_DIED = 2,
ACTION_PACK_WALK = 3,
};
const Position hadronoxSteps[4] =
static const std::array<Position, 3> hadronoxSteps =
{{
{ 562.191f, 514.068f, 696.50710f },
{ 615.802f, 517.418f, 695.68066f },
{ 530.420f, 560.003f, 733.22473f },
}};
struct boss_hadronox : public BossAI
{
{607.9f, 512.8f, 695.3f, 0.0f},
{611.67f, 564.11f, 720.0f, 0.0f},
{576.1f, 580.0f, 727.5f, 0.0f},
{534.87f, 554.0f, 733.0f, 0.0f}
explicit boss_hadronox(Creature* creature) : BossAI(creature, DATA_HADRONOX), _crushersLeft(0), _doorsWebbed(false), _lastPlayerCombatState(false) { }
void Reset() override
{
BossAI::Reset();
SummonCrusherPack(SUMMON_GROUP_CRUSHER_1);
me->SummonCreatureGroup(SUMMON_GROUP_WORLD_TRIGGERS);
_doorsWebbed = false;
_lastPlayerCombatState = false;
}
void SummonedCreatureEvade(Creature* summon) override
{
switch (summon->GetEntry())
{
case NPC_ANUB_AR_CRUSHER:
case NPC_ANUB_AR_CHAMPION_PACK:
case NPC_ANUB_AR_CRYPT_FIEND_PACK:
case NPC_ANUB_AR_NECROMANCER_PACK:
EnterEvadeMode(EVADE_REASON_OTHER);
break;
default:
break;
}
}
void DoAction(int32 param) override
{
if (param == ACTION_CRUSHER_DIED)
--_crushersLeft;
else if (param == ACTION_CRUSHER_ENGAGED)
{
if (instance->GetBossState(DATA_HADRONOX) == IN_PROGRESS)
return;
instance->SetBossState(DATA_HADRONOX, IN_PROGRESS);
events.ScheduleEvent(EVENT_CHECK_EVADE, 5s);
SummonCrusherPack(SUMMON_GROUP_CRUSHER_2);
SummonCrusherPack(SUMMON_GROUP_CRUSHER_3);
events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 0s);
events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 45s);
events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 90s);
}
}
void SummonCrusherPack(const SummonGroups group)
{
std::list<TempSummon*> summoned;
me->SummonCreatureGroup(group, &summoned);
_crushersLeft = summoned.size();
for (TempSummon* summon : summoned)
{
summon->AI()->SetData(DATA_CRUSHER_PACK_ID, group);
summon->AI()->DoAction(ACTION_PACK_WALK);
}
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
switch (summon->GetEntry())
{
case NPC_WORLD_TRIGGER_LAOI:
summon->AddAura(SPELL_SUMMON_ANUBAR_CHAMPION_PERIODIC, summon);
summon->AddAura(SPELL_SUMMON_ANUBAR_NECROMANCER_PERIODIC, summon);
summon->AddAura(SPELL_SUMMON_ANUBAR_CRYPT_FIEND_PERIODIC, summon);
break;
case NPC_ANUB_AR_CHAMPION:
case NPC_ANUB_AR_NECROMANCER:
case NPC_ANUB_AR_CRYPTFIEND:
// Xinef: cannot use pathfinding...
if (summon->GetDistance(477.0f, 618.0f, 771.0f) < 5.0f)
summon->GetMotionMaster()->MoveWaypoint(3000012, false);
else if (summon->GetDistance(583.0f, 617.0f, 771.0f) < 5.0f)
summon->GetMotionMaster()->MoveWaypoint(3000013, false);
else if (summon->GetDistance(581.0f, 608.5f, 739.0f) < 5.0f)
summon->GetMotionMaster()->MoveWaypoint(3000014, false);
break;
default:
break;
}
}
void KilledUnit(Unit* victim) override
{
if (!me->IsAlive() || !victim->HasAura(SPELL_LEECH_POISON))
return;
me->ModifyHealth(static_cast<int32>(me->CountPctFromMaxHealth(10)));
}
void JustEngagedWith(Unit* /*who*/) override
{
me->setActive(true);
events.RescheduleEvent(EVENT_HADRONOX_ACID, 10s);
events.RescheduleEvent(EVENT_HADRONOX_LEECH, 4s);
events.RescheduleEvent(EVENT_HADRONOX_PIERCE, 1s);
events.RescheduleEvent(EVENT_HADRONOX_GRAB, 15s);
events.RescheduleEvent(EVENT_CHECK_EVADE, 1s);
}
bool IsInCombatWithPlayer() const
{
return std::ranges::any_of(me->GetThreatMgr().GetThreatList(), [](auto const& ref) {
return ref->getTarget()->IsControlledByPlayer();
});
}
void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
{
if ((!who || !who->IsControlledByPlayer()) && me->HealthBelowPct(70))
{
if (me->HealthBelowPctDamaged(5, damage))
damage = 0;
else
damage *= (me->GetHealthPct() - 5.0f) / 65.0f;
}
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
if (!UpdateVictim())
return;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (uint32 eventId = events.ExecuteEvent())
{
case EVENT_HADRONOX_PIERCE:
DoCastVictim(SPELL_PIERCE_ARMOR);
events.Repeat(8s);
break;
case EVENT_HADRONOX_ACID:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, false))
DoCast(target, SPELL_ACID_CLOUD);
events.Repeat(25s);
break;
case EVENT_HADRONOX_LEECH:
DoCastSelf(SPELL_LEECH_POISON);
events.Repeat(12s);
break;
case EVENT_HADRONOX_GRAB:
DoCastSelf(SPELL_WEB_GRAB);
events.Repeat(25s);
break;
case EVENT_HADRONOX_MOVE3:
if (_crushersLeft > 0)
{
events.Repeat(2s);
break;
}
[[fallthrough]];
case EVENT_HADRONOX_MOVE1:
case EVENT_HADRONOX_MOVE2:
Talk(SAY_HADRONOX_EMOTE);
me->SetReactState(REACT_PASSIVE);
me->GetMotionMaster()->Clear();
me->AttackStop();
me->GetMotionMaster()->MovePoint(eventId, hadronoxSteps[eventId - 1]);
break;
case EVENT_CHECK_EVADE:
if (IsInCombatWithPlayer() != _lastPlayerCombatState)
{
_lastPlayerCombatState = !_lastPlayerCombatState;
if (_lastPlayerCombatState)
{
me->SetReactState(REACT_AGGRESSIVE);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->Clear();
}
else
EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
}
events.Repeat(1s);
break;
default:
break;
}
DoMeleeAttackIfReady();
}
void MovementInform(uint32 movementType, uint32 pointId) override
{
if (movementType != POINT_MOTION_TYPE)
return;
me->SetReactState(REACT_AGGRESSIVE);
if (pointId == EVENT_HADRONOX_MOVE3)
{
DoCastSelf(SPELL_WEB_FRONT_DOORS, true);
_doorsWebbed = true;
}
}
uint32 GetData(uint32 data) const override
{
if (data == me->GetEntry()) // 'Hadronox Denied' achievement
return _doorsWebbed ? 0 : 1;
return 0;
}
private:
uint8 _crushersLeft;
bool _doorsWebbed;
bool _lastPlayerCombatState;
};
class boss_hadronox : public CreatureScript
struct npc_hadronox_crusherPackAI : public ScriptedAI
{
public:
boss_hadronox() : CreatureScript("boss_hadronox") { }
npc_hadronox_crusherPackAI(Creature* creature, Position const* positions) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _positions(positions), _myPack(SUMMON_GROUP_CRUSHER_NONE), _doFacing(false) { }
struct boss_hadronoxAI : public BossAI
virtual void DoEngagedWith() = 0;
virtual void DoEvent(uint32 /*eventId*/) = 0;
void DoAction(int32 action) override
{
boss_hadronoxAI(Creature* creature) : BossAI(creature, DATA_HADRONOX)
if (action == ACTION_PACK_WALK)
{
}
void Reset() override
{
summons.DoAction(ACTION_DESPAWN_ADDS);
BossAI::Reset();
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 542.9f, 519.5f, 741.24f, 2.14f);
}
void DoAction(int32 param) override
{
if (param == ACTION_START_EVENT)
switch (_myPack)
{
instance->SetBossState(DATA_HADRONOX, IN_PROGRESS);
me->setActive(true);
events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 20s);
events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 40s);
events.ScheduleEvent(EVENT_HADRONOX_MOVE3, 60s);
events.ScheduleEvent(EVENT_HADRONOX_MOVE4, 80s);
case SUMMON_GROUP_CRUSHER_1:
case SUMMON_GROUP_CRUSHER_2:
case SUMMON_GROUP_CRUSHER_3:
me->GetMotionMaster()->MovePoint(ACTION_PACK_WALK, _positions[_myPack - SUMMON_GROUP_CRUSHER_1]);
break;
default:
break;
}
}
}
uint32 GetData(uint32 data) const override
{
if (data == me->GetEntry())
return !me->isActiveObject() || events.HasTimeUntilEvent(EVENT_HADRONOX_MOVE4) ? 1 : 0;
return 0;
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
// Xinef: cannot use pathfinding...
if (summon->GetDistance(477.0f, 618.0f, 771.0f) < 5.0f)
summon->GetMotionMaster()->MoveWaypoint(3000012, false);
else if (summon->GetDistance(583.0f, 617.0f, 771.0f) < 5.0f)
summon->GetMotionMaster()->MoveWaypoint(3000013, false);
else if (summon->GetDistance(581.0f, 608.5f, 739.0f) < 5.0f)
summon->GetMotionMaster()->MoveWaypoint(3000014, false);
}
void KilledUnit(Unit* victim) override
{
if (!me->IsAlive() || !victim->HasAura(SPELL_LEECH_POISON))
return;
me->ModifyHealth(int32(me->CountPctFromMaxHealth(10)));
}
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
}
void JustEngagedWith(Unit*) override
{
events.RescheduleEvent(EVENT_HADRONOX_ACID, 10s);
events.RescheduleEvent(EVENT_HADRONOX_LEECH, 4s);
events.RescheduleEvent(EVENT_HADRONOX_PIERCE, 1s);
events.RescheduleEvent(EVENT_HADRONOX_GRAB, 15s);
}
bool AnyPlayerValid() const
{
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
for(Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
if (me->GetDistance(itr->GetSource()) < 130.0f && itr->GetSource()->IsAlive() && !itr->GetSource()->IsGameMaster() && me->CanCreatureAttack(itr->GetSource()))
return true;
return false;
}
void DamageTaken(Unit* who, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
{
if ((!who || !who->IsControlledByPlayer()) && me->HealthBelowPct(70))
{
if (me->HealthBelowPctDamaged(5, damage))
{
damage = 0;
}
else
{
damage *= (me->GetHealthPct() - 5.0f) / 65.0f;
}
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (uint32 eventId = events.ExecuteEvent())
{
case EVENT_HADRONOX_PIERCE:
me->CastSpell(me->GetVictim(), SPELL_PIERCE_ARMOR, false);
events.ScheduleEvent(EVENT_HADRONOX_PIERCE, 8s);
break;
case EVENT_HADRONOX_ACID:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, false))
me->CastSpell(target, SPELL_ACID_CLOUD, false);
events.ScheduleEvent(EVENT_HADRONOX_ACID, 25s);
break;
case EVENT_HADRONOX_LEECH:
me->CastSpell(me, SPELL_LEECH_POISON, false);
events.ScheduleEvent(EVENT_HADRONOX_LEECH, 12s);
break;
case EVENT_HADRONOX_GRAB:
me->CastSpell(me, SPELL_WEB_GRAB, false);
events.ScheduleEvent(EVENT_HADRONOX_GRAB, 25s);
break;
case EVENT_HADRONOX_MOVE4:
me->CastSpell(me, SPELL_WEB_FRONT_DOORS, true);
[[fallthrough]]; /// @todo: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked.
case EVENT_HADRONOX_MOVE1:
case EVENT_HADRONOX_MOVE2:
case EVENT_HADRONOX_MOVE3:
Talk(SAY_HADRONOX_EMOTE);
me->GetMotionMaster()->MoveCharge(hadronoxSteps[eventId - 1].GetPositionX(), hadronoxSteps[eventId - 1].GetPositionY(), hadronoxSteps[eventId - 1].GetPositionZ(), 10.0f, 0, nullptr, true);
break;
}
DoMeleeAttackIfReady();
}
bool CheckEvadeIfOutOfCombatArea() const override
{
return me->isActiveObject() && !AnyPlayerValid();
}
};
CreatureAI* GetAI(Creature* creature) const override
void MovementInform(uint32 type, uint32 id) override
{
return GetAzjolNerubAI<boss_hadronoxAI>(creature);
if (type == POINT_MOTION_TYPE && id == ACTION_PACK_WALK)
_doFacing = true;
}
uint32 GetData(uint32 data) const override
{
if (data == DATA_CRUSHER_PACK_ID)
return _myPack;
return 0;
}
void SetData(uint32 data, uint32 value) override
{
if (data == DATA_CRUSHER_PACK_ID)
{
_myPack = SummonGroups(value);
me->SetReactState(_myPack ? REACT_PASSIVE : REACT_AGGRESSIVE);
}
}
void JustEngagedWith(Unit* who) override
{
if (me->HasReactState(REACT_PASSIVE))
{
std::list<Creature*> creatures;
me->GetCreatureListWithEntryInGrid(creatures, { NPC_ANUB_AR_CRUSHER, NPC_ANUB_AR_CHAMPION_PACK, NPC_ANUB_AR_NECROMANCER_PACK, NPC_ANUB_AR_CRYPT_FIEND_PACK }, 40.0f);
for (Creature* creature : creatures)
if (creature->AI()->GetData(DATA_CRUSHER_PACK_ID) == _myPack)
{
creature->SetReactState(REACT_AGGRESSIVE);
creature->AI()->AttackStart(who);
}
}
DoEngagedWith();
ScriptedAI::JustEngagedWith(who);
}
void MoveInLineOfSight(Unit* who) override
{
if (!me->HasReactState(REACT_PASSIVE))
{
ScriptedAI::MoveInLineOfSight(who);
return;
}
if (me->CanStartAttack(who) && me->IsWithinDistInMap(who, me->GetAttackDistance(who) + me->m_CombatDistance))
JustEngagedWith(who);
}
void UpdateAI(uint32 diff) override
{
if (_doFacing)
{
_doFacing = false;
me->SetFacingTo(_positions[_myPack - SUMMON_GROUP_CRUSHER_1].GetOrientation());
}
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
DoEvent(eventId);
DoMeleeAttackIfReady();
}
protected:
InstanceScript* const _instance;
Position const* const _positions;
SummonGroups _myPack;
bool _doFacing;
};
static const Position crusherWaypoints[] =
{
{ 529.6913f, 547.1257f, 731.9155f, 4.799650f },
{ 517.51f , 561.439f , 734.0306f, 4.520403f },
{ 543.414f , 551.728f , 732.0522f, 3.996804f }
};
struct npc_anub_ar_crusher : public npc_hadronox_crusherPackAI
{
explicit npc_anub_ar_crusher(Creature* creature) : npc_hadronox_crusherPackAI(creature, crusherWaypoints), _hadFrenzy(false) { }
void DoEngagedWith() override
{
events.ScheduleEvent(EVENT_CRUSHER_SMASH, 8s, 12s);
if (_myPack != SUMMON_GROUP_CRUSHER_1)
return;
if (_instance->GetBossState(DATA_HADRONOX) == IN_PROGRESS)
return;
if (Creature* hadronox = _instance->GetCreature(DATA_HADRONOX))
hadronox->AI()->DoAction(ACTION_CRUSHER_ENGAGED);
Talk(SAY_CRUSHER_AGGRO);
}
void DamageTaken(Unit* /*who*/, uint32& damage, DamageEffectType /*damageType*/, SpellSchoolMask /*damageSchoolMask*/) override
{
if (_hadFrenzy || !me->HealthBelowPctDamaged(25, damage))
return;
_hadFrenzy = true;
Talk(SAY_CRUSHER_EMOTE);
DoCastSelf(SPELL_FRENZY);
}
void DoEvent(uint32 eventId) override
{
if (eventId == EVENT_CRUSHER_SMASH)
{
DoCastVictim(SPELL_SMASH);
events.Repeat(13s, 21s);
}
}
void JustDied(Unit* killer) override
{
if (Creature* hadronox = _instance->GetCreature(DATA_HADRONOX))
hadronox->AI()->DoAction(ACTION_CRUSHER_DIED);
ScriptedAI::JustDied(killer);
}
private:
bool _hadFrenzy;
};
static const Position championWaypoints[] =
{
{ 539.2076f, 549.7539f, 732.8668f, 4.55531f },
{ 527.3098f, 559.5197f, 732.9407f, 4.742493f },
{ }
};
struct npc_anub_ar_crusher_champion : public npc_hadronox_crusherPackAI
{
explicit npc_anub_ar_crusher_champion(Creature* creature) : npc_hadronox_crusherPackAI(creature, championWaypoints) { }
void DoEvent(uint32 eventId) override
{
switch (eventId)
{
case EVENT_REND:
DoCastVictim(SPELL_REND);
events.Repeat(12s, 16s);
break;
case EVENT_PUMMEL:
DoCastVictim(SPELL_PUMMEL);
events.Repeat(12s, 17s);
break;
default:
break;
}
}
void DoEngagedWith() override
{
events.ScheduleEvent(EVENT_REND, 4s, 8s);
events.ScheduleEvent(EVENT_PUMMEL, 15s, 19s);
}
};
class npc_anub_ar_crusher : public CreatureScript
static const Position cryptFiendWaypoints[] =
{
public:
npc_anub_ar_crusher() : CreatureScript("npc_anub_ar_crusher") { }
{ 520.3911f, 548.7895f, 732.0118f, 5.0091f },
{ },
{ 550.9611f, 545.1674f, 731.9031f, 3.996804f }
};
struct npc_anub_ar_crusher_crypt_fiend : public npc_hadronox_crusherPackAI
{
explicit npc_anub_ar_crusher_crypt_fiend(Creature* creature) : npc_hadronox_crusherPackAI(creature, cryptFiendWaypoints) { }
struct npc_anub_ar_crusherAI : public ScriptedAI
void DoEvent(uint32 eventId) override
{
npc_anub_ar_crusherAI(Creature* c) : ScriptedAI(c), summons(me) {}
EventMap events;
SummonList summons;
void Reset() override
switch (eventId)
{
summons.DespawnAll();
events.Reset();
if (me->ToTempSummon())
if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
if (summoner->GetEntry() == me->GetEntry())
{
me->CastSpell(me, RAND(SPELL_SUMMON_ANUBAR_CHAMPION, SPELL_SUMMON_ANUBAR_CRYPT_FIEND, SPELL_SUMMON_ANUBAR_NECROMANCER), true);
me->CastSpell(me, RAND(SPELL_SUMMON_ANUBAR_CHAMPION, SPELL_SUMMON_ANUBAR_CRYPT_FIEND, SPELL_SUMMON_ANUBAR_NECROMANCER), true);
}
case EVENT_CRUSHING_WEBS:
DoCastVictim(SPELL_CRUSHING_WEBS);
events.Repeat(12s, 16s);
break;
case EVENT_INFECTED_WOUND:
DoCastVictim(SPELL_INFECTED_WOUND);
events.Repeat(16s, 25s);
break;
default:
break;
}
}
void JustSummoned(Creature* summon) override
{
if (summon->GetEntry() != me->GetEntry())
{
summon->GetMotionMaster()->MovePoint(0, *me, FORCED_MOVEMENT_NONE, 0.f, false);
summon->GetMotionMaster()->MoveFollow(me, 0.1f, 0.0f + M_PI * 0.3f * summons.size());
}
summons.Summon(summon);
}
void DoAction(int32 param) override
{
if (param == ACTION_DESPAWN_ADDS)
{
summons.DoAction(ACTION_DESPAWN_ADDS);
summons.DespawnAll();
}
}
void JustEngagedWith(Unit*) override
{
if (me->ToTempSummon())
if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
if (summoner->GetEntry() != me->GetEntry())
{
summoner->GetAI()->DoAction(ACTION_START_EVENT);
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 519.58f, 573.73f, 734.30f, 4.50f);
me->SummonCreature(NPC_ANUB_AR_CRUSHER, 539.38f, 573.25f, 732.20f, 4.738f);
Talk(SAY_CRUSHER_AGGRO);
}
events.ScheduleEvent(EVENT_CRUSHER_SMASH, 8s, 0, 0);
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1s);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CRUSHER_SMASH:
me->CastSpell(me->GetVictim(), SPELL_SMASH, false);
events.ScheduleEvent(EVENT_CRUSHER_SMASH, 15s);
break;
case EVENT_CHECK_HEALTH:
if (me->HealthBelowPct(30))
{
Talk(SAY_CRUSHER_EMOTE);
me->CastSpell(me, SPELL_FRENZY, false);
break;
}
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1s);
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
void DoEngagedWith() override
{
return GetAzjolNerubAI<npc_anub_ar_crusherAI>(creature);
events.ScheduleEvent(EVENT_CRUSHING_WEBS, 4s, 8s);
events.ScheduleEvent(EVENT_INFECTED_WOUND, 15s, 19s);
}
};
static const Position necromancerWaypoints[] =
{
{ },
{ 507.6937f, 563.3471f, 734.8986f, 4.520403f },
{ 535.1049f, 552.8961f, 732.8441f, 3.996804f },
};
struct npc_anub_ar_crusher_necromancer : public npc_hadronox_crusherPackAI
{
explicit npc_anub_ar_crusher_necromancer(Creature* creature) : npc_hadronox_crusherPackAI(creature, necromancerWaypoints) { }
void DoEvent(uint32 eventId) override
{
switch (eventId)
{
case EVENT_SHADOW_BOLT:
DoCastVictim(SPELL_SHADOW_BOLT);
events.Repeat(2s, 5s);
break;
case EVENT_ANIMATE_BONES:
DoCastVictim(RAND(SPELL_ANIMATE_BONES_2, SPELL_ANIMATE_BONES_1));
events.Repeat(35s, 50s);
break;
default:
break;
}
}
void DoEngagedWith() override
{
events.ScheduleEvent(EVENT_SHADOW_BOLT, 2s, 4s);
events.ScheduleEvent(EVENT_ANIMATE_BONES, 37s, 45s);
}
};
@ -330,7 +609,7 @@ class spell_hadronox_summon_periodic_aura : public AuraScript
PrepareAuraScript(spell_hadronox_summon_periodic_aura);
public:
spell_hadronox_summon_periodic_aura(uint32 delay, uint32 spellEntry) : _delay(delay), _spellEntry(spellEntry) { }
spell_hadronox_summon_periodic_aura(int32 delay, uint32 spellEntry) : _delay(delay), _spellEntry(spellEntry) { }
bool Validate(SpellInfo const* /*spellInfo*/) override
{
@ -342,7 +621,7 @@ public:
PreventDefaultAction();
Unit* owner = GetUnitOwner();
if (InstanceScript* instance = owner->GetInstanceScript())
if (!instance->IsBossDone(DATA_HADRONOX))
if (!instance->IsBossDone(DATA_HADRONOX) != NOT_STARTED)
{
if (!owner->HasAura(SPELL_WEB_FRONT_DOORS))
owner->CastSpell(owner, _spellEntry, true);
@ -363,7 +642,7 @@ public:
}
private:
uint32 _delay;
int32 _delay;
uint32 _spellEntry;
};
@ -389,12 +668,29 @@ class spell_hadronox_leech_poison_aura : public AuraScript
}
};
class spell_hadronox_web_grab : public SpellScript
{
PrepareSpellScript(spell_hadronox_web_grab);
// hack to avoid pulling Anub'ar Crusher through the floor and causing Hadronox to evade
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if([&](WorldObject* target) -> bool
{
return target->GetEntry() == NPC_ANUB_AR_CRUSHER;
});
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hadronox_web_grab::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
class achievement_hadronox_denied : public AchievementCriteriaScript
{
public:
achievement_hadronox_denied() : AchievementCriteriaScript("achievement_hadronox_denied")
{
}
achievement_hadronox_denied() : AchievementCriteriaScript("achievement_hadronox_denied") { }
bool OnCheck(Player* /*player*/, Unit* target, uint32 /*criteria_id*/) override
{
@ -407,11 +703,15 @@ public:
void AddSC_boss_hadronox()
{
new boss_hadronox();
new npc_anub_ar_crusher();
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_champion_aura", 15000, SPELL_SUMMON_ANUBAR_CHAMPION);
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_necromancer_aura", 10000, SPELL_SUMMON_ANUBAR_NECROMANCER);
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_crypt_fiend_aura", 5000, SPELL_SUMMON_ANUBAR_CRYPT_FIEND);
RegisterAzjolNerubCreatureAI(boss_hadronox);
RegisterAzjolNerubCreatureAI(npc_anub_ar_crusher);
RegisterAzjolNerubCreatureAI(npc_anub_ar_crusher_champion);
RegisterAzjolNerubCreatureAI(npc_anub_ar_crusher_crypt_fiend);
RegisterAzjolNerubCreatureAI(npc_anub_ar_crusher_necromancer);
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_champion_aura", 15'000, SPELL_SUMMON_ANUBAR_CHAMPION);
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_necromancer_aura", 10'000, SPELL_SUMMON_ANUBAR_NECROMANCER);
RegisterSpellScriptWithArgs(spell_hadronox_summon_periodic_aura, "spell_hadronox_summon_periodic_crypt_fiend_aura", 5'000, SPELL_SUMMON_ANUBAR_CRYPT_FIEND);
RegisterSpellScript(spell_hadronox_leech_poison_aura);
RegisterSpellScript(spell_hadronox_web_grab);
new achievement_hadronox_denied();
}

View File

@ -47,6 +47,7 @@ ObjectData const summonData[] =
{ NPC_ANUB_AR_CHAMPION, DATA_HADRONOX },
{ NPC_ANUB_AR_NECROMANCER, DATA_HADRONOX },
{ NPC_ANUB_AR_CRYPTFIEND, DATA_HADRONOX },
{ NPC_WORLD_TRIGGER_LAOI, DATA_HADRONOX },
{ 0, 0 }
};

View File

@ -33,7 +33,6 @@ enum Yells
enum Spells
{
SPELL_CURSE_OF_LIFE = 49527,
SPELL_RAIN_OF_FIRE = 49518,
SPELL_SHADOW_VOLLEY = 49528,
// flesh spells
@ -56,7 +55,6 @@ enum Misc
ACTION_TURN_BONES = 1,
EVENT_SPELL_CURSE_OF_LIFE = 1,
EVENT_SPELL_RAIN_OF_FIRE = 2,
EVENT_SPELL_SHADOW_VOLLEY = 3,
EVENT_SPELL_EYE_BEAM = 4,
EVENT_SPELL_LIGHTNING_BREATH = 5,
@ -97,7 +95,6 @@ public:
Talk(SAY_AGGRO);
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 5s);
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, 14s, 18s);
events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, 8s, 10s);
events.ScheduleEvent(EVENT_SPELL_TURN_FLESH, 1s);
}
@ -146,17 +143,11 @@ public:
switch (events.ExecuteEvent())
{
case EVENT_SPELL_CURSE_OF_LIFE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
me->CastSpell(target, SPELL_CURSE_OF_LIFE, false);
DoCastRandomTarget(SPELL_CURSE_OF_LIFE, 0, 30.0f, false);
events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 13s);
break;
case EVENT_SPELL_RAIN_OF_FIRE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30.0f, true))
me->CastSpell(target, SPELL_RAIN_OF_FIRE, false);
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, 16s);
break;
case EVENT_SPELL_SHADOW_VOLLEY:
me->CastSpell(me, SPELL_SHADOW_VOLLEY, false);
DoCastAOE(SPELL_SHADOW_VOLLEY);
events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, 9s);
break;
case EVENT_SPELL_TURN_FLESH:
@ -173,9 +164,8 @@ public:
events.ScheduleEvent(EVENT_SPELL_TURN_FLESH, 1s);
break;
case EVENT_TURN_FLESH_REAL:
me->CastSpell(me, SPELL_DUMMY, true);
me->GetMotionMaster()->MoveChase(me->GetVictim());
DoCastSelf(SPELL_DUMMY, true);
me->ResumeChasingVictim();
events.ScheduleEvent(EVENT_SPELL_EYE_BEAM, 11s);
events.ScheduleEvent(EVENT_SPELL_LIGHTNING_BREATH, 3s);
events.ScheduleEvent(EVENT_SPELL_POISON_CLOUD, 6s);
@ -199,7 +189,6 @@ public:
me->CastSpell(me, SPELL_CLEAR_GIFT, true);
events.Reset();
events.ScheduleEvent(EVENT_SPELL_CURSE_OF_LIFE, 1s);
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, 12s, 14s);
events.ScheduleEvent(EVENT_SPELL_SHADOW_VOLLEY, 8s, 10s);
break;
}
@ -249,7 +238,6 @@ class spell_tharon_ja_dummy_aura : public AuraScript
{
PreventDefaultAction();
GetUnitOwner()->GetThreatMgr().ResetAllThreat();
GetUnitOwner()->GetMotionMaster()->Clear();
GetUnitOwner()->CastSpell((Unit*)nullptr, SPELL_TURN_BONES, false);
GetUnitOwner()->GetAI()->DoAction(ACTION_TURN_BONES);
}

View File

@ -41,6 +41,7 @@ enum VolkhanOther
NPC_VOLKHAN_ANVIL = 28823,
NPC_MOLTEN_GOLEM = 28695,
NPC_BRITTLE_GOLEM = 28681,
NPC_SLAG = 28585,
// Misc
ACTION_SHATTER = 1,
@ -77,7 +78,7 @@ enum Yells
struct boss_volkhan : public BossAI
{
boss_volkhan(Creature* creature) : BossAI(creature, DATA_VOLKHAN), summons(creature) { }
boss_volkhan(Creature* creature) : BossAI(creature, DATA_VOLKHAN) { }
void Reset() override
{
@ -104,6 +105,18 @@ struct boss_volkhan : public BossAI
{
_JustDied();
Talk(SAY_DEATH);
std::list<Creature*> slags;
GetCreatureListWithEntryInGrid(slags, me, NPC_SLAG, 100.0f);
if (!slags.empty())
{
for (Creature* slag : slags)
{
if (slag)
slag->DespawnOrUnsummon();
}
}
}
void GetNextPos()
@ -286,8 +299,6 @@ struct boss_volkhan : public BossAI
}
private:
EventMap events;
SummonList summons;
float x, y, z;
uint8 PointID;
uint8 ShatteredCount;

View File

@ -17,6 +17,7 @@
#include "CreatureScript.h"
#include "GameObjectScript.h"
#include "GridNotifiers.h"
#include "PassiveAI.h"
#include "Player.h"
#include "ScriptedCreature.h"
@ -26,6 +27,7 @@
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "Vehicle.h"
#include <algorithm>
enum AlchemistItemRequirements
{
@ -234,297 +236,376 @@ public:
}
};
enum overlordDrakuru
enum OverlordDrakuru
{
SPELL_SHADOW_BOLT = 54113,
SPELL_SCOURGE_DISGUISE_EXPIRING = 52010,
SPELL_THROW_BRIGHT_CRYSTAL = 54087,
SPELL_TELEPORT_EFFECT = 52096,
SPELL_SCOURGE_DISGUISE = 51966,
SPELL_SCOURGE_DISGUISE_INSTANT_CAST = 52192,
SPELL_BLIGHT_FOG = 54104,
SPELL_THROW_PORTAL_CRYSTAL = 54209,
SPELL_ARTHAS_PORTAL = 51807,
SPELL_TOUCH_OF_DEATH = 54236,
SPELL_DRAKURU_DEATH = 54248,
SPELL_SUMMON_SKULL = 54253,
SPELL_SHADOW_BOLT = 54113,
SPELL_SCOURGE_DISGUISE_EXPIRING = 52010,
SPELL_DROP_DISGUISE = 54089,
SPELL_THROW_BRIGHT_CRYSTAL = 54087,
SPELL_TELEPORT_EFFECT = 52096,
SPELL_SCOURGE_SPOTLIGHT = 53104,
SPELL_SCOURGE_DISGUISE = 51966,
SPELL_SCOURGE_DISGUISE_INSTANT_CAST = 52192,
SPELL_BLIGHT_FOG = 54104,
SPELL_THROW_PORTAL_CRYSTAL = 54209,
SPELL_ARTHAS_PORTAL = 51807,
SPELL_TOUCH_OF_DEATH = 54236,
SPELL_DRAKURU_DEATH = 54248,
SPELL_SUMMON_SKULL = 54253,
SPELL_BLOATED_ABOMINATION_FEIGN_DEATH = 52593,
SPELL_EXPLODE_ABOMINATION_BLOODY_MEAT = 52523,
SPELL_EXPLODE_ABOMINATION_MEAT = 52520,
SPELL_DRAKURUS_SKULL_MISSILE = 54250,
SPELL_BURST_AT_THE_SEAMS_BONE = 52516,
QUEST_BETRAYAL = 12713,
QUEST_BETRAYAL = 12713,
NPC_BLIGHTBLOOD_TROLL = 28931,
NPC_LICH_KING = 28498,
NPC_BLIGHTBLOOD_TROLL = 28931,
NPC_LICH_KING = 28498,
NPC_TOTALLY_GENERIC_BUNNY = 29100,
NPC_TOTALLY_GENERIC_BUNNY_JSB = 28960,
GO_DRAKURUS_LAST_WISH = 202357,
EVENT_BETRAYAL_1 = 1,
EVENT_BETRAYAL_2 = 2,
EVENT_BETRAYAL_3 = 3,
EVENT_BETRAYAL_4 = 4,
EVENT_BETRAYAL_5 = 5,
EVENT_BETRAYAL_6 = 6,
EVENT_BETRAYAL_7 = 7,
EVENT_BETRAYAL_8 = 8,
EVENT_BETRAYAL_9 = 9,
EVENT_BETRAYAL_10 = 10,
EVENT_BETRAYAL_11 = 11,
EVENT_BETRAYAL_12 = 12,
EVENT_BETRAYAL_13 = 13,
EVENT_BETRAYAL_14 = 14,
EVENT_BETRAYAL_SHADOW_BOLT = 20,
EVENT_BETRAYAL_CRYSTAL = 21,
EVENT_BETRAYAL_COMBAT_TALK = 22,
ACTION_SUMMON_DRAKURU_LAST_WISH = 1,
ACTION_DESTROY_DRAKURU_LAST_WISH = 2,
ACTION_REMOVE_SPOTLIGHTS = 3,
SAY_DRAKURU_0 = 0,
SAY_DRAKURU_1 = 1,
SAY_DRAKURU_2 = 2,
SAY_DRAKURU_3 = 3,
SAY_DRAKURU_4 = 4,
SAY_DRAKURU_5 = 5,
SAY_DRAKURU_6 = 6,
SAY_DRAKURU_7 = 7,
SAY_LICH_7 = 7,
SAY_LICH_8 = 8,
SAY_LICH_9 = 9,
SAY_LICH_10 = 10,
SAY_LICH_11 = 11,
SAY_LICH_12 = 12,
SUMMON_GROUP_BLIGHTBLOOD_TROLL = 1,
EVENT_BETRAYAL_INTRO_1 = 1,
EVENT_BETRAYAL_INTRO_2 = 2,
EVENT_BETRAYAL_INTRO_3 = 3,
EVENT_BETRAYAL_INTRO_4 = 4,
EVENT_BETRAYAL_EVADE_CHECK = 5,
EVENT_BETRAYAL_EPILOGUE_1 = 6,
EVENT_BETRAYAL_EPILOGUE_2 = 7,
EVENT_BETRAYAL_EPILOGUE_3 = 8,
EVENT_BETRAYAL_EPILOGUE_4 = 9,
EVENT_BETRAYAL_EPILOGUE_5 = 10,
EVENT_BETRAYAL_EPILOGUE_6 = 11,
EVENT_BETRAYAL_EPILOGUE_7 = 12,
EVENT_BETRAYAL_EPILOGUE_8 = 13,
EVENT_BETRAYAL_EPILOGUE_9 = 14,
EVENT_BETRAYAL_EPILOGUE_10 = 15,
SAY_DRAKURU_0 = 0,
SAY_DRAKURU_1 = 1,
SAY_DRAKURU_2 = 2,
SAY_DRAKURU_3 = 3,
SAY_DRAKURU_4 = 4,
SAY_DRAKURU_5 = 5,
SAY_DRAKURU_6 = 6,
SAY_DRAKURU_7 = 7,
SAY_LICH_7 = 7,
SAY_LICH_8 = 8,
SAY_LICH_9 = 9,
SAY_LICH_10 = 10,
SAY_LICH_11 = 11,
SAY_LICH_12 = 12,
};
class npc_overlord_drakuru_betrayal : public CreatureScript
enum BetrayalState
{
public:
npc_overlord_drakuru_betrayal() : CreatureScript("npc_overlord_drakuru_betrayal") { }
BETRAYAL_NOT_STARTED,
BETRAYAL_IN_PROGRESS,
BETRAYAL_EPILOGUE,
BETRAYAL_EVADE,
};
CreatureAI* GetAI(Creature* creature) const override
struct npc_overlord_drakuru_betrayal : public ScriptedAI
{
npc_overlord_drakuru_betrayal(Creature* creature) : ScriptedAI(creature), _summons(me), _state(BETRAYAL_NOT_STARTED)
{
return new npc_overlord_drakuru_betrayalAI(creature);
me->SetCombatMovement(false);
}
struct npc_overlord_drakuru_betrayalAI : public ScriptedAI
void EnterEvadeMode(EvadeReason why) override
{
npc_overlord_drakuru_betrayalAI(Creature* creature) : ScriptedAI(creature), summons(me)
{
}
if (_state != BETRAYAL_EVADE)
return;
me->SetFaction(FACTION_UNDEAD_SCOURGE);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
ScriptedAI::EnterEvadeMode(why);
}
EventMap events;
SummonList summons;
ObjectGuid playerGUID;
ObjectGuid lichGUID;
void Reset() override
{
events.Reset();
scheduler.CancelAll();
_summons.DespawnAll();
_playerGUID.Clear();
_lichGUID.Clear();
me->SetFaction(FACTION_UNDEAD_SCOURGE);
me->SetVisible(false);
DoAction(ACTION_SUMMON_DRAKURU_LAST_WISH);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetImmuneToPC(true);
_state = BETRAYAL_NOT_STARTED;
DoAction(ACTION_REMOVE_SPOTLIGHTS);
}
void EnterEvadeMode(EvadeReason why) override
void DoAction(int32 action) override
{
switch (action)
{
if (playerGUID)
if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
if (player->IsWithinDistInMap(me, 80))
return;
me->SetFaction(FACTION_UNDEAD_SCOURGE);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
ScriptedAI::EnterEvadeMode(why);
}
void Reset() override
{
events.Reset();
summons.DespawnAll();
playerGUID.Clear();
lichGUID.Clear();
me->SetFaction(FACTION_UNDEAD_SCOURGE);
me->SetVisible(false);
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
}
void MoveInLineOfSight(Unit* who) override
{
if (who->IsPlayer())
case ACTION_SUMMON_DRAKURU_LAST_WISH:
if (!me->FindNearestGameObject(GO_DRAKURUS_LAST_WISH, 80.0f))
me->SummonGameObject(GO_DRAKURUS_LAST_WISH, 6185.989, -2029.6979, 590.87787, 0, 0, 0, 0, 0, 0, true, GO_SUMMON_TIMED_DESPAWN);
break;
case ACTION_DESTROY_DRAKURU_LAST_WISH:
if (GameObject* go = me->FindNearestGameObject(GO_DRAKURUS_LAST_WISH, 80.0f))
go->Delete();
break;
case ACTION_REMOVE_SPOTLIGHTS:
{
if (playerGUID)
std::list<Creature*> creatures;
me->GetCreatureListWithEntryInGrid(creatures, NPC_TOTALLY_GENERIC_BUNNY, 55.0f);
for (Creature* creature : creatures)
creature->RemoveAurasDueToSpell(SPELL_SCOURGE_SPOTLIGHT);
}
}
}
bool IsPlayerOnQuest(Player* player)
{
return player->GetQuestStatus(QUEST_BETRAYAL) == QUEST_STATUS_INCOMPLETE;
}
void MoveInLineOfSight(Unit* who) override
{
if (Player* player = who->ToPlayer())
{
bool shouldStartEvent = (_state == BETRAYAL_NOT_STARTED) && IsPlayerOnQuest(player) && player->HasAura(SPELL_SCOURGE_DISGUISE) && player->IsWithinDistInMap(me, 80.0f);
if (shouldStartEvent)
{
me->SetVisible(true);
_state = BETRAYAL_IN_PROGRESS;
DoAction(ACTION_DESTROY_DRAKURU_LAST_WISH);
_playerGUID = who->GetGUID();
events.ScheduleEvent(EVENT_BETRAYAL_INTRO_1, 6s);
events.ScheduleEvent(EVENT_BETRAYAL_EVADE_CHECK, 10s);
}
}
else
ScriptedAI::MoveInLineOfSight(who);
}
void JustSummoned(Creature* summon) override
{
_summons.Summon(summon);
switch (summon->GetEntry())
{
case NPC_BLIGHTBLOOD_TROLL:
if (Creature* target = summon->FindNearestCreature(NPC_TOTALLY_GENERIC_BUNNY, 10.0f, true))
target->CastSpell(target, SPELL_TELEPORT_EFFECT, true);
break;
case NPC_LICH_KING:
me->SetFacingToObject(summon);
_lichGUID = summon->GetGUID();
summon->GetMotionMaster()->MovePoint(0, 6164.2695, -2016.8978, 590.8636);
break;
default:
break;
}
}
void JustEngagedWith(Unit* /*who*/) override
{
scheduler.Schedule(0s, [this](TaskContext context)
{
if (!me->IsWithinMeleeRange(me->GetVictim()))
DoCastVictim(SPELL_SHADOW_BOLT);
context.Repeat(2s);
}).Schedule(5s, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true))
DoCast(target, SPELL_THROW_BRIGHT_CRYSTAL);
context.Repeat(6s, 15s);
}).Schedule(20s, [this](TaskContext context)
{
Talk(SAY_DRAKURU_4);
context.Repeat(10s, 20s);
});
}
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*dmgType*/, SpellSchoolMask /*school*/) override
{
if (damage >= me->GetHealth() && !me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
{
damage = 0;
me->RemoveAllAuras();
me->CombatStop();
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetFaction(2082);
me->SetImmuneToPC(true);
events.Reset();
scheduler.CancelAll();
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_1, 4200ms);
_state = BETRAYAL_EPILOGUE;
}
}
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
{
switch (spellInfo->Id)
{
case SPELL_THROW_PORTAL_CRYSTAL:
if (Aura* aura = target->AddAura(SPELL_ARTHAS_PORTAL, target))
aura->SetDuration(77'000);
break;
case SPELL_DRAKURUS_SKULL_MISSILE:
target->CastSpell(target, SPELL_SUMMON_SKULL, true);
break;
case SPELL_DROP_DISGUISE:
target->CastSpell(target, SPELL_SCOURGE_DISGUISE_EXPIRING, true);
break;
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TOUCH_OF_DEATH)
{
DoCastAOE(SPELL_DRAKURUS_SKULL_MISSILE, true);
DoCastSelf(SPELL_BLOATED_ABOMINATION_FEIGN_DEATH, true);
DoCastSelf(SPELL_BURST_AT_THE_SEAMS_BONE, true);
DoCastSelf(SPELL_BURST_AT_THE_SEAMS_BONE, true);
DoCastSelf(SPELL_BURST_AT_THE_SEAMS_BONE, true);
DoCastSelf(SPELL_EXPLODE_ABOMINATION_MEAT, true);
DoCastSelf(SPELL_EXPLODE_ABOMINATION_BLOODY_MEAT, true);
DoCastSelf(SPELL_EXPLODE_ABOMINATION_BLOODY_MEAT, true);
DoCastSelf(SPELL_EXPLODE_ABOMINATION_BLOODY_MEAT, true);
DoCastSelf(SPELL_DRAKURU_DEATH, true);
DoAction(ACTION_SUMMON_DRAKURU_LAST_WISH);
me->SetImmuneToPC(true);
}
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_BETRAYAL_EVADE_CHECK:
{
if (_state == BETRAYAL_IN_PROGRESS)
{
if (who->GetGUID() != playerGUID)
float radius = 80.0f;
std::list<Player*> players;
Acore::AnyPlayerInObjectRangeCheck checker(me, radius, true, true);
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(me, players, checker);
Cell::VisitObjects(me, searcher, radius);
if (std::ranges::any_of(players, [this](Player* player)
{
Player* player = ObjectAccessor::GetPlayer(*me, playerGUID);
if (player && player->IsWithinDistInMap(me, 80))
who->ToPlayer()->NearTeleportTo(6143.76f, -1969.7f, 417.57f, 2.08f);
else
{
EnterEvadeMode(EVADE_REASON_OTHER);
return;
}
return IsPlayerOnQuest(player);
}))
{
events.Repeat(10s);
}
else
ScriptedAI::MoveInLineOfSight(who);
{
_state = BETRAYAL_EVADE;
EnterEvadeMode(EVADE_REASON_OTHER);
}
}
else if (who->ToPlayer()->GetQuestStatus(QUEST_BETRAYAL) == QUEST_STATUS_INCOMPLETE && who->HasAura(SPELL_SCOURGE_DISGUISE))
break;
}
case EVENT_BETRAYAL_INTRO_1:
Talk(SAY_DRAKURU_0);
events.ScheduleEvent(EVENT_BETRAYAL_INTRO_2, 4s);
events.ScheduleEvent(EVENT_BETRAYAL_INTRO_3, 6600ms);
break;
case EVENT_BETRAYAL_INTRO_2:
me->SummonCreatureGroup(SUMMON_GROUP_BLIGHTBLOOD_TROLL);
break;
case EVENT_BETRAYAL_INTRO_3:
Talk(SAY_DRAKURU_1);
DoCastAOE(SPELL_DROP_DISGUISE);
events.ScheduleEvent(EVENT_BETRAYAL_INTRO_4, 9600ms);
break;
case EVENT_BETRAYAL_INTRO_4:
{
Talk(SAY_DRAKURU_2);
Talk(SAY_DRAKURU_3);
me->SetImmuneToPC(false);
std::list<Creature*> creatures;
me->GetCreatureListWithEntryInGrid(creatures, NPC_TOTALLY_GENERIC_BUNNY, 55.0f);
for (Creature* creature : creatures)
creature->CastSpell(creature, SPELL_SCOURGE_SPOTLIGHT, true);
break;
}
case EVENT_BETRAYAL_EPILOGUE_1:
{
Talk(SAY_DRAKURU_5);
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_2, 4800ms);
DoAction(ACTION_REMOVE_SPOTLIGHTS);
break;
}
case EVENT_BETRAYAL_EPILOGUE_2:
Talk(SAY_DRAKURU_6);
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_3, 1800ms);
break;
case EVENT_BETRAYAL_EPILOGUE_3:
DoCastSelf(SPELL_THROW_PORTAL_CRYSTAL, true);
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_4, 3600ms);
break;
case EVENT_BETRAYAL_EPILOGUE_4:
me->SummonCreature(NPC_LICH_KING, 6140.4233, -2010.9938, 589.1911, 6.126106, TEMPSUMMON_TIMED_DESPAWN, 77'000);
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_5, 8400ms);
break;
case EVENT_BETRAYAL_EPILOGUE_5:
Talk(SAY_DRAKURU_7);
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_6, 9600ms);
break;
case EVENT_BETRAYAL_EPILOGUE_6:
if (Creature* lich = ObjectAccessor::GetCreature(*me, _lichGUID))
{
me->SetVisible(true);
playerGUID = who->GetGUID();
events.ScheduleEvent(EVENT_BETRAYAL_1, 5s);
lich->AI()->Talk(SAY_LICH_7);
lich->AI()->Talk(SAY_LICH_8, 5400ms);
}
}
else
ScriptedAI::MoveInLineOfSight(who);
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_7, 7800ms);
break;
case EVENT_BETRAYAL_EPILOGUE_7:
if (Creature* lich = ObjectAccessor::GetCreature(*me, _lichGUID))
lich->CastSpell(me, SPELL_TOUCH_OF_DEATH, false);
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_8, 4200ms);
break;
case EVENT_BETRAYAL_EPILOGUE_8:
me->SetVisible(false);
if (Creature* lich = ObjectAccessor::GetCreature(*me, _lichGUID))
{
lich->AI()->Talk(SAY_LICH_9, 3600ms);
lich->AI()->Talk(SAY_LICH_10, 8400ms);
lich->AI()->Talk(SAY_LICH_11, 22800ms);
lich->AI()->Talk(SAY_LICH_12, 27600ms);
}
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_9, 32600ms);
events.ScheduleEvent(EVENT_BETRAYAL_EPILOGUE_10, 37200ms);
break;
case EVENT_BETRAYAL_EPILOGUE_9:
if (Creature* lich = ObjectAccessor::GetCreature(*me, _lichGUID))
lich->GetMotionMaster()->MovePoint(0, 6141.2393, -2011.2728, 589.8653);
break;
case EVENT_BETRAYAL_EPILOGUE_10:
EnterEvadeMode(EVADE_REASON_OTHER);
break;
}
void JustSummoned(Creature* cr) override
{
summons.Summon(cr);
if (cr->GetEntry() == NPC_BLIGHTBLOOD_TROLL)
cr->CastSpell(cr, SPELL_TELEPORT_EFFECT, true);
else
{
me->SetFacingToObject(cr);
lichGUID = cr->GetGUID();
float o = me->GetAngle(cr);
cr->GetMotionMaster()->MovePoint(0, me->GetPositionX() + cos(o) * 6.0f, me->GetPositionY() + std::sin(o) * 6.0f, me->GetPositionZ());
}
}
if (me->GetFaction() == 2082 || me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED))
return;
void JustEngagedWith(Unit*) override
{
Talk(SAY_DRAKURU_3);
events.ScheduleEvent(EVENT_BETRAYAL_SHADOW_BOLT, 2s);
events.ScheduleEvent(EVENT_BETRAYAL_CRYSTAL, 5s);
events.ScheduleEvent(EVENT_BETRAYAL_COMBAT_TALK, 20s);
}
if (!UpdateVictim())
return;
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
{
if (damage >= me->GetHealth() && !me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
{
damage = 0;
me->RemoveAllAuras();
me->CombatStop();
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->SetFaction(FACTION_FRIENDLY);
events.Reset();
events.ScheduleEvent(EVENT_BETRAYAL_4, 1s);
}
}
scheduler.Update(diff);
DoMeleeAttackIfReady();
}
void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_THROW_PORTAL_CRYSTAL)
if (Aura* aura = target->AddAura(SPELL_ARTHAS_PORTAL, target))
aura->SetDuration(48000);
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spellInfo) override
{
if (spellInfo->Id == SPELL_TOUCH_OF_DEATH)
{
me->CastSpell(me, SPELL_DRAKURU_DEATH, true);
me->CastSpell(me, SPELL_SUMMON_SKULL, true);
}
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_BETRAYAL_1:
Talk(SAY_DRAKURU_0);
events.ScheduleEvent(EVENT_BETRAYAL_2, 5s);
break;
case EVENT_BETRAYAL_2:
me->SummonCreature(NPC_BLIGHTBLOOD_TROLL, 6184.1f, -1969.9f, 586.76f, 4.5f);
me->SummonCreature(NPC_BLIGHTBLOOD_TROLL, 6222.9f, -2026.5f, 586.76f, 2.9f);
me->SummonCreature(NPC_BLIGHTBLOOD_TROLL, 6166.2f, -2065.4f, 586.76f, 1.4f);
me->SummonCreature(NPC_BLIGHTBLOOD_TROLL, 6127.5f, -2008.7f, 586.76f, 0.0f);
events.ScheduleEvent(EVENT_BETRAYAL_3, 5s);
break;
case EVENT_BETRAYAL_3:
Talk(SAY_DRAKURU_1);
Talk(SAY_DRAKURU_2);
if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
player->CastSpell(player, SPELL_SCOURGE_DISGUISE_EXPIRING, true);
if (Aura* aur = me->AddAura(SPELL_BLIGHT_FOG, me))
aur->SetDuration(22000);
break;
case EVENT_BETRAYAL_4:
Talk(SAY_DRAKURU_5);
events.ScheduleEvent(EVENT_BETRAYAL_5, 6s);
break;
case EVENT_BETRAYAL_5:
Talk(SAY_DRAKURU_6);
me->CastSpell(me, SPELL_THROW_PORTAL_CRYSTAL, true);
events.ScheduleEvent(EVENT_BETRAYAL_6, 8s);
break;
case EVENT_BETRAYAL_6:
me->SummonCreature(NPC_LICH_KING, 6142.9f, -2011.6f, 590.86f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 41000);
events.ScheduleEvent(EVENT_BETRAYAL_7, 8s);
break;
case EVENT_BETRAYAL_7:
Talk(SAY_DRAKURU_7);
events.ScheduleEvent(EVENT_BETRAYAL_8, 5s);
break;
case EVENT_BETRAYAL_8:
if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
lich->AI()->Talk(SAY_LICH_7);
events.ScheduleEvent(EVENT_BETRAYAL_9, 6s);
break;
case EVENT_BETRAYAL_9:
if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
{
lich->AI()->Talk(SAY_LICH_8);
lich->CastSpell(me, SPELL_TOUCH_OF_DEATH, false);
}
events.ScheduleEvent(EVENT_BETRAYAL_10, 4s);
break;
case EVENT_BETRAYAL_10:
me->SetVisible(false);
if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
lich->AI()->Talk(SAY_LICH_9);
events.ScheduleEvent(EVENT_BETRAYAL_11, 4s);
break;
case EVENT_BETRAYAL_11:
if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
lich->AI()->Talk(SAY_LICH_10);
events.ScheduleEvent(EVENT_BETRAYAL_12, 6s);
break;
case EVENT_BETRAYAL_12:
if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
lich->AI()->Talk(SAY_LICH_11);
events.ScheduleEvent(EVENT_BETRAYAL_13, 3s);
break;
case EVENT_BETRAYAL_13:
if (Creature* lich = ObjectAccessor::GetCreature(*me, lichGUID))
{
lich->AI()->Talk(SAY_LICH_12);
lich->GetMotionMaster()->MovePoint(0, 6143.8f, -2011.5f, 590.9f);
}
events.ScheduleEvent(EVENT_BETRAYAL_14, 7s);
break;
case EVENT_BETRAYAL_14:
playerGUID.Clear();
EnterEvadeMode(EVADE_REASON_OTHER);
break;
}
if (me->GetFaction() == FACTION_FRIENDLY || me->HasUnitState(UNIT_STATE_CASTING | UNIT_STATE_STUNNED))
return;
if (!UpdateVictim())
return;
switch (events.ExecuteEvent())
{
case EVENT_BETRAYAL_SHADOW_BOLT:
if (!me->IsWithinMeleeRange(me->GetVictim()))
me->CastSpell(me->GetVictim(), SPELL_SHADOW_BOLT, false);
events.Repeat(2s);
break;
case EVENT_BETRAYAL_CRYSTAL:
if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
me->CastSpell(player, SPELL_THROW_BRIGHT_CRYSTAL, true);
events.Repeat(6s, 15s);
break;
case EVENT_BETRAYAL_COMBAT_TALK:
Talk(SAY_DRAKURU_4);
events.Repeat(20s);
break;
}
DoMeleeAttackIfReady();
}
};
private:
SummonList _summons;
ObjectGuid _playerGUID;
ObjectGuid _lichGUID;
BetrayalState _state;
};
/*####
@ -864,11 +945,32 @@ class spell_scourge_disguise_instability : public AuraScript
}
};
// 54105 - Blight Fog
class spell_blight_fog : public SpellScript
{
PrepareSpellScript(spell_blight_fog);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if([](WorldObject* target) -> bool
{
float z = target->GetPositionZ();
bool isInBlightFog = (582.0f <= z && z <= 583.0f) || (586.0f <= z && z <= 587.0f);
return !isInBlightFog;
});
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blight_fog::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
void AddSC_zuldrak()
{
new npc_finklestein();
new go_finklestein_cauldron();
new npc_overlord_drakuru_betrayal();
RegisterCreatureAI(npc_overlord_drakuru_betrayal);
new npc_drakuru_shackles();
new npc_captured_rageclaw();
new npc_released_offspring_harkoa();
@ -876,4 +978,5 @@ void AddSC_zuldrak()
new go_scourge_enclosure();
RegisterSpellScript(spell_scourge_disguise_instability);
RegisterSpellScript(spell_blight_fog);
}